选了付费问答类题目,在体验分答的过程中,发现分答的模式,提问者的答案被偷听是需要1元,提问者可以分成0.5元。想到几个问题: 1. 有哪些问题是可以赚到钱的。 2. 哪些人是在分答上赚到钱的。 3. 哪些人才是分答上最受欢迎的。 4. 能否从分答的数据上分析用户是否活跃,有没有前景。 显然,这些数据是无法直接在网上直接找到的。要想得到答案,需要爬取分答的数据。 之前没有搞过类似爬取,想尝试爬取的乐趣
通常的数据爬取都用python,也有很多成熟的爬取方案。但是,我想尝试一下Go。一来温习一下Go相关知识。二来学习Go上其他没有接触过的东西
` http://apis-fd.zaih.com/v1/accounts/587503258
返回的结果是json格式 ``{"answers count": 209, "avatar": "http://wx.qlogo.cn/mmopen/RZrGLEga7AiawE5sTQk0kItX6c9JR5dLkkKv1ZTosFv3Llc7upHc26pH8Ls75NYuDsr68pZzbic2UiaZqqgiaLEDVUngOpg0YgtI/0", "followers count": 16220, "gravity": -1, "id": 587503258, "income": 12777950, "introduction": "u4f17u591au660eu661fu827au4ebau7684u79c1u4ebau60c5u611fu4e13u5bb6uff0cu54a8u8be2u673au6784u82b1u9547u8463u4e8bu957fu3001u767eu4e07u7545u9500u4e66u4f5cu5bb6u2026u672cu5e73u53f0u6536u5165u5c06u5168u90e8u7528u4f5cu5973u6027u516cu76cau3002u5728u4f60u95eeu4e4bu524du5148u82b1u4e00u70b9u5c0fu94b1u628au522bu4ebau7684u542cu4e00u4e0buff0cu4e5fu8bb8u4e0du7528u95eeu5c31u80fdu627eu5230u7b54u6848u3002", "is black": false, "is followed": false, "is receive inquiry": true, "is verified": true, "nickname": "ayawawa", "price": 50000, "questions count": 3, "tags": [{"id": 17, "name": "u60c5u611f"}], "tenant": {}, "title": "u7545u9500u4e66u4f5cu5bb6uff0cu8457u6709u300au5b8cu7f8eu5173u7cfbu7684u79d8u5bc6u300bu7b49"} ``` 从上可以看到,个人信息基本都有了,回答个数(answers_count),收入(income),问题价格(price,分币)等等 奇怪地是,跟通用的api需要带个授权码appkey不同,分答接口是不需要票据就能直接拉取的。
` http://apis-fd.zaih.com/v1/accounts/587503258/answers?page=1ℴ_by=default&per_page=20
每个用户回答的题目结果,分页返回。可以通过轮询查询,只要返回了空结果就结束。 这里请求的结果有点多,就不贴了,直接对结果的格式进行分析。前面用户信息的格式,比较简单,但是要手工弄成Go的结构体也是一件麻烦事。任凭vim各种奇巧淫技终究累得半死。于是,想一定有从json的实例,直接转成Go结构体的,果然,搜到了json-to-go(https://mholt.github.io/json-to-go/)。用问题请求返回的结果。贴上去,处理结果如下 ``type AutoGenerated []struct { Answer struct { DateUpdated time.Time
json:"date_updated"Duration int
json:"duration"FreeKey interface{}
json:"free_key"ID string
json:"id"IsEnableReanswer bool
json:"is_enable_reanswer"IsFree bool
json:"is_free"IsLiked bool
json:"is_liked"IsOpposed bool
json:"is_opposed"IsReanswered bool
json:"is_reanswered"LikingsCount int
json:"likings_count"OpposedCount int
json:"opposed_count"QuestionID string
json:"question_id"Voice interface{}
json:"voice"}
json:"answer"Asker struct { AnswersCount int
json:"answers_count"Avatar string
json:"avatar"ID int
json:"id"Nickname string
json:"nickname"Price int
json:"price"Title string
json:"title"}
json:"asker"Content string
json:"content"DateCreated time.Time
json:"date_created"DateUpdated time.Time
json:"date_updated"DiscussionsCount int
json:"discussions_count"HasDiscussions bool
json:"has_discussions"ID string
json:"id"IsFendaAsk bool
json:"is_fenda_ask"IsSticky bool
json:"is_sticky"ListeningsCount int
json:"listenings_count"Offer int
json:"offer"Respondent struct { AnswersCount int
json:"answers_count"Avatar string
json:"avatar"ID int
json:"id"Nickname string
json:"nickname"Price int
json:"price"Title string
json:"title"}
json:"respondent"RespondentID int
json:"respondent_id"Status string
json:"status"Type string
json:"type"VisitorCount int
json:"visitor_count"} ``` 清晰明了,妥妥的。 接下来的套路就是“请求-返回-解包-存储" 使用Go自带的http包和json包,请求和解析一气呵成。
` // requestData request data from url and decode to data. func requestData(url string, data interface{}) (err error) { var resp *http.Response resp, err = http.Get(url) if err != nil { return } defer resp.Body.Close() dec := json.NewDecoder(resp.Body) err = dec.Decode(&data) return }
`
` stmt, err := db.Prepare("INSERT INTO account(AnswersCount, Avatar, FollowersCount, ID, IsFollowed, NickName, Price, Title) VALUES(?, ?, ?,?,?,?,?,?)")` 看到需要搞这么的成员数据,这么多的"?"。后面还有更庞大的结构体在等着我时,我觉得
这个时候,是该请出ORM来了,看了网上的介绍,ORM有 xorm 和 gorm ,分别看了xorm和gorm的文档。发现我还是喜欢有quickstart的文档,千言万语,不值一个demo简单明了。于是我选择了gorm先尝试一把,解决眼前问题再说,其他orm来日再来把玩,搞技术也要雨露均沾呀
` func (a Account) Save(dbName string) error { db, err := gorm.Open("sqlite3", dbName) if err != nil { return err } defer db.Close() db.AutoMigrate(&Account{}) db.Create(a) return nil }
` AutoMigrate封装了创建表格的细节。Create封装了插入表的细节。妥妥的
对已经存放在数据库里面的数据进行有目的的统计计算。以“ 有哪些问题是可以赚到钱的”为例,从question_dbs表和accounts表取出数据
` SELECT b.nickname, content, offer/100, listenings_count, (profit - offer/100) AS earn FROM (SELECT respondent_id, id, content, offer,listenings_count, listenings_count*0.45 as profit FROM question_dbs ORDER BY profit DESC LIMIT 10) a LEFT OUTER JOIN (select id, Nickname, price from accounts) b ON a.respondent_id = b.id;
输出结果 ``
王思聪|你如何分辨女票爱你的人还是爱你的钱?|4999|26887|7100.15 王思聪|我和你一样是网红,一样学哲学,我在分答回答最多的是你啪啪喜欢什么姿势,同样的问题我也问一下你|3000|23482|7566.9 王思聪|请问作为亚洲首富的儿子,您的人生还有什么买不起的?|3000|23294|7482.3 王思聪|作为一个普通人,特别想知道,校长平均在每个女朋友身上花费多少?|3000|20567|6255.15 王思聪|听说你是不婚主义,要是交往的女孩子意外怀孕怎么办?|3000|18932|5519.4 王思聪|你是如何处理和前女友的关系的,分手之后还是朋友吗?有没有分手后依然还爱的情况,如果有,你是怎么做的?|4999|18172|3178.4 王思聪|我替几千万适龄女性问吧:请问你择偶条件是什么?|3000|15219|3848.55 王思聪|校长,身边的朋友会找你借钱吧,如果不想借,您怎么推辞呢?如果借了,对方总拖着不还,您怎么办?|3000|13142|2913.9 王思聪|我是命理测算师,测算过你的命盘,但没有时辰颇多偏差。很想知道你和你家人是否算过命,对算命有什么看法?|4999|13111|900.95 章子怡|子怡好!每个行业都有潜规则。您觉得这些年演艺界最盛行的潜规则是什么?您遭遇过的最尴尬的潜规则是什么?|2929|11391|2196.95 ``` 结论:问题是否让人有偷听的意愿很关键,更关键地是答主的影响力。
分析出来的数据如果用表格,然后用图来表示,整个过程显得很繁琐,例如,月回答问题量,导出csv,再用excel打开,然后出图。如果数据有更新,又需要这个过程。 后面可以考虑,展示和数据结合在一起,数据按模板输出,数据更新了,刷新页面,重读数据即可。 想法:数据可交换性,鼠标放在点,有数据显示,后续再玩