pyrthon 簡單爬蟲實現

簡單爬蟲的通用步驟

html

 

本文首發:ZKeeer’s Blog——簡單爬蟲的通用步驟
代碼基於 python3.5
多圖預警,長文預警前端

知識點不少,適合小白,大神繞路python

 

爬蟲,python,python爬蟲,多線程爬蟲,多進程爬蟲,分佈式爬蟲,增量式爬蟲,反爬蟲

1.獲取數據

爬蟲,就是要想方設法地裝成瀏覽器從網站騙數據。——我說的git

1.1從requests.get()提及

最開始一個簡單的爬蟲就是調用python的requests模塊,使用get函數。(爲了避免禍害別人網站,我以本身的網站爲例)github

import requests
url_response = requests.get("http://zkeeer.space")
print(url_response.status_code, url_response.text)

這裏get函數從給出的URL獲取數據,打印出狀態碼和獲取的內容看看。正則表達式

200 <!DOCTYPE html>
<html lang="zh-CN">
 <head>......

狀態碼200,說明平穩落地。後面是獲取到的網頁。算法

這裏要說明一點,url_response.text 和 url_response.content的區別:數據庫

.text返回的是Unicode類型,.content返回的是bytes型也就是傳說的二進制的數據。當須要的數據是文本時,最好用.text,當你須要下載圖片時,要用.contentjson

上面是.text返回的值,下面打印出來.content的值讓你們看看。瀏覽器

200 b'<!DOCTYPE html>\r\n<html lang="zh-CN">\r\n <head>

看到前面的小b以及後面赤裸裸的\r\n了麼?

個人博客挺簡單沒有那麼大訪問量,也不須要限制訪問量,也不須要嚴查你的IP,UserAgent,Cookie等。當你須要大量,高頻次訪問,並且訪問的仍是淘寶這樣的商業網站,這時候你就須要假裝了,不能只是赤裸裸的用個get加個url,就向網站大喊:「我!瀏覽器!給數據!」 也就個人博客這麼好心給你,淘寶早就會「淘寶不想理你,並向你扔了個大創可貼」。

1.2學會使用火狐瀏覽器開發者工具

如何假裝一個瀏覽器?

學習固然都是從模仿開始——也是我說的!

這裏使用的是火狐瀏覽器開發者工具,別聽這麼高大上,其實就是打開火狐瀏覽器按F12!

第一步輸入網址進入個人博客,http://zkeeer.space 而後按F12,找到網絡這一欄。它會提示你從新載入,那就按一下F5,刷新一下。

爬蟲,python,python爬蟲,多線程爬蟲,多進程爬蟲,分佈式爬蟲,增量式爬蟲,反爬蟲

注意如下幾欄。而後找到並點開咱們須要的,也就是第一個爬蟲,python,python爬蟲,多線程爬蟲,多進程爬蟲,分佈式爬蟲,增量式爬蟲,反爬蟲

右側會出來對應的詳細信息。包括:消息頭,Cookie,參數,響應,耗時,堆棧跟蹤。

首先requests.get(url,  params=None,  **kwargs),下面的順序按照參數順序,一一來。

1.3requests.get()參數一:url

消息頭這一欄給出的請求方法是GET,即請求時使用requests.get(),若是這裏是POST,對應使用requests.post()。get函數的url,即請求頭的Host,這裏是「zkeeer.space」

爬蟲,python,python爬蟲,多線程爬蟲,多進程爬蟲,分佈式爬蟲,增量式爬蟲,反爬蟲

 

1.4requests.get()參數二:params

get(url,  params=None,  **kwargs)中params,是構成網址中一些參數,網址連接「?」後面的那些參數。舉個栗子:個人一篇文章連接是http://zkeeer.space/?p=383 那麼後面p=383就是get 的參數(固然你也能夠直接訪問http://zkeeer.space/?p=383,而不須要參數)。

爬蟲,python,python爬蟲,多線程爬蟲,多進程爬蟲,分佈式爬蟲,增量式爬蟲,反爬蟲

須要把這裏列舉的參數都寫到params裏面,哪怕是該參數沒有值。

那麼一開頭咱們那幾行代碼就應該這麼寫了。

import requests

tar_url = "http://zkeeer.space"  # 目標網頁
param = {"p": 383}  # 請求頭的參數
url_response = requests.get(url=tar_url, params=param)
print(url_response.status_code, url_response.text)

這樣獲取到的頁面就是「zkeeer.space/?p=383」對應的文章了。

爬蟲,python,python爬蟲,多線程爬蟲,多進程爬蟲,分佈式爬蟲,增量式爬蟲,反爬蟲

 

1.5requests.get()參數三:headers

可能會有疑問,get(url,  params=None,  **kwargs)並無headers這個參數啊。這個包含在**kwargs裏面,一樣還有另外一經常使用的proxies,待會兒會說到。

headers應該寫什麼呢?下圖所示的消息頭中的請求頭便是這裏的headers參數。

爬蟲,python,python爬蟲,多線程爬蟲,多進程爬蟲,分佈式爬蟲,增量式爬蟲,反爬蟲

跟參數同樣,須要把請求頭的全部信息寫入headers(若是網站不查cookie的話,cookie不必寫)。若是對這些參數不瞭解,能夠點擊後面對應的詳細瞭解,介紹的很詳細。

上面的幾行代碼又要進化了。

import requests

tar_url = "http://zkeeer.space"  # 目標網頁
param = {"p": 383}  # 請求頭的參數
header = {  # 請求頭部
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:55.0) Gecko/20100101 Firefox/55.0",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
    "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3",
    "Accept-Encoding": "gzip, deflate",
    "Referer": "http://zkeeer.space/",
    "Connection": "keep-alive",
    "Upgrade-Insecure-Requests": "1"
}
url_response = requests.get(url=tar_url, params=param, headers=header)
print(url_response.status_code, url_response.text)

這樣一來就比較完備了。

可是這樣狀況下,高頻次訪問對服務器形成壓力了,可能會分析哪一個UserAgent訪問次數最多,發現是你在狂刷人家網站,這時候就有可能給你禁了這個UserAgent,這時候你須要更多的UserAgent隨機挑選進行訪問。

我在上篇文章《獲取爬蟲所須要的代理IP》中的代碼中就有收集的UserAgent,見Github 。

爬蟲,python,python爬蟲,多線程爬蟲,多進程爬蟲,分佈式爬蟲,增量式爬蟲,反爬蟲

可使用random.choice()隨便挑嘛。

1.6requests.get()參數四:proxies

上面提到了,這個參數是代理,對,是代理。當你使用隨機UserAgent的人家無法封了。就會查你IP,發現這個IP刷爆了網站,直接就封了。這時候你要使用代理IP。

上面的代碼又進化了呢!

import requests

tar_url = "http://zkeeer.space"  # 目標網頁
param = {"p": 383}  # 請求頭的參數
proxy = {"http": "http://{}:{}".format("221.8.186.249", "80"),
         "https": "https://{}:{}".format("221.8.186.249", "80")}  #代理IP
header = {  # 請求頭部
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:55.0) Gecko/20100101 Firefox/55.0",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
    "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3",
    "Accept-Encoding": "gzip, deflate",
    "Referer": "http://zkeeer.space/",
    "Connection": "keep-alive",
    "Upgrade-Insecure-Requests": "1"
}
url_response = requests.get(url=tar_url, params=param, proxies=proxy, headers=header)
print(url_response.status_code, url_response.text)

問題又來了,長時間使用同一個代理IP,也會被封啊,我要獲取大量代理IP,最好仍是匿名或者高匿。這些代理IP從哪來的?我該怎麼獲取?上篇文章我寫了若是獲取大量代理IP以及使用:獲取爬蟲所須要的代理IP 

若是須要高質量IP能夠從代理網站或者淘寶買,大量,不貴。

1.7總結

至此,基本的獲取網頁已經差很少了,大多數網站你均可以暢行。儘管,也不能暴力訪問一個網站,要有公德心嘛,我寫爬蟲還sleep(0.5)呢。

火狐瀏覽器的開發者工具很好用,但願你們能發揮其做用。

2.提取數據

獲取完網頁接下來應該提取數據了。獲取網頁的數據,我想提取網頁中特定的文字,或者是數據,或者是圖片,這就是網頁主要提取的吧。

2.1提取文字

先說提取文字,強烈推薦正則表達式,太強大了。簡直就是加特林噠噠噠噠冒藍火的那種;正則在手,天下我有;固然個人水平僅限於能用,就不出來獻醜了。你們按照網上的教程來就能夠。固然你也能夠用beautifulsoup。正則表達式和beautifulsoup這兩種效率比較高。

2.2提取圖片

以我博客中《獲取爬蟲所須要的代理IP》文章爲例,提取其中的圖片。提取網頁中的圖片,咱們能夠用提取文字的方式,用正則表達式獲取圖片連接。這時候,又用的get函數。跟獲取網頁同樣,獲取圖片。記得前面說過的text和content的區別。這裏要使用後者。那麼如何保存一張圖片呢?看下面的代碼示例。

打開火狐瀏覽器開發者工具。此次使用的是查看器,而不是網絡。一層層找到上面文章中的圖片所在位置及相關連接。

爬蟲,python,python爬蟲,多線程爬蟲,多進程爬蟲,分佈式爬蟲,增量式爬蟲,反爬蟲

找到了<img>標籤,這時能夠右鍵查看網頁源代碼,查找一下看有多少是跟你目標類似的,看看如何區分

爬蟲,python,python爬蟲,多線程爬蟲,多進程爬蟲,分佈式爬蟲,增量式爬蟲,反爬蟲

我找到了10項,但只有一項是我須要的,因而我把正則式寫成了

<img class=\"[^\"]+\" src=\"([^\"]+)\"

這時候能夠用 站長工具-正則表達式在線測試 測試下本身寫的正則表達式是否正確

爬蟲,python,python爬蟲,多線程爬蟲,多進程爬蟲,分佈式爬蟲,增量式爬蟲,反爬蟲

成功了!代碼以下:

import re

import requests

tar_url = "http://zkeeer.space"  # 目標網頁
param = {"p": 383}  # 請求頭的參數
header = {  # 請求頭部
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:55.0) Gecko/20100101 Firefox/55.0",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
    "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3",
    "Accept-Encoding": "gzip, deflate",
    "Referer": "http://zkeeer.space/",
    "Connection": "keep-alive",
    "Upgrade-Insecure-Requests": "1"
}
url_response = requests.get(url=tar_url, params=param, headers=header)

img_url = re.findall(r"<img class=\"[^\"]+\" src=\"([^\"]+)\"", url_response.text)
print(img_url[0])

輸出結果:

http://zkeeer.space/wp-content/uploads/2017/08/邏輯圖-1024x576.png

這樣有了圖片的連接,咱們就可使用連接獲取並保存圖片了。

必定要注意使用F12,並仔細查看請求頭和參數!

必定要注意使用F12,並仔細查看請求頭和參數!

必定要注意使用F12,並仔細查看請求頭和參數!

import re

import requests

tar_url = "http://zkeeer.space"  # 目標網頁
param = {"p": 383}  # 請求頭的參數
header = {  # 請求頭部
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:55.0) Gecko/20100101 Firefox/55.0",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
    "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3",
    "Accept-Encoding": "gzip, deflate",
    "Referer": "http://zkeeer.space/",
    "Connection": "keep-alive",
    "Upgrade-Insecure-Requests": "1"
}
url_response = requests.get(url=tar_url, params=param, headers=header)


img_header = {  # 請求頭部
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:55.0) Gecko/20100101 Firefox/55.0",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
    "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3",
    "Accept-Encoding": "gzip, deflate",
    "Referer": "http://zkeeer.space/?p=383",
    "Connection": "keep-alive",
    "Upgrade-Insecure-Requests": "1"
}
# 獲取圖片連接
img_url = re.findall(r"<img class=\"[^\"]+\" src=\"([^\"]+)\"", url_response.text)[0]
# 從圖片連接中提取圖片名
img_name = re.findall(r"([^/]+.png)", img_url)[0]
# 請求
url_response = requests.get(url=img_url, headers=img_header)
# 保存圖片
with open(img_name, "wb") as fw:
    fw.write(url_response.content)

運行程序查看獲得的圖片(個人vps配置特別低,速度特慢,輕噴。給Vultr的VPS打個廣告,有優惠!

爬蟲,python,python爬蟲,多線程爬蟲,多進程爬蟲,分佈式爬蟲,增量式爬蟲,反爬蟲

好了,到這兒能夠獲取基本的網頁信息了。並且高頻次訪問基本上不會被封。
你覺得到這就結束了嗎?

2.3提取動態加載的數據

在獲取有些重要數據的時候。這些數據是動態加載的。這也是反爬蟲的一種手段,下面我有說起反爬蟲。

當我只獲取這個網頁的時候,根本不會顯示這些數據。這個時候又要讓你的爬蟲裝一次瀏覽器。固然不能說:我!瀏覽器!給數據! 這個時候你不光要賣萌,還要回答問題。快看快看,我是瀏覽器,我是可愛的瀏覽器,快給我數據啊。

這時候人家就問你,你是從哪兒(Refer)找到個人?你的雞毛信(ID)呢?你從袖筒裏排出幾個參數,瀏覽器一看,哎呀,大兄弟,真的是你,快給你數據。這時候不要吭聲,趁他不注意,拿了數據趕忙跑。

爬蟲,python,python爬蟲,多線程爬蟲,多進程爬蟲,分佈式爬蟲,增量式爬蟲,反爬蟲

獲取方式跟上面獲取網頁同樣。一樣是使用火狐。以淘寶米6商品評論爲例,我隨便找的,別說我軟廣:

爬蟲,python,python爬蟲,多線程爬蟲,多進程爬蟲,分佈式爬蟲,增量式爬蟲,反爬蟲

點擊評論,而後看到網絡這一欄,動態加載的內容就出來了,從域名裏我找到了rate.taobao.com,對應左邊兩個文件,一個是detailCommon.htm 另外一個是freeRateList.htm;我查看了下,分別對應評論中的你們印象和詳細評論。查看哪兒?查看對應的響應內容。

這裏就以「你們印象」爲例:按照1.獲取數據的步驟,獲取到了以下結果:

import re
import requests

tar_url = "https://rate.taobao.com/detailCommon.htm"
# 商品連接
refer = "https://item.taobao.com/item.htm?spm=a230r.1.14.119.76bf523Zih6Ob&id=548765652209&ns=1&abbucket=12"
# 從商品連接中提取商品ID
NumId = re.findall(r"id=(\d+)\&", refer)
# 參數
param = {"auctionNumId": NumId,
         "userNumId": "43440508",
         "callback": "json_tbc_rate_summary"}
# 頭部信息
header = {
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    'Accept-Encoding': 'gzip, deflate, compress',
    'Accept-Language': 'zh-CN,zh;q=0.8,en;q=0.6,ru;q=0.4',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive',
    'Upgrade-Insecure-Requests': "1",
    'Referer': refer,
    'User-Agent': "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:55.0) Gecko/20100101 Firefox/55.0"
}

try:
    url_content = requests.get(url=tar_url, params=param, headers=header)
    print("url_content: ", url_content.text)
except BaseException as e:
    pass

結果:

json_tbc_rate_summary({"watershed":100,"isShowDefaultSort":true,"askAroundDisabled":false,"sellerRefundCount":6,"skuSelected":true,"data":{"newSearch":false,"count":{"total":4689,"tryReport":0,"goodFull":4622,"additional":243,"correspond":0,"normal":30,"hascontent":0,"good":4622,"pic":588,"bad":37,"totalFull":4689},"spuRatting":[],"correspond":"4.8","impress":[{"title":"手機不錯","count":477,"value":1,"attribute":"620-11","scm":""},{"title":"手機是正品","count":243,"value":1,"attribute":"1020-11","scm":""},{"title":"系統很強大","count":214,"value":1,"attribute":"921-11","scm":""},{"title":"態度不錯","count":144,"value":1,"attribute":"10120-11","scm":""},{"title":"款式好看","count":115,"value":1,"attribute":"121-11","scm":""},{"title":"快遞不錯","count":108,"value":1,"attribute":"420-11","scm":""},{"title":"手感很好","count":90,"value":1,"attribute":"721-11","scm":""},{"title":"性價比很高","count":85,"value":1,"attribute":"20520-11","scm":""},{"title":"性能通常","count":39,"value":-1,"attribute":"921-13","scm":""},{"title":"配件通常","count":35,"value":-1,"attribute":"621-13","scm":""}],"attribute":[{"name":"版本類型","options":[{"name":"中國大陸","value":"中國大陸"}]},{"name":"版本類型","options":[{"name":"中國大陸","value":"中國大陸"}]},{"name":"版本類型","options":[{"name":"中國大陸","value":"中國大陸"}]},{"name":"版本類型","options":[{"name":"中國大陸","value":"中國大陸"}]}]},"skuFull":false,"showPicRadio":true,"isRefundUser":true})

最外層是個json_tbc_rate_summary()回調函數,它的參數是個詞典,咱們詞典拿出來,放到python中看起來就比較方便了。

處理結果:

爬蟲,python,python爬蟲,多線程爬蟲,多進程爬蟲,分佈式爬蟲,增量式爬蟲,反爬蟲

爬蟲,python,python爬蟲,多線程爬蟲,多進程爬蟲,分佈式爬蟲,增量式爬蟲,反爬蟲

2.4總結

這樣一來,隨便你怎麼造,基本的數據你都能獲取到了,動態內容你也有了。正則式也有了,隨便搞。看到這裏,基本能夠爬取一些網頁了,下面的內容都是在吹牛,不看也罷。

儘管你都能獲取到了,可是效率呢?下面說說怎樣高效抓取。

3.高效抓取數據(多線程/多進程/分佈式爬蟲)

從這兒之後的內容我瞭解的不深,大部份內容我也在學,權當一塊兒聊聊,說錯的地方請及時指出;我盡力說說,重在你們本身的修行。多看書,多學習。

3.1多線程爬蟲

以上篇文章《獲取爬蟲所須要的代理IP》中驗證IP可用性來講,當數據庫和獲取到的數據中有多個IP,假設有1000IP,若是是串行的話,一個個IP去驗證,效率很是低了,更況且遇到不能用的還會超時。這裏使用多線程,明顯提升了效率。

不談多線程的原理/好處,只說說怎麼使用。由於我不會!你來打我呀!

上篇文章中,驗證IP時,將IP所有讀入列表。多個線程從列表中獲取、驗證,而後將可用的IP放入詞典(主要爲了去重)中。這裏只是給你們一個思路,還好比,你設置一個或者多個線程專門抓取網頁上的連接而後放在列表中,而後多個線程從列表中取/訪問連接,這就涉及到生產者消費者問題了。很少說了,你們應該多學學這裏,之後用得着。

線程數量多少依據電腦性能來定。

這裏使用的模塊是threadings,具體怎麼用,網上的例子比我說得好,萬一我跟他想到一起去了,說的同樣好了,那不就來指控我抄襲?參考廖雪峯老師的教程:多線程

代碼:Github   多線程的使用在GetIP.py文件中。

邏輯圖:

爬蟲,python,python爬蟲,多線程爬蟲,多進程爬蟲,分佈式爬蟲,增量式爬蟲,反爬蟲

這雖然不是串行,效率提升了好多,但這還不夠,我要作你近旁的一株木棉……跑題了,這還不夠,併發效率雖然提升了,可是不能有效的利用CPU的多核,常常是1核有難,7核圍觀。蛋疼的GIL啊。(你們有興趣能夠百度「python 多線程能利用多核嗎」)

接下來你須要的是多進程爬蟲。多個CPU一塊兒建設社會主義,大步邁入小康社會!

3.2多進程爬蟲

若是單單是多進程爬蟲,執行效率會提升,再加上協程的話,效率會有明顯提升。邏輯結構同多線程相似,只不過進程之間通訊要使用Queue或者Pipes。

多進程的使用參考廖雪峯老師的教程

大致結構以下圖

爬蟲,python,python爬蟲,多線程爬蟲,多進程爬蟲,分佈式爬蟲,增量式爬蟲,反爬蟲

我把那個獲取代理IP改寫成多進程版本再發出來。

3.3分佈式爬蟲

當網絡帶寬、端口資源、IP資源、存儲資源知足不了爬蟲時,應當適用分佈式爬蟲,最基本的分佈式爬蟲結構以下圖:

爬蟲,python,python爬蟲,多線程爬蟲,多進程爬蟲,分佈式爬蟲,增量式爬蟲,反爬蟲

每個從機上均可以再使用多進程。

我還沒寫過度布式。推薦一個Github項目,簡單的分佈式爬蟲,爬取知乎用戶:ZhiHu Spider based on  Python

3.4總結

提高效率的方法:串行->併發->並行->分佈式。

提高效率了也得注意公德,別給人家服務形成太大壓力,適當的sleep。

4.持續抓取數據(增量式爬蟲)

是 指 對 已 下 載 網 頁 採 取 增 量式更新和只爬行新產生的或者已經發生變化網頁的爬蟲,它可以在必定程度上保證所爬行的頁面是儘量新的頁面。 和週期性爬行和刷新頁面的網絡爬蟲相比,增量式爬蟲只會在須要的時候爬行新產生或發生更新的頁面 ,並不從新下載沒有發生變化的頁面,可有效減小數據下載量,及時更新已爬行的網頁,減少時間和空間上的耗費,可是增長了爬行算法的複雜度和實現難度。——百度百科

舉例,拿最熱的《戰狼2》來講,我要實時獲取最新的影評,進行一系列操做,可是不抓已經保存的評論,只檢測最新的評論而後獲取/處理。知乎上的大神們提到增量式爬蟲重點在怎麼判斷是否抓取過,從而避免重複抓取;再一個就是數據去重。

推薦Github項目:byrSpider

5.爬蟲和反爬蟲和反反爬蟲

爬蟲(Spider),反爬蟲(Anti-Spider),反反爬蟲(Anti-Anti-Spider),是一場精彩絕倫的戰爭,你方唱罷我登場。

5.1動態加載

關於動態加載,一種是前面在提到的提取動態內容,方法差很少。另外可使用selenium/phantomjs提取啊。

由於爬蟲不會執行js代碼進行渲染,有的可能會使用js代碼與服務器通訊,回傳必定的數據,如果爬蟲,這段js代碼便不會執行,能夠封IP了;或者給你假數據,投毒。

還遇到過,抓取代理IP時,某個網站須要調用API來checkuser,只須要調用,哪怕check失敗了;若是不調用的話,就得不到數據。這就跟上面差很少。

這時候用必要使用selenium/phantomjs了,可是會大大下降效率。

還想到的其餘反爬蟲策略也有改動頁面結構。

5.2驗證碼

當網站判斷你是個爬蟲時,常常會跳出幾個驗證碼來打斷你……的腿。處理驗證碼,經常使用的方法有:

1.頻率不高,數據量不大時,能夠手動輸入

2.頻率高,數據量大,考慮接入打碼平臺。大家知道嗎,這叫服務,得花錢!

3.當以上行不通時,本身寫程序識別驗證碼啊。我會說我本科畢設作的就是基於深度神經網絡的驗證碼識別嗎?會!因爲作的不成熟,就不拿出來現眼了。驗證碼識別在知乎和GitHub上都有相關的項目,能夠參考作一下。

4.還有哪些非傳統的驗證碼,例如12306的選擇圖片、滑塊驗證、記錄鼠標軌跡和點擊等等。12306那個能夠調用谷歌或者百度的識圖API,滑塊和鼠標軌跡之類的得藉助phantomjs。等我學會了我再講出來。這裏會耗費精力很大。多多sleep會在很大程度上避免驗證碼。

5.3登陸

還在學習這個,懂得很少,不吹牛皮,推薦Github項目:模擬登陸一些知名的網站,爲了方便爬取須要登陸的網站

爬蟲,python,python爬蟲,多線程爬蟲,多進程爬蟲,分佈式爬蟲,增量式爬蟲,反爬蟲

 

5.4cookie

大多數不是真心想要反爬蟲的網站,或者保護重要數據,不會查你的cookie。推薦幾篇關於cookie的文章,別的之後想起來再補充。

Find Hao——python爬蟲學習(四)獲取cookie

州的先生——Python爬蟲實戰入門四:使用Cookie模擬登陸——獲取電子書下載連接

Jerry——Python爬蟲—破解JS加密的Cookie

5.5總結

其實繞過這些反爬蟲手段纔是王道,正面剛得費多少精力。間隔時間大一點兒,併發量小一點兒,不給人家服務器形成壓力,人家纔不會盯上你。出來混都不容易,誰還不是個寶寶。

6.推薦

1.有能力的去閱讀Scrapy源碼

2.推薦書目:《HTTP權威指南》《用python寫網絡爬蟲》,前端方面我是小白,就知道本《CSS權威指南》求你們推薦基礎的前端書籍。

3.python相關的:路人甲大神的python總結,還有知乎上好多python大牛,多多關注他們

4.我這兒還有一些python的電子書,包括網上的和我本身買的,都貢獻出來爬蟲,python,python爬蟲,多線程爬蟲,多進程爬蟲,分佈式爬蟲,增量式爬蟲,反爬蟲

連接:http://pan.baidu.com/s/1skEQeTZ 密碼:gi91

5.正則表達式相關的,我卻是常常看見這個大哥(國服第一奇葩輔助)回答

This article was written by ZKeeer

文章導航

2 THOUGHTS ON 「簡單爬蟲的通用步驟」

  1. 小鹹魚 說道:

    博主,你的VPS配置是多少的?多少的配置能夠知足平常爬蟲須要?

    1. ZKeeer 說道:

      個人博客vps是vultr家的,1核512M,挺便宜的,推薦一下https://www.vultr.com/?ref=7170172
      若是要單純用vps部署爬蟲,要看爬蟲的設計來決定vps配置了。

 

簡單爬蟲的通用步驟

 

本文首發:ZKeeer’s Blog——簡單爬蟲的通用步驟
代碼基於 python3.5
多圖預警,長文預警

知識點不少,適合小白,大神繞路

 

爬蟲,python,python爬蟲,多線程爬蟲,多進程爬蟲,分佈式爬蟲,增量式爬蟲,反爬蟲

1.獲取數據

爬蟲,就是要想方設法地裝成瀏覽器從網站騙數據。——我說的

1.1從requests.get()提及

最開始一個簡單的爬蟲就是調用python的requests模塊,使用get函數。(爲了避免禍害別人網站,我以本身的網站爲例)

import requests
url_response = requests.get("http://zkeeer.space")
print(url_response.status_code, url_response.text)

這裏get函數從給出的URL獲取數據,打印出狀態碼和獲取的內容看看。

200 <!DOCTYPE html>
<html lang="zh-CN">
 <head>......

狀態碼200,說明平穩落地。後面是獲取到的網頁。

這裏要說明一點,url_response.text 和 url_response.content的區別:

.text返回的是Unicode類型,.content返回的是bytes型也就是傳說的二進制的數據。當須要的數據是文本時,最好用.text,當你須要下載圖片時,要用.content

上面是.text返回的值,下面打印出來.content的值讓你們看看。

200 b'<!DOCTYPE html>\r\n<html lang="zh-CN">\r\n <head>

看到前面的小b以及後面赤裸裸的\r\n了麼?

個人博客挺簡單沒有那麼大訪問量,也不須要限制訪問量,也不須要嚴查你的IP,UserAgent,Cookie等。當你須要大量,高頻次訪問,並且訪問的仍是淘寶這樣的商業網站,這時候你就須要假裝了,不能只是赤裸裸的用個get加個url,就向網站大喊:「我!瀏覽器!給數據!」 也就個人博客這麼好心給你,淘寶早就會「淘寶不想理你,並向你扔了個大創可貼」。

1.2學會使用火狐瀏覽器開發者工具

如何假裝一個瀏覽器?

學習固然都是從模仿開始——也是我說的!

這裏使用的是火狐瀏覽器開發者工具,別聽這麼高大上,其實就是打開火狐瀏覽器按F12!

第一步輸入網址進入個人博客,http://zkeeer.space 而後按F12,找到網絡這一欄。它會提示你從新載入,那就按一下F5,刷新一下。

爬蟲,python,python爬蟲,多線程爬蟲,多進程爬蟲,分佈式爬蟲,增量式爬蟲,反爬蟲

注意如下幾欄。而後找到並點開咱們須要的,也就是第一個爬蟲,python,python爬蟲,多線程爬蟲,多進程爬蟲,分佈式爬蟲,增量式爬蟲,反爬蟲

右側會出來對應的詳細信息。包括:消息頭,Cookie,參數,響應,耗時,堆棧跟蹤。

首先requests.get(url,  params=None,  **kwargs),下面的順序按照參數順序,一一來。

1.3requests.get()參數一:url

消息頭這一欄給出的請求方法是GET,即請求時使用requests.get(),若是這裏是POST,對應使用requests.post()。get函數的url,即請求頭的Host,這裏是「zkeeer.space」

爬蟲,python,python爬蟲,多線程爬蟲,多進程爬蟲,分佈式爬蟲,增量式爬蟲,反爬蟲

 

1.4requests.get()參數二:params

get(url,  params=None,  **kwargs)中params,是構成網址中一些參數,網址連接「?」後面的那些參數。舉個栗子:個人一篇文章連接是http://zkeeer.space/?p=383 那麼後面p=383就是get 的參數(固然你也能夠直接訪問http://zkeeer.space/?p=383,而不須要參數)。

爬蟲,python,python爬蟲,多線程爬蟲,多進程爬蟲,分佈式爬蟲,增量式爬蟲,反爬蟲

須要把這裏列舉的參數都寫到params裏面,哪怕是該參數沒有值。

那麼一開頭咱們那幾行代碼就應該這麼寫了。

import requests

tar_url = "http://zkeeer.space"  # 目標網頁
param = {"p": 383}  # 請求頭的參數
url_response = requests.get(url=tar_url, params=param)
print(url_response.status_code, url_response.text)

這樣獲取到的頁面就是「zkeeer.space/?p=383」對應的文章了。

爬蟲,python,python爬蟲,多線程爬蟲,多進程爬蟲,分佈式爬蟲,增量式爬蟲,反爬蟲

 

1.5requests.get()參數三:headers

可能會有疑問,get(url,  params=None,  **kwargs)並無headers這個參數啊。這個包含在**kwargs裏面,一樣還有另外一經常使用的proxies,待會兒會說到。

headers應該寫什麼呢?下圖所示的消息頭中的請求頭便是這裏的headers參數。

爬蟲,python,python爬蟲,多線程爬蟲,多進程爬蟲,分佈式爬蟲,增量式爬蟲,反爬蟲

跟參數同樣,須要把請求頭的全部信息寫入headers(若是網站不查cookie的話,cookie不必寫)。若是對這些參數不瞭解,能夠點擊後面對應的詳細瞭解,介紹的很詳細。

上面的幾行代碼又要進化了。

import requests

tar_url = "http://zkeeer.space"  # 目標網頁
param = {"p": 383}  # 請求頭的參數
header = {  # 請求頭部
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:55.0) Gecko/20100101 Firefox/55.0",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
    "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3",
    "Accept-Encoding": "gzip, deflate",
    "Referer": "http://zkeeer.space/",
    "Connection": "keep-alive",
    "Upgrade-Insecure-Requests": "1"
}
url_response = requests.get(url=tar_url, params=param, headers=header)
print(url_response.status_code, url_response.text)

這樣一來就比較完備了。

可是這樣狀況下,高頻次訪問對服務器形成壓力了,可能會分析哪一個UserAgent訪問次數最多,發現是你在狂刷人家網站,這時候就有可能給你禁了這個UserAgent,這時候你須要更多的UserAgent隨機挑選進行訪問。

我在上篇文章《獲取爬蟲所須要的代理IP》中的代碼中就有收集的UserAgent,見Github 。

爬蟲,python,python爬蟲,多線程爬蟲,多進程爬蟲,分佈式爬蟲,增量式爬蟲,反爬蟲

可使用random.choice()隨便挑嘛。

1.6requests.get()參數四:proxies

上面提到了,這個參數是代理,對,是代理。當你使用隨機UserAgent的人家無法封了。就會查你IP,發現這個IP刷爆了網站,直接就封了。這時候你要使用代理IP。

上面的代碼又進化了呢!

import requests

tar_url = "http://zkeeer.space"  # 目標網頁
param = {"p": 383}  # 請求頭的參數
proxy = {"http": "http://{}:{}".format("221.8.186.249", "80"),
         "https": "https://{}:{}".format("221.8.186.249", "80")}  #代理IP
header = {  # 請求頭部
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:55.0) Gecko/20100101 Firefox/55.0",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
    "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3",
    "Accept-Encoding": "gzip, deflate",
    "Referer": "http://zkeeer.space/",
    "Connection": "keep-alive",
    "Upgrade-Insecure-Requests": "1"
}
url_response = requests.get(url=tar_url, params=param, proxies=proxy, headers=header)
print(url_response.status_code, url_response.text)

問題又來了,長時間使用同一個代理IP,也會被封啊,我要獲取大量代理IP,最好仍是匿名或者高匿。這些代理IP從哪來的?我該怎麼獲取?上篇文章我寫了若是獲取大量代理IP以及使用:獲取爬蟲所須要的代理IP 

若是須要高質量IP能夠從代理網站或者淘寶買,大量,不貴。

1.7總結

至此,基本的獲取網頁已經差很少了,大多數網站你均可以暢行。儘管,也不能暴力訪問一個網站,要有公德心嘛,我寫爬蟲還sleep(0.5)呢。

火狐瀏覽器的開發者工具很好用,但願你們能發揮其做用。

2.提取數據

獲取完網頁接下來應該提取數據了。獲取網頁的數據,我想提取網頁中特定的文字,或者是數據,或者是圖片,這就是網頁主要提取的吧。

2.1提取文字

先說提取文字,強烈推薦正則表達式,太強大了。簡直就是加特林噠噠噠噠冒藍火的那種;正則在手,天下我有;固然個人水平僅限於能用,就不出來獻醜了。你們按照網上的教程來就能夠。固然你也能夠用beautifulsoup。正則表達式和beautifulsoup這兩種效率比較高。

2.2提取圖片

以我博客中《獲取爬蟲所須要的代理IP》文章爲例,提取其中的圖片。提取網頁中的圖片,咱們能夠用提取文字的方式,用正則表達式獲取圖片連接。這時候,又用的get函數。跟獲取網頁同樣,獲取圖片。記得前面說過的text和content的區別。這裏要使用後者。那麼如何保存一張圖片呢?看下面的代碼示例。

打開火狐瀏覽器開發者工具。此次使用的是查看器,而不是網絡。一層層找到上面文章中的圖片所在位置及相關連接。

爬蟲,python,python爬蟲,多線程爬蟲,多進程爬蟲,分佈式爬蟲,增量式爬蟲,反爬蟲

找到了<img>標籤,這時能夠右鍵查看網頁源代碼,查找一下看有多少是跟你目標類似的,看看如何區分

爬蟲,python,python爬蟲,多線程爬蟲,多進程爬蟲,分佈式爬蟲,增量式爬蟲,反爬蟲

我找到了10項,但只有一項是我須要的,因而我把正則式寫成了

<img class=\"[^\"]+\" src=\"([^\"]+)\"

這時候能夠用 站長工具-正則表達式在線測試 測試下本身寫的正則表達式是否正確

爬蟲,python,python爬蟲,多線程爬蟲,多進程爬蟲,分佈式爬蟲,增量式爬蟲,反爬蟲

成功了!代碼以下:

import re

import requests

tar_url = "http://zkeeer.space"  # 目標網頁
param = {"p": 383}  # 請求頭的參數
header = {  # 請求頭部
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:55.0) Gecko/20100101 Firefox/55.0",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
    "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3",
    "Accept-Encoding": "gzip, deflate",
    "Referer": "http://zkeeer.space/",
    "Connection": "keep-alive",
    "Upgrade-Insecure-Requests": "1"
}
url_response = requests.get(url=tar_url, params=param, headers=header)

img_url = re.findall(r"<img class=\"[^\"]+\" src=\"([^\"]+)\"", url_response.text)
print(img_url[0])

輸出結果:

http://zkeeer.space/wp-content/uploads/2017/08/邏輯圖-1024x576.png

這樣有了圖片的連接,咱們就可使用連接獲取並保存圖片了。

必定要注意使用F12,並仔細查看請求頭和參數!

必定要注意使用F12,並仔細查看請求頭和參數!

必定要注意使用F12,並仔細查看請求頭和參數!

import re

import requests

tar_url = "http://zkeeer.space"  # 目標網頁
param = {"p": 383}  # 請求頭的參數
header = {  # 請求頭部
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:55.0) Gecko/20100101 Firefox/55.0",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
    "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3",
    "Accept-Encoding": "gzip, deflate",
    "Referer": "http://zkeeer.space/",
    "Connection": "keep-alive",
    "Upgrade-Insecure-Requests": "1"
}
url_response = requests.get(url=tar_url, params=param, headers=header)


img_header = {  # 請求頭部
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:55.0) Gecko/20100101 Firefox/55.0",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
    "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3",
    "Accept-Encoding": "gzip, deflate",
    "Referer": "http://zkeeer.space/?p=383",
    "Connection": "keep-alive",
    "Upgrade-Insecure-Requests": "1"
}
# 獲取圖片連接
img_url = re.findall(r"<img class=\"[^\"]+\" src=\"([^\"]+)\"", url_response.text)[0]
# 從圖片連接中提取圖片名
img_name = re.findall(r"([^/]+.png)", img_url)[0]
# 請求
url_response = requests.get(url=img_url, headers=img_header)
# 保存圖片
with open(img_name, "wb") as fw:
    fw.write(url_response.content)

運行程序查看獲得的圖片(個人vps配置特別低,速度特慢,輕噴。給Vultr的VPS打個廣告,有優惠!

爬蟲,python,python爬蟲,多線程爬蟲,多進程爬蟲,分佈式爬蟲,增量式爬蟲,反爬蟲

好了,到這兒能夠獲取基本的網頁信息了。並且高頻次訪問基本上不會被封。
你覺得到這就結束了嗎?

2.3提取動態加載的數據

在獲取有些重要數據的時候。這些數據是動態加載的。這也是反爬蟲的一種手段,下面我有說起反爬蟲。

當我只獲取這個網頁的時候,根本不會顯示這些數據。這個時候又要讓你的爬蟲裝一次瀏覽器。固然不能說:我!瀏覽器!給數據! 這個時候你不光要賣萌,還要回答問題。快看快看,我是瀏覽器,我是可愛的瀏覽器,快給我數據啊。

這時候人家就問你,你是從哪兒(Refer)找到個人?你的雞毛信(ID)呢?你從袖筒裏排出幾個參數,瀏覽器一看,哎呀,大兄弟,真的是你,快給你數據。這時候不要吭聲,趁他不注意,拿了數據趕忙跑。

爬蟲,python,python爬蟲,多線程爬蟲,多進程爬蟲,分佈式爬蟲,增量式爬蟲,反爬蟲

獲取方式跟上面獲取網頁同樣。一樣是使用火狐。以淘寶米6商品評論爲例,我隨便找的,別說我軟廣:

爬蟲,python,python爬蟲,多線程爬蟲,多進程爬蟲,分佈式爬蟲,增量式爬蟲,反爬蟲

點擊評論,而後看到網絡這一欄,動態加載的內容就出來了,從域名裏我找到了rate.taobao.com,對應左邊兩個文件,一個是detailCommon.htm 另外一個是freeRateList.htm;我查看了下,分別對應評論中的你們印象和詳細評論。查看哪兒?查看對應的響應內容。

這裏就以「你們印象」爲例:按照1.獲取數據的步驟,獲取到了以下結果:

import re
import requests

tar_url = "https://rate.taobao.com/detailCommon.htm"
# 商品連接
refer = "https://item.taobao.com/item.htm?spm=a230r.1.14.119.76bf523Zih6Ob&id=548765652209&ns=1&abbucket=12"
# 從商品連接中提取商品ID
NumId = re.findall(r"id=(\d+)\&", refer)
# 參數
param = {"auctionNumId": NumId,
         "userNumId": "43440508",
         "callback": "json_tbc_rate_summary"}
# 頭部信息
header = {
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    'Accept-Encoding': 'gzip, deflate, compress',
    'Accept-Language': 'zh-CN,zh;q=0.8,en;q=0.6,ru;q=0.4',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive',
    'Upgrade-Insecure-Requests': "1",
    'Referer': refer,
    'User-Agent': "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:55.0) Gecko/20100101 Firefox/55.0"
}

try:
    url_content = requests.get(url=tar_url, params=param, headers=header)
    print("url_content: ", url_content.text)
except BaseException as e:
    pass

結果:

json_tbc_rate_summary({"watershed":100,"isShowDefaultSort":true,"askAroundDisabled":false,"sellerRefundCount":6,"skuSelected":true,"data":{"newSearch":false,"count":{"total":4689,"tryReport":0,"goodFull":4622,"additional":243,"correspond":0,"normal":30,"hascontent":0,"good":4622,"pic":588,"bad":37,"totalFull":4689},"spuRatting":[],"correspond":"4.8","impress":[{"title":"手機不錯","count":477,"value":1,"attribute":"620-11","scm":""},{"title":"手機是正品","count":243,"value":1,"attribute":"1020-11","scm":""},{"title":"系統很強大","count":214,"value":1,"attribute":"921-11","scm":""},{"title":"態度不錯","count":144,"value":1,"attribute":"10120-11","scm":""},{"title":"款式好看","count":115,"value":1,"attribute":"121-11","scm":""},{"title":"快遞不錯","count":108,"value":1,"attribute":"420-11","scm":""},{"title":"手感很好","count":90,"value":1,"attribute":"721-11","scm":""},{"title":"性價比很高","count":85,"value":1,"attribute":"20520-11","scm":""},{"title":"性能通常","count":39,"value":-1,"attribute":"921-13","scm":""},{"title":"配件通常","count":35,"value":-1,"attribute":"621-13","scm":""}],"attribute":[{"name":"版本類型","options":[{"name":"中國大陸","value":"中國大陸"}]},{"name":"版本類型","options":[{"name":"中國大陸","value":"中國大陸"}]},{"name":"版本類型","options":[{"name":"中國大陸","value":"中國大陸"}]},{"name":"版本類型","options":[{"name":"中國大陸","value":"中國大陸"}]}]},"skuFull":false,"showPicRadio":true,"isRefundUser":true})

最外層是個json_tbc_rate_summary()回調函數,它的參數是個詞典,咱們詞典拿出來,放到python中看起來就比較方便了。

處理結果:

爬蟲,python,python爬蟲,多線程爬蟲,多進程爬蟲,分佈式爬蟲,增量式爬蟲,反爬蟲

爬蟲,python,python爬蟲,多線程爬蟲,多進程爬蟲,分佈式爬蟲,增量式爬蟲,反爬蟲

2.4總結

這樣一來,隨便你怎麼造,基本的數據你都能獲取到了,動態內容你也有了。正則式也有了,隨便搞。看到這裏,基本能夠爬取一些網頁了,下面的內容都是在吹牛,不看也罷。

儘管你都能獲取到了,可是效率呢?下面說說怎樣高效抓取。

3.高效抓取數據(多線程/多進程/分佈式爬蟲)

從這兒之後的內容我瞭解的不深,大部份內容我也在學,權當一塊兒聊聊,說錯的地方請及時指出;我盡力說說,重在你們本身的修行。多看書,多學習。

3.1多線程爬蟲

以上篇文章《獲取爬蟲所須要的代理IP》中驗證IP可用性來講,當數據庫和獲取到的數據中有多個IP,假設有1000IP,若是是串行的話,一個個IP去驗證,效率很是低了,更況且遇到不能用的還會超時。這裏使用多線程,明顯提升了效率。

不談多線程的原理/好處,只說說怎麼使用。由於我不會!你來打我呀!

上篇文章中,驗證IP時,將IP所有讀入列表。多個線程從列表中獲取、驗證,而後將可用的IP放入詞典(主要爲了去重)中。這裏只是給你們一個思路,還好比,你設置一個或者多個線程專門抓取網頁上的連接而後放在列表中,而後多個線程從列表中取/訪問連接,這就涉及到生產者消費者問題了。很少說了,你們應該多學學這裏,之後用得着。

線程數量多少依據電腦性能來定。

這裏使用的模塊是threadings,具體怎麼用,網上的例子比我說得好,萬一我跟他想到一起去了,說的同樣好了,那不就來指控我抄襲?參考廖雪峯老師的教程:多線程

代碼:Github   多線程的使用在GetIP.py文件中。

邏輯圖:

爬蟲,python,python爬蟲,多線程爬蟲,多進程爬蟲,分佈式爬蟲,增量式爬蟲,反爬蟲

這雖然不是串行,效率提升了好多,但這還不夠,我要作你近旁的一株木棉……跑題了,這還不夠,併發效率雖然提升了,可是不能有效的利用CPU的多核,常常是1核有難,7核圍觀。蛋疼的GIL啊。(你們有興趣能夠百度「python 多線程能利用多核嗎」)

接下來你須要的是多進程爬蟲。多個CPU一塊兒建設社會主義,大步邁入小康社會!

3.2多進程爬蟲

若是單單是多進程爬蟲,執行效率會提升,再加上協程的話,效率會有明顯提升。邏輯結構同多線程相似,只不過進程之間通訊要使用Queue或者Pipes。

多進程的使用參考廖雪峯老師的教程

大致結構以下圖

爬蟲,python,python爬蟲,多線程爬蟲,多進程爬蟲,分佈式爬蟲,增量式爬蟲,反爬蟲

我把那個獲取代理IP改寫成多進程版本再發出來。

3.3分佈式爬蟲

當網絡帶寬、端口資源、IP資源、存儲資源知足不了爬蟲時,應當適用分佈式爬蟲,最基本的分佈式爬蟲結構以下圖:

爬蟲,python,python爬蟲,多線程爬蟲,多進程爬蟲,分佈式爬蟲,增量式爬蟲,反爬蟲

每個從機上均可以再使用多進程。

我還沒寫過度布式。推薦一個Github項目,簡單的分佈式爬蟲,爬取知乎用戶:ZhiHu Spider based on  Python

3.4總結

提高效率的方法:串行->併發->並行->分佈式。

提高效率了也得注意公德,別給人家服務形成太大壓力,適當的sleep。

4.持續抓取數據(增量式爬蟲)

是 指 對 已 下 載 網 頁 採 取 增 量式更新和只爬行新產生的或者已經發生變化網頁的爬蟲,它可以在必定程度上保證所爬行的頁面是儘量新的頁面。 和週期性爬行和刷新頁面的網絡爬蟲相比,增量式爬蟲只會在須要的時候爬行新產生或發生更新的頁面 ,並不從新下載沒有發生變化的頁面,可有效減小數據下載量,及時更新已爬行的網頁,減少時間和空間上的耗費,可是增長了爬行算法的複雜度和實現難度。——百度百科

舉例,拿最熱的《戰狼2》來講,我要實時獲取最新的影評,進行一系列操做,可是不抓已經保存的評論,只檢測最新的評論而後獲取/處理。知乎上的大神們提到增量式爬蟲重點在怎麼判斷是否抓取過,從而避免重複抓取;再一個就是數據去重。

推薦Github項目:byrSpider

5.爬蟲和反爬蟲和反反爬蟲

爬蟲(Spider),反爬蟲(Anti-Spider),反反爬蟲(Anti-Anti-Spider),是一場精彩絕倫的戰爭,你方唱罷我登場。

5.1動態加載

關於動態加載,一種是前面在提到的提取動態內容,方法差很少。另外可使用selenium/phantomjs提取啊。

由於爬蟲不會執行js代碼進行渲染,有的可能會使用js代碼與服務器通訊,回傳必定的數據,如果爬蟲,這段js代碼便不會執行,能夠封IP了;或者給你假數據,投毒。

還遇到過,抓取代理IP時,某個網站須要調用API來checkuser,只須要調用,哪怕check失敗了;若是不調用的話,就得不到數據。這就跟上面差很少。

這時候用必要使用selenium/phantomjs了,可是會大大下降效率。

還想到的其餘反爬蟲策略也有改動頁面結構。

5.2驗證碼

當網站判斷你是個爬蟲時,常常會跳出幾個驗證碼來打斷你……的腿。處理驗證碼,經常使用的方法有:

1.頻率不高,數據量不大時,能夠手動輸入

2.頻率高,數據量大,考慮接入打碼平臺。大家知道嗎,這叫服務,得花錢!

3.當以上行不通時,本身寫程序識別驗證碼啊。我會說我本科畢設作的就是基於深度神經網絡的驗證碼識別嗎?會!因爲作的不成熟,就不拿出來現眼了。驗證碼識別在知乎和GitHub上都有相關的項目,能夠參考作一下。

4.還有哪些非傳統的驗證碼,例如12306的選擇圖片、滑塊驗證、記錄鼠標軌跡和點擊等等。12306那個能夠調用谷歌或者百度的識圖API,滑塊和鼠標軌跡之類的得藉助phantomjs。等我學會了我再講出來。這裏會耗費精力很大。多多sleep會在很大程度上避免驗證碼。

5.3登陸

還在學習這個,懂得很少,不吹牛皮,推薦Github項目:模擬登陸一些知名的網站,爲了方便爬取須要登陸的網站

爬蟲,python,python爬蟲,多線程爬蟲,多進程爬蟲,分佈式爬蟲,增量式爬蟲,反爬蟲

 

5.4cookie

大多數不是真心想要反爬蟲的網站,或者保護重要數據,不會查你的cookie。推薦幾篇關於cookie的文章,別的之後想起來再補充。

Find Hao——python爬蟲學習(四)獲取cookie

州的先生——Python爬蟲實戰入門四:使用Cookie模擬登陸——獲取電子書下載連接

Jerry——Python爬蟲—破解JS加密的Cookie

5.5總結

其實繞過這些反爬蟲手段纔是王道,正面剛得費多少精力。間隔時間大一點兒,併發量小一點兒,不給人家服務器形成壓力,人家纔不會盯上你。出來混都不容易,誰還不是個寶寶。

6.推薦

1.有能力的去閱讀Scrapy源碼

2.推薦書目:《HTTP權威指南》《用python寫網絡爬蟲》,前端方面我是小白,就知道本《CSS權威指南》求你們推薦基礎的前端書籍。

3.python相關的:路人甲大神的python總結,還有知乎上好多python大牛,多多關注他們

4.我這兒還有一些python的電子書,包括網上的和我本身買的,都貢獻出來爬蟲,python,python爬蟲,多線程爬蟲,多進程爬蟲,分佈式爬蟲,增量式爬蟲,反爬蟲

連接:http://pan.baidu.com/s/1skEQeTZ 密碼:gi91

5.正則表達式相關的,我卻是常常看見這個大哥(國服第一奇葩輔助)回答

This article was written by ZKeeer

文章導航

2 THOUGHTS ON 「簡單爬蟲的通用步驟」

  1. 小鹹魚 說道:

    博主,你的VPS配置是多少的?多少的配置能夠知足平常爬蟲須要?

    1. ZKeeer 說道:

      個人博客vps是vultr家的,1核512M,挺便宜的,推薦一下https://www.vultr.com/?ref=7170172
      若是要單純用vps部署爬蟲,要看爬蟲的設計來決定vps配置了。

相關文章
相關標籤/搜索