用GO语言爬取今日热榜

之前一直想给网站做个热榜模块,奈何功力不够,用PHP怎么都搞不定,主要问题是对应各大榜单都要自己重新设置规则,而且很多站都是JS渲染页面,用PHP有点繁琐。

前几天无意浏览到有人分享的用GO抓取热榜,确实不错。通过多协程异步快速抓取信息,简化代码后本地测试无误。只是还是需要定义各大榜单的规则。

思前想后突然灵光一现,为什么不直接爬今日热榜呢!!!只需要对应一个站的规则即可获得几百个热榜榜单了呀!!!

说干就干,初学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
}

 

发表评论

后才能评论

评论(4)