Go爬蟲攻防思考分享
技術標籤:研發經驗
背景
最近和朋友討論瞭如何使用指令碼檢查自己釋出的幾十篇釋出在某網站的文章是否還在。我把用到的技術簡單分享一下。
一、使用Golang如何爬取網頁內容。
以前用過php和python寫過爬蟲,這次分享一下最近一個使用
首頁總結一下這裡涉及到的技術點,爬取網站的內容需要用到這二個內建庫:
"io/ioutil"
"net/http"
於是有了這段程式碼:
package tools
import (
"io/ioutil"
"net/http"
)
func GetUrl(url string ) string {
res, err :=http.Get(url)
if err != nil {
return ""
}
robots, err := ioutil.ReadAll(res.Body)
res.Body.Close()
if err != nil {
return ""
}
return string(robots)
}
要注意的是,這裡返回的string是根據頁面指定輸出的格式。除非頁面返回utf-8,否則像返回gbk或者gb2312等常見的中文網頁,特別是2010年以前流行起來的網站,有不少並不是utf-8。那麼這裡會返回亂碼。
二、請求被攔截怎麼辦?
1 cookie紀錄了請求頻次
一般的網站對短時間請求較多的客戶端會提示先輸入驗證碼,然後才能繼續下一步。安全級別更高的網站會檢查是不是機器破解了驗證碼。而有的網站會在cookie裡簡單地判斷客戶端是否頻繁開啟頁面,這種做法只要客戶端不紀錄cookie,完全沒有防範效果。如果您是網站的管理員,就要意思到只使用這一招基本上沒有防範的效果。
2 服務端判斷agent是否真實
一般爬蟲的請求沒有特別注意時,會使用空的user-agent或者工具預設的user-agent。例如下圖,我的請求User-Agent是:
有的伺服器會判斷user-agent是否真實,如果請求帶過來的資訊是機器生成的,不能從中拿到準確的瀏覽器資訊,則會拒絕服務。
既然意識到這個問題,那就可以將agent進行修改,就會繞過大量服務端程式的監測。大部分網站只會做到這一步。
3 觸發IP鎖定
如果 IP 被識別並被封禁,那一定是嚴重觸犯了網站的規則。因為大多數網站不會輕易封禁使用者IP。原因很簡單,假如使用者所在的網路是學校、公司內網,用統一的IP訪問,那麼封禁這個IP等於將其所在網路的所有使用者都封禁了。
這時候如果有一個IP代理連線池,本機能不斷地更換IP地址,便能解決這個問題。只要某個IP訪問次數不要太誇張,一般網站無識通過IP識別其單位時間內的請求是否為爬蟲。更多網站會把防範重心放在惡意攻擊上。
4 網站做了 csrf
關於 csrf 又是一個更專業網站安全的話題,如果本文章的點贊數超過20,我再寫一篇關於csrf攻防相關的文章。現在僅有網頁的連結地址,也無法爬取到網頁內容。但仔細一想,網頁始終是要被開啟的,不然怎麼被使用者檢視。
現在有不少開源的無UI的瀏覽器外掛,使用它們來進行網頁請求,而不是一次簡單地curl_get 或者 curl_post,這種方式可以大大地增加伺服器的反爬蟲成本。推薦一個工具:Selenium+PhantomJS。當然,這是使用python來做的。
5 其它
如以上都通過,還可以再判斷一下伺服器是否檢查了 reffer。當然還有其它,這裡就不再展開。
三、併發請求
既然使用go來進行爬蟲,在完成以上攔截的處理後,可以使用go的協程來對爬蟲速度加速請求。