intimate/extractor/twitcasting_extractor/twitcasting_extractor.go

186 lines
5.5 KiB
Go
Raw Normal View History

2020-08-11 10:26:17 +00:00
package main
import (
"database/sql"
"encoding/json"
2020-08-11 10:26:17 +00:00
"intimate"
"log"
"strconv"
"strings"
"time"
"github.com/474420502/extractor"
"github.com/474420502/requests"
)
// sstore 源存储实例, 为存储源数据的实现. 表格具体参考sql/intimate_source.sql
var sstore *intimate.StoreSource = intimate.NewStoreSource(string(intimate.STOpenrec))
// estore 解析存储连接实例
var estore *intimate.StoreExtractor = intimate.NewStoreExtractor()
type LiveData struct {
UserName string `exp:"//span[@class='tw-live-author__info-username']" method:"Text"`
Follower int64 `exp:"(//span[@class='tw-user-nav-list-count'])[2]" method:"r:ExtractNumber"`
MaxViews int64 `exp:"//span[@id='max_viewer_count']/text()" method:"r:ExtractNumber"`
2020-08-11 10:26:17 +00:00
LiveTitle string `exp:"//meta[@property='og:title']" method:"AttributeValue,content"`
2020-08-12 04:22:46 +00:00
LiveStart string `exp:"//time[@data-kind='relative']" method:"AttributeValue,datetime"`
2020-08-11 10:26:17 +00:00
LiveDuration string `exp:"//span[@id='updatetimer']" method:"AttributeValue,data-duration"`
2020-08-12 04:22:46 +00:00
Tags []string `exp:"//div[@class='tw-live-author__commandbox--tags']//a[@class='tag tag-info']" method:"Text"`
2020-08-11 10:26:17 +00:00
}
func main() {
ps := intimate.NewPerfectShutdown()
2020-08-12 04:22:46 +00:00
ses := requests.NewSession()
2020-09-08 10:24:51 +00:00
streamerQueue := intimate.TStreamer.Queue(intimate.Streamer{}, intimate.ConditionDefault(intimate.Ptwitcasting))
2020-09-10 09:33:52 +00:00
var lasterr error
2020-08-11 10:26:17 +00:00
for !ps.IsClose() {
2020-09-08 10:24:51 +00:00
// streamer, err := estore.Pop(intimate.Ptwitcasting)
isteamer, err := streamerQueue.Pop()
2020-08-11 10:26:17 +00:00
if err != nil {
2020-09-10 09:33:52 +00:00
if lasterr != err {
lasterr = err
log.Println(err)
}
time.Sleep(time.Minute)
2020-09-08 10:24:51 +00:00
continue
2020-08-11 10:26:17 +00:00
}
2020-09-08 10:24:51 +00:00
streamer := isteamer.(*intimate.Streamer)
streamer.LiveUrl = &sql.NullString{String: "https://twitcasting.tv/" + *streamer.UserId, Valid: true}
2020-08-12 04:22:46 +00:00
resp, err := ses.Get(streamer.LiveUrl.String).Execute()
2020-08-11 10:26:17 +00:00
if err != nil {
2020-09-08 10:24:51 +00:00
intimate.TStreamer.UpdateError(streamer, err)
log.Println(err, *streamer.UserId)
2020-08-12 04:22:46 +00:00
continue
2020-08-11 10:26:17 +00:00
}
var ldata *LiveData
2020-09-08 10:24:51 +00:00
// f, _ := os.OpenFile("./twistcasting.html", os.O_CREATE|os.O_RDWR|os.O_TRUNC, os.ModePerm)
// f.Write(resp.Content())
2020-08-12 09:42:27 +00:00
etor := extractor.ExtractHtml(resp.Content())
2020-09-08 10:24:51 +00:00
ildata := etor.GetObjectByTag(LiveData{})
if ildata == nil {
log.Println(streamer.LiveUrl.String)
continue
}
ldata = ildata.(*LiveData)
// ldata.MaxViews = regexp.MustCompile("\\d+").FindString(ldata.MaxViews)
2020-08-11 10:26:17 +00:00
coincount := 0
for i := 0; ; i++ {
2020-08-12 04:22:46 +00:00
giverurl := streamer.LiveUrl.String + "/backers/" + strconv.Itoa(i)
2020-08-11 10:26:17 +00:00
resp, err = ses.Get(giverurl).Execute()
if err != nil {
2020-09-08 10:24:51 +00:00
intimate.TStreamer.UpdateError(streamer, err)
2020-08-11 10:26:17 +00:00
log.Panic(err)
}
2020-08-12 09:42:27 +00:00
etor := extractor.ExtractHtml(resp.Content())
2020-08-11 10:26:17 +00:00
xp, err := etor.XPaths("//td[@class='tw-memorial-table-recent-point']")
if err != nil {
2020-09-08 10:24:51 +00:00
intimate.TStreamer.UpdateError(streamer, err)
2020-08-11 10:26:17 +00:00
log.Panic(err)
}
coins := xp.GetTexts()
for _, cointxt := range coins {
scointxt := strings.Split(cointxt, "/")
if len(scointxt) == 2 {
coin := strings.Trim(scointxt[1], " ")
c, err := strconv.Atoi(coin)
if err == nil {
coincount += c
}
2020-08-12 04:22:46 +00:00
// log.Println(coin, coincount)
2020-08-11 10:26:17 +00:00
} else {
log.Println("coin error: ", cointxt)
}
}
if len(coins) < 20 {
break
}
}
var tags []byte
tags, err = json.Marshal(ldata.Tags)
if err != nil {
log.Println(err, streamer.UserId)
}
2020-08-11 10:26:17 +00:00
streamer.Platform = intimate.Ptwitcasting
2020-09-08 10:24:51 +00:00
streamer.UpdateTime = &sql.NullTime{Time: time.Now(), Valid: true}
streamer.UserName = &sql.NullString{String: ldata.UserName, Valid: true}
2020-08-14 11:26:03 +00:00
streamer.Operator = 0
streamer.Tags = tags
2020-08-12 04:22:46 +00:00
// streamer.UpdateInterval = 60
2020-08-11 10:26:17 +00:00
clog := &intimate.CollectLog{}
2020-09-08 10:24:51 +00:00
clog.UserId = *streamer.UserId
clog.Gratuity = &sql.NullInt64{Int64: int64(coincount), Valid: true}
2020-08-11 10:26:17 +00:00
clog.Platform = streamer.Platform
clog.UpdateTime = streamer.UpdateTime
2020-09-08 10:24:51 +00:00
clog.LiveTitle = &sql.NullString{String: ldata.LiveTitle, Valid: true}
clog.Tags = tags
2020-09-08 10:24:51 +00:00
clog.Followers = &sql.NullInt64{Int64: int64(ldata.Follower), Valid: true}
switch {
case ldata.Follower <= 100:
2020-08-28 11:07:12 +00:00
streamer.UpdateInterval = 720
case ldata.Follower <= 1000:
2020-08-28 11:07:12 +00:00
streamer.UpdateInterval = 320
case ldata.Follower <= 10000:
streamer.UpdateInterval = 240
default:
2020-08-28 11:07:12 +00:00
streamer.UpdateInterval = 120
2020-08-11 10:26:17 +00:00
}
2020-09-08 10:24:51 +00:00
clog.Views = &sql.NullInt64{Int64: ldata.MaxViews, Valid: true}
if ldata.LiveStart != "" {
st, err := time.Parse("Mon, 02 Jan 2006 15:04:05 -0700", ldata.LiveStart)
2020-08-12 04:22:46 +00:00
if err == nil {
startTime := st
2020-09-08 10:24:51 +00:00
clog.LiveStartTime = &sql.NullTime{Time: startTime, Valid: true}
dt, err := strconv.Atoi(ldata.LiveDuration)
2020-08-28 11:07:12 +00:00
liveduration := time.Now().Sub(startTime)
switch {
case liveduration >= time.Hour*24*240:
streamer.Operator = 5
2020-08-28 11:07:12 +00:00
case liveduration >= time.Hour*24*60:
streamer.UpdateInterval = 60 * 24 * 30
case liveduration >= time.Hour*24*30:
streamer.UpdateInterval = 60 * 24 * 15
case liveduration >= time.Hour*24*15:
streamer.UpdateInterval = 60 * 24 * 7
case liveduration >= time.Hour*24*7:
streamer.UpdateInterval = 60 * 24 * 3
}
if err == nil {
endTime := startTime.Add((time.Duration)(dt) * time.Millisecond)
2020-09-08 10:24:51 +00:00
clog.LiveEndTime = &sql.NullTime{Time: endTime, Valid: true}
} else {
log.Println(err, streamer.UserId)
}
2020-08-11 10:26:17 +00:00
} else {
2020-08-12 04:22:46 +00:00
log.Println(err, streamer.UserId)
2020-08-11 10:26:17 +00:00
}
}
2020-09-08 10:24:51 +00:00
clog.StreamerUid = streamer.Uid
uid, err := intimate.TClog.InsertRetAutoID(clog)
if err != nil {
log.Println(err)
continue
}
streamer.LatestLogUid = uid
intimate.TStreamer.Update(streamer)
// estore.UpdateStreamer(streamer)
log.Println(*streamer.UserId)
2020-08-11 10:26:17 +00:00
}
}