前言
“白日依山尽,___”。下句自然填黄河入海流,那么“日月忽其不淹兮,___,___,恐美人之迟暮”,中间两句怎么填呢?
最近工作中有个需求,就是1500道语文诗词填空题没有答案,现在需要给这些题目大爷们匹配它们对应的答案,好在题目信息都很完整,指出了诗词出处、作者信息。自然想到到网上爬取对应文章信息然后字符串匹配答案。目前做完,效果还可以,基本上所有题目的答案都有了,现把操作流程记录下,做个总结。
1. 文章信息获取
网上找了很久,目前发现百度汉语对古诗词收录的比较好,格式也比较规范,整个爬取过程还是比较简单,浏览器分析网站,找到它们的搜索接口:http://hanyu.baidu.com/hanyu/ajax/sugs只需要传一个参数:mainkey,是一个urlencode格式的字符串。接口会返回一个匹配列表,再用作者名称对这个列表做筛选,详细
baseUrl := "http://hanyu.baidu.com/hanyu/ajax/sugs?"
client := &http.Client{
}
u, _ := url.Parse(baseUrl)
q := u.Query()
q.Set("mainkey", name)
u.RawQuery = q.Encode()
//添加Header
req, _ := http.NewRequest("GET", u.String(), nil)
req.Header.Add("User-Agent", `Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36`)
req.Header.Add("DNT", "1")
req.Header.Add("Host", "hanyu.baidu.com")
req.Header.Add("Accept-Language", "zh-CN,zh;q=0.8")
req.Header.Add("Referer", "http://hanyu.baidu.com/shici/detail?pid=be520db056da43238035dc18bb1e1798&tn=sug_click")
resp, errDo := client.Do(req)
拿到返回值以后,筛选出对应的作者信息。
//如果有多个搜索结果,比对author是否正确
respJson.ForEach(func(key, value gjson.Result) bool {
//先看看有没有display_name
displayName := value.Get("display_name.0").String()
sid := value.Get("sid.0").String()
if len(displayName) == 0 {
//不是这条记录
return true
}
//看看type
typeStr := value.Get("type.0").String()
if typeStr == "poemline"{
//取Source
displayName = value.Get("source_poem.0").String()
sid = value.Get("source_poem_sid.0").String()
}
literatureAuthor := value.Get("literature_author.0").String()
//author是否一致
if literatureAuthor == author {
searchResult.Sid = sid
searchResult.DisplayName = displayName
searchResult.Author = literatureAuthor
return false
}
return true // keep iterating
})
SearchResult保存了搜索到的结果,根据sid拿到文章页面,解析出其中的文章。
func GetContent(sid string) (content string, err error) {
baseUrl := "http://hanyu.baidu.com/shici/detail"
result := make([]string, 0, 0)
client := &http.Client{
}
u, _ := url.Parse(baseUrl)
q := u.Query()
q.Set("pid", sid)
u.RawQuery = q.Encode()
req, _ := http.NewRequest("GET", u.String(), nil)
req.Header.Add("User-Agent", `Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36`)
req.Header.Add("DNT", "1")
req.Header.Add("Host", "hanyu.baidu.com")
req.Header.Add("Accept-Language", "zh-CN,zh;q=0.8")
req.Header.Add("Referer", "http://hanyu.baidu.com/shici/detail?pid=be520db056da43238035dc18bb1e1798&tn=sug_click")
resp, errDo := client.Do(req)
if errDo != nil || resp.StatusCode != 200 {
err = errors.New("无法连接百度汉语 " + errDo.Error())
return
}
docm, errDoc := goquery.NewDocumentFromResponse(resp)
if errDoc != nil {
err = errors.New("解析Doc错误 " + errDoc.Error())
return
}
//诗词信息都保存在 body_p 的div中,可以通过PuerkitoBio/goquery库获取
pSelect := docm.Find("#body_p")
pSelect.Each(func(pos int, selection *goquery.Selection) {
content := strings.TrimSpace(selection.Text())
result = append(result, content)
})
content = strings.Join(result, "")
return
}









