反爬蟲和抗DDOS攻擊技術實踐

導語

企鵝媒體平臺媒體名片頁反爬蟲技術實踐,分佈式網頁爬蟲技術、利用人工智能進行人機識別、圖像識別碼、頻率訪問控制、利用無頭瀏覽器PhantomJS、Selenium 進行網頁抓取等相關技術不在本文討論範圍內。html

你們都知道http請求是無狀態的,爲了讓http請求從「無狀態」 to 「有狀態」 , W3C 在 rfc6265 中描述了整個http協議的狀態機制,既從客戶端(一般是瀏覽器)到服務器端的流轉過程,cookie 的引入使得 服務器在 接收到請求時能夠區分用戶和狀態。程序員

經過上邊這張圖,咱們能夠容易的發現,這個過程就好像「上車打票」同樣,有普通票(不記名)和 也月票(「記名的票」),有位偉大的程序員曾經說過「若是你的程序邏輯和實際生活中的邏輯反了,就必定是你錯了」。web

言歸正傳,爲何反爬蟲

互聯網有不少業務或者說網頁,是不須要用戶進行登陸的(不記名的票),你能夠簡單的認爲這實際上是一個「不須要記錄http狀態的業務場景」(注意這裏是簡單認爲,但其實並非無狀態的),那這些不須要登陸的頁面,每每又會包含大量的聚合信息,好比新聞門戶網站、視頻門戶網站、搜索引擎,這些信息是公開的,實際上是能夠能夠被爬蟲抓取的,站長甚至還要作SEO(搜索引擎優化)讓搜索引擎或其餘網站更多更常常的去收錄本身的整站,以便推廣,那既然咱們要作SEO優化爲何還要 「反爬蟲」 ?網頁爬蟲

由於經過程序進行 URL 請求 去得到數據的成本是很低的,這就形成大量抵質量網頁爬蟲在網絡橫行,對業務方的服務器形成沒必要要的流量浪費和資源消耗。瀏覽器

網頁爬蟲到底有多容易

正常打開的界面內容是這樣的安全

查看網頁源代碼,看看咱們要抓取的目標,這裏就不在演示了,而後利用Chrome開發者工具提供的 「Copy as curl」服務器

curl 'https://v.qq.com/' -H 'Pragma: no-cache' -H 'DNT: 1' -H 'Accept-Encoding: gzip, deflate, sdch, br' -H 'Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.4' -H 'Upgrade-Insecure-Requests: 1' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8' -H 'Cache-Control: no-cache' -H 'Cookie: tvfe_boss_uuid=ad12b5df44c4af49; ad_play_index=34; pgv_info=ssid=s9710442890; ts_last=v.qq.com/; pgv_pvid=7925047056; ts_uid=578794400; qv_als=778esxpJSKmr5N0bA11491899166PnRBKw==' -H 'Connection: keep-alive' --compressed 

而後你會發現,與「查看網頁源代碼」 沒有區別,說明咱們已經成功得到數據內容。cookie

反爬蟲效果是什麼樣的?

咱們經過瀏覽器直接打開下面這個連接 ,會發現請求到的結果是個JSON網絡

如今咱們重複剛剛的 「Copy as curl」 的過程,看看是否依然能得到正確結果 ? 答案是否認的,咱們來驗證一下app

curl 'https://media.om.qq.com/media/5054675/list' -H 'pragma: no-cache' -H 'dnt: 1' -H 'accept-encoding: gzip, deflate, sdch, br' -H 'accept-language: zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.4' -H 'upgrade-insecure-requests: 1' -H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36' -H 'accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8' -H 'cache-control: no-cache' -H 'authority: media.om.qq.com' -H 'cookie: signiture=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjpbXSwiZWkiOjUsInN0IjoiMTQ5MTg5OTczNjQ3NyIsImlhdCI6MTQ5MTg5OTc0M30.fTAsbJZNOTsHk0QoLfZIA-AXhO6ezaCOiCTj8lYCqO4; tvfe_boss_uuid=ad12b5df44c4af49; pgv_info=ssid=s9710442890; pgv_pvid=7925047056; omuisid=eyJ1aWQiOiI5ZGVjMjRiN2UxM2FiNGUyZWJjNWRhMGU1N2EyYTRkZSJ9; omuisid.sig=5wAr5khpxGvFDp3WpkJ6_QX9iE4' -H 'referer: https://media.om.qq.com/media/5054675/list' --compressed 

咱們會發現獲得的是一個網頁而不是 JSON,命中了反爬蟲邏輯

到底發生了什麼?

前面提到了 「不記名票據」 和 因推廣需求網站不須要登陸的場景,那針對這樣的狀況,是否咱們就真的不須要對請求進行簽名呢 ? 答案是否認的,不花錢或花不多的錢就能夠免費進入公園遊玩了,遊客可能自己是感覺不到「票據」的存在,但其實咱們仍是須要對用戶進行標記,這裏發散一下,其實統計網站在追蹤pv/uv時也是進行了相似的「標記」,下面咱們經過一張圖來描述下上面請求發生的過程

這裏咱們有兩次簽名過程,一次在服務器端進行,一次在客戶端進行,由於在這個頁面是不須要用戶登陸,因此在服務器端進行簽名,對於爬蟲來講是一個幾乎沒有成本的過程,它能夠每次來「園子」裏玩的時候,都申請一張新的票,假裝成爲一個「新的用戶」,爲了應對如此低廉的成本,咱們增長「客戶端進行簽名」的流程,有人說「客戶端簽名是不靠譜的,由於你的代碼別人都是能夠看到的是能夠破解的」,這個地方的客戶端簽名不是爲了數據安全,而是爲了增長爬蟲進行抓取的成本,由於通常網頁爬蟲都不具有 js 之行能力,這樣就增長了它抓取的成本。

另一點,簽名雖然是由客戶端簽發的,可是倒是由服務器端進行驗證,咱們這裏是利用 JWT(JSON WEB TOKEN) 進行了 encode和decode過程,且經過將服務器時間對客戶端進行下發,完成有效期控制。

起到必定的防DDOS攻擊的效果

經過上圖咱們能夠看到,關鍵就是兩次票據的簽發與驗證,一次由瀏覽器簽發,一次由後臺簽發,可是驗證真僞都是在服務端進行,這樣作的最終效果就是,要對咱們的界面進行抓取或攻擊的人,必須按照咱們設定的套路運轉,就會增長他下載js並執行咱們js的過程,若是有攻擊方利用xss 獲的肉機,對咱們的域名發起攻擊時,因爲咱們有兩次票據驗證,而去其中有一個票據的有效期時間很短,基本上不太可能對咱們的服務器形成連續傷害了。

若是網頁抓取人,經過使用徹底模擬瀏覽器的運行環境的第三方軟件(PhantomJS、Selenium,WEBDRIVER)對咱們進行抓取,其實效率是很慢的,基本上須要5-6秒完成一次, 基本上比一個真實的用戶打開網頁還要慢不少,對於這種能夠當成是真是用戶同樣對待,數據原本就是開放的

接入這套反爬、防DDOS邏輯後,從模調系統查看數據後臺服務被擊穿的現象已經完成消失,異常流量已被隔離。

相關文章
相關標籤/搜索