兵長:
胖sir,最近一段時間正在使用golang來進行開發專案,慢慢的對golang
有了一些瞭解,突然有一天,我想用golang來實現爬取網站上的資料,例如天氣預報
,每日一句
等等
發現這些網站的資料都是javascript
動態生成,苦惱呀,不知道如何才能把網站上的動態資料
獲取下來,為我所用呀,例如我抓取到動態資料之後發郵件給我喲
胖sir撩撩了自己的長髮,溫和的對兵長說,小夥子,golang
做應用開發效率很快的,當然爬取網站上的資料也是不在話下的喲,動態的也有動態的方法,來我給你娓娓道來
Golang的安裝
此步驟主要是為了照顧沒有在linux
上安裝過golang的童鞋們,若自己做過安裝過golang的童鞋可以直接跳過golang簡單安裝步驟
下載golang軟體
- 【國內網站】
https://studygolang.com/dl
go語言中文網下載 go最新的安裝包,根據不同的系統,可以選擇windows,linux,mac
- 【可以上外網的話】訪問go語言英文網站
https://docs.studygolang.com/doc/install
解壓golang
tar -C /usr/local -xzf go1.16.linux-amd64.tar.gz
配置golang
將go的二進位制目錄新增到
PATH
環境變數vim /etc/profile export GOROOT=/usr/local/go export PATH=$PATH:$GOROOT/bin
重新匯入配置
source /etc/profile
chromedp框架的使用
chromedp框架
是github
開源的,童鞋們可以放心食用,若是有想法,可以在github
上為此添磚加瓦,為開源做出自己的一份貢獻
可以透過如下命令來進行下載
github.com/chromedp/chromedp
實際的程式碼編寫
兵長,你想爬取每日一句
的網站,我給你找一個例子,如爬取這個網站http://news.iciba.com/
,我們將網站上每天都會更新的一句話爬取出來
開始編碼
//獲取網站上爬取的資料
func GetHttpHtmlContent(url string, selector string, sel interface{}) (string, error) {
options := []chromedp.ExecAllocatorOption{
chromedp.Flag("headless", true), // debug使用
chromedp.Flag("blink-settings", "imagesEnabled=false"),
chromedp.UserAgent(`Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36`),
}
//初始化引數,先傳一個空的資料
options = append(chromedp.DefaultExecAllocatorOptions[:], options...)
c, _ := chromedp.NewExecAllocator(context.Background(), options...)
// create context
chromeCtx, cancel := chromedp.NewContext(c, chromedp.WithLogf(log.Printf))
// 執行一個空task, 用提前建立Chrome例項
chromedp.Run(chromeCtx, make([]chromedp.Action, 0, 1)...)
//建立一個上下文,超時時間為40s
timeoutCtx, cancel := context.WithTimeout(chromeCtx, 40*time.Second)
defer cancel()
var htmlContent string
err := chromedp.Run(timeoutCtx,
chromedp.Navigate(url),
chromedp.WaitVisible(selector),
chromedp.OuterHTML(sel, &htmlContent, chromedp.ByJSPath),
)
if err != nil {
logger.Info("Run err : %v\n", err)
return "", err
}
//log.Println(htmlContent)
return htmlContent, nil
}
GetHttpHtmlContent
做為一個爬取網站動態資料的介面,主要功能是爬取js
生成的動態資料(當然靜態資料更是不在話下)第一個引數
url
即為我們需要傳入的要爬取的網站地址,頁面如上第二個引數
selector
即為我們爬取的資料對應的選html擇器
, 透過谷歌瀏覽器進入網站,按F12
->點選左上角的滑鼠
->再點選我們需要爬取的資料
->就可以看到實際的html原始碼
(目前看到的是透過javascript
動態生成資料後的)右鍵點選
item-bottom
->Copy
->Copy selector
即可得到如下結果body > div.screen > div.banner > div.swiper-container-place > div > div.swiper-slide.swiper-slide-0.swiper-slide-visible.swiper-slide-active > a.item.item-big > div.item-bottom
此字串即為
GetHttpHtmlContent
函式的第二個引數selector
第三個引數 我們暫時先寫
document.querySelector("body") //從body裡面獲取資料
返回值 即為 爬取到的資料,是字串格式的,內容是
html
如下是擴充和解釋上述程式碼的內容
chromedp.Flag
給chromedp
設定引數,設定為無頭模式 headless
,無頭模式即Chrome瀏覽器的無GUI的命令列版瀏覽器,但功能上和我們平常使用的chrome沒有區別,若該引數不設定為true
,則在程式執行的時候,chromedp
會拉取我們環境中的chrome瀏覽器,顯示頁面chromedp.Flag("blink-settings", "imagesEnabled=false")
設定為不顯示圖片htmlContent
用於接收爬取的結果,是一個字串格式,具體內容是html
chromedp.ByJSPath
是隻以什麼方式進行解析,這是一個回撥函式,這個引數還可以填下面幾個,按需索取chromedp.ByNodeID
chromedp.BySearch
chromedp.ByID
chromedp.ByQueryAll
chromedp.ByQuery
chromedp.ByFunc
關於
chromedp
涉及的介面如下給兵長
介紹幾個名字 說明 Navigate 進入某個頁面 Run 執行各類操作 Screenshot 截圖 Click 模擬滑鼠點選 WaitVisible 等候某元素出現 ActionFunc 執行自定義函式 SendKeys 模擬鍵盤輸入
兵長: 使用這個框架我得到的是一串html
的字串,我也不會解析他呀,我要如何才能找到剛才在頁面上看到的每日一句
?
胖sir:別擔心,我一步一步給你說,直播教學呢,看好了, 現在我們已經完成了最核心的一步了,現在資料已經獲取到了,咯,我給你介紹一個神奇,goquery
就可以解決下面這一串html
的解析問題了
goquery第三方庫的使用
我之前寫過一個小介面,可以給你看看,兵長
goquery
也是github
開源的,童鞋們可以放心食用哦,透過如下命令在下載goquery第三方庫
go get github.com/PuerkitoBio/goquery
開始編碼
//得到具體的資料
func GetSpecialData(htmlContent string, selector string) (string, error) {
dom, err := goquery.NewDocumentFromReader(strings.NewReader(htmlContent))
if err != nil {
logger.Error(err)
return "", err
}
var str string
dom.Find(selector).Each(func(i int, selection *goquery.Selection) {
str = selection.Text()
})
return str, nil
}
第一個引數
htmlContent
就是 上面chromedp
爬取到的資料,是字串,內容是html
第二個引數即是
html
的選擇器 ,對於這個網站,這個引數可以填.chinese
,如GetSpecialData(htmlContent, ".chinese")
返回值就是我們要抓取的結果了
當你是在為夢想成真努力時,就不會有壓力。
如下是關於goquery一些用法
主要是關於html各種選擇器的寫法使用方式,下面簡單介紹一下種類,如果需要詳細瞭解,可以給我留言喲
- 基於HTML Element 元素的選擇器
- ID 選擇器
- Class選擇器
- 屬性選擇器
- parent > child選擇器
- element + next 相鄰選擇器
- element~next 兄弟選擇器
胖sir:兵長,我說的這些還算清楚吧,你知道怎麼用了嗎?
兵長:明~明白了,我還要多加練習,多多爬取一下不同的站資料看看效果
胖sir:誒,兵長剛才你說你想將資料處理完畢後,發郵件給你自己嗎?
兵長:對呀,誒呀,這又是個問題。我不知道把程式放在那裡呢,放在我自己電腦裡面的話,我電腦每天是要關機的,我休息了,我的電腦也要跟著我休息,誒,咋辦呀
胖sir:好辦,這個我可以推薦你用一下 阿里雲伺服器
如何將自己的程式部署到阿里雲伺服器上
自己買一個雲伺服器就可以很方便的將自己的監控程式或者需要一直執行的程式放在上面,這就可以7*24小時不間斷的跑了,我最近感受了一下,確實好用。具體的阿里雲購買方式可以嘗試掃描下面的二維碼或者點選連結進行購買,親測真的好用,如何使用和簡單配置,可以給我留言獲取資料。
當然,需要上述整個小案例原始碼的,也可以給我留言哦,讓我們一起實踐我們的每一個想法,一步一步往上爬。
胖sir:兵長,我需要提醒一點哦,阿里雲伺服器會自動把你的執行程式關閉掉了的
兵長:啊?那麼你還讓我買伺服器,你這不是坑我嗎
胖sir:別急,我推薦的肯定是好東西啦,還附帶解決方案喲
screen工具
screen工具可以幫助我們將可執行程式部署到阿里雲伺服器上面,且能夠一直不間斷的執行
原理:
screen是在伺服器上單獨開一個程式,讓他專門來執行後臺任務。
具體操作:
安裝
//ubuntu安裝 sudo apt-get install screen //centos yum install screen
建立screen視窗
screen -S name 例如: screen -S ssh
檢視程式
screen -ls
進入自己的manager
screen -r -d 自己的id 如: screen -r -d 5295
關閉screen程式
screen -S 程式名 -X quit
大家如果有需要,可以透過此連結購買阿里雲伺服器,目前萌新有優惠,親測很可,別問我是誰,我是小魔童哪吒。
https://www.aliyun.com/activity?taskCode=messenger2101&recordId=337686&usercode=&share_source=copy_link
作者:小魔童哪吒
本作品採用《CC 協議》,轉載必須註明作者和本文連結