用GO语言爬取今日热榜
之前一直想给网站做个热榜模块,奈何功力不够,用PHP怎么都搞不定,主要问题是对应各大榜单都要自己重新设置规则,而且很多站都是JS渲染页面,用PHP有点繁琐。
前几天无意浏览到有人分享的用GO抓取热榜,确实不错。通过多协程异步快速抓取信息,简化代码后本地测试无误。只是还是需要定义各大榜单的规则。
思前想后突然灵光一现,为什么不直接爬今日热榜呢!!!只需要对应一个站的规则即可获得几百个热榜榜单了呀!!!
说干就干,初学GO可能代码中有很多睿智的地方,凑活看吧,代码不多思路很简单,目前完美运行无报错,得到的结果我个人还是十分满意的。
运行截图
代码
package main
import (
"bytes"
"encoding/json"
"fmt"
"github.com/PuerkitoBio/goquery"
_ "github.com/go-sql-driver/mysql"
"io"
"net/http"
"strings"
"time"
)
func main(){
url := "https://tophub.today/"
timeout := time.Duration(15 * time.Second)
client := &http.Client{
Timeout: timeout,
}
var Body io.Reader
request, err := http.NewRequest("GET", url, Body)
if err != nil {
fmt.Println("抓取失败1")
return
}
res, err := client.Do(request)
if err != nil {
fmt.Println("抓取失败2")
return
}
defer res.Body.Close()
document, err := goquery.NewDocumentFromReader(res.Body)
if err != nil {
fmt.Println("抓取失败3")
return
}
var allData []map[string]interface{}
document.Find(" .kb-lb-ib-c a").Each(func(i int, selection *goquery.Selection) {
url, boolUrl := selection.Attr("href")
sort := selection.Find(".gb-c").Text()
if(boolUrl && sort!="首页"){
sort_url := "https://tophub.today"+url
sort_timeout := time.Duration(15 * time.Second)
sort_client := &http.Client{
Timeout: sort_timeout,
}
var sort_Body io.Reader
sort_request, err := http.NewRequest("GET", sort_url, sort_Body)
if err != nil {
fmt.Println("抓取失败4")
return
}
sort_res, err := sort_client.Do(sort_request)
if err != nil {
fmt.Println("抓取失败5")
return
}
defer sort_res.Body.Close()
sort_document, err := goquery.NewDocumentFromReader(sort_res.Body)
if err != nil {
fmt.Println("抓取失败6")
return
}
sort_document.Find(".bc-cc div").Each(func(i int, selection *goquery.Selection) {
id, _ := selection.Attr("id")
typeName := selection.Find(".cc-cd-lb").Text()
typeName = strings.Replace(typeName, " ", "", -1)
document.Find("#"+id+" .nano-content a").Each(func(i int, selection *goquery.Selection) {
url, boolUrl := selection.Attr("href")
text := selection.Find(".t").Text()
if boolUrl {
allData = append(allData, map[string]interface{}{"sort": sort,"type": typeName,"title": text, "url": url})
}
})
})
}
})
od, _ := JSONMarshal(allData,true)
fmt.Println(string(od))
}
//替换转译字符
func JSONMarshal(v interface{}, safeEncoding bool) ([]byte, error) {
b, err := json.Marshal(v)
if safeEncoding {
b = bytes.Replace(b, []byte("\\u003c"), []byte("<"), -1)
b = bytes.Replace(b, []byte("\\u003e"), []byte(">"), -1)
b = bytes.Replace(b, []byte("\\u0026"), []byte("&"), -1)
}
return b, err
}
声明:本站(www.mysqlschool.cn)所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
评论(4)
你好
我能提交代码吗
暂时还没开放投稿功能
评论功能已经开启,欢迎投稿。