資訊內(nèi)容
深入理解Python分布式爬蟲(chóng)原理
4NQ少兒編程網(wǎng)-Scratch_Python_教程_免費(fèi)兒童編程學(xué)習(xí)平臺(tái)
免費(fèi)推薦:python視頻教程4NQ少兒編程網(wǎng)-Scratch_Python_教程_免費(fèi)兒童編程學(xué)習(xí)平臺(tái)
首先,我們先來(lái)看看,如果是人正常的行為,是如何獲取網(wǎng)頁(yè)內(nèi)容的。
4NQ少兒編程網(wǎng)-Scratch_Python_教程_免費(fèi)兒童編程學(xué)習(xí)平臺(tái)
(1)打開(kāi)瀏覽器,輸入U(xiǎn)RL,打開(kāi)源網(wǎng)頁(yè)
4NQ少兒編程網(wǎng)-Scratch_Python_教程_免費(fèi)兒童編程學(xué)習(xí)平臺(tái)
(2)選取我們想要的內(nèi)容,包括標(biāo)題,作者,摘要,正文等信息
4NQ少兒編程網(wǎng)-Scratch_Python_教程_免費(fèi)兒童編程學(xué)習(xí)平臺(tái)
(3)存儲(chǔ)到硬盤(pán)中4NQ少兒編程網(wǎng)-Scratch_Python_教程_免費(fèi)兒童編程學(xué)習(xí)平臺(tái)
上面的三個(gè)過(guò)程,映射到技術(shù)層面上,其實(shí)就是:網(wǎng)絡(luò)請(qǐng)求,抓取結(jié)構(gòu)化數(shù)據(jù),數(shù)據(jù)存儲(chǔ)。
4NQ少兒編程網(wǎng)-Scratch_Python_教程_免費(fèi)兒童編程學(xué)習(xí)平臺(tái)
我們使用Python寫(xiě)一個(gè)簡(jiǎn)單的程序,實(shí)現(xiàn)上面的簡(jiǎn)單抓取功能。4NQ少兒編程網(wǎng)-Scratch_Python_教程_免費(fèi)兒童編程學(xué)習(xí)平臺(tái)
#!/usr/bin/python #-*- coding: utf-8 -*- ''''' Created on 2014-03-16 @author: Kris ''' import urllib2, re, cookielib def httpCrawler(url): ''''' @summary: 網(wǎng)頁(yè)抓取 ''' content = httpRequest(url) title = parseHtml(content) saveData(title) def httpRequest(url): ''''' @summary: 網(wǎng)絡(luò)請(qǐng)求 ''' try: ret = None SockFile = None request = urllib2.Request(url) request.add_header('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322)') request.add_header('Pragma', 'no-cache') opener = urllib2.build_opener() SockFile = opener.open(request) ret = SockFile.read() finally: if SockFile: SockFile.close() return ret def parseHtml(html): ''''' @summary: 抓取結(jié)構(gòu)化數(shù)據(jù) ''' content = None pattern = '<title>([^<]*?)</title>' temp = re.findall(pattern, html) if temp: content = temp[0] return content def saveData(data): ''''' @summary: 數(shù)據(jù)存儲(chǔ) ''' f = open('test', 'wb') f.write(data) f.close() if __name__ == '__main__': url = 'http://www.baidu.com' httpCrawler(url)看著很簡(jiǎn)單,是的,它就是一個(gè)爬蟲(chóng)入門(mén)的基礎(chǔ)程序。當(dāng)然,在實(shí)現(xiàn)一個(gè)采集過(guò)程,無(wú)非就是上面的幾個(gè)基礎(chǔ)步驟。但是實(shí)現(xiàn)一個(gè)強(qiáng)大的采集過(guò)程,你會(huì)遇到下面的問(wèn)題:
4NQ少兒編程網(wǎng)-Scratch_Python_教程_免費(fèi)兒童編程學(xué)習(xí)平臺(tái)
(1)需要帶著cookie信息訪問(wèn),比如大多數(shù)的社交化軟件,基本上都是需要用戶登錄之后,才能看到有價(jià)值的東西,其實(shí)很簡(jiǎn)單,我們可以使用Python提供的cookielib模塊,實(shí)現(xiàn)每次訪問(wèn)都帶著源網(wǎng)站給的cookie信息去訪問(wèn),這樣只要我們成功模擬了登錄,爬蟲(chóng)處于登錄狀態(tài),那么我們就可以采集到登錄用戶看到的一切信息了。下面是使用cookie對(duì)httpRequest()方法的修改:4NQ少兒編程網(wǎng)-Scratch_Python_教程_免費(fèi)兒童編程學(xué)習(xí)平臺(tái)
ckjar = cookielib.MozillaCookieJar() cookies = urllib2.HTTPCookieProcessor(ckjar) #定義cookies對(duì)象 def httpRequest(url): ''''' @summary: 網(wǎng)絡(luò)請(qǐng)求 ''' try: ret = None SockFile = None request = urllib2.Request(url) request.add_header('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322)') request.add_header('Pragma', 'no-cache') opener = urllib2.build_opener(cookies) #傳遞cookies對(duì)象 SockFile = opener.open(request) ret = SockFile.read() finally: if SockFile: SockFile.close() return ret(2)編碼問(wèn)題。網(wǎng)站目前**多的兩種編碼:utf-8,或者gbk,當(dāng)我們采集回來(lái)源網(wǎng)站編碼和我們數(shù)據(jù)庫(kù)存儲(chǔ)的編碼不一致時(shí),比如,163.com的編碼使用的是gbk,而我們需要存儲(chǔ)的是utf-8編碼的數(shù)據(jù),那么我們可以使用Python中提供的encode()和decode()方法進(jìn)行轉(zhuǎn)換,比如:4NQ少兒編程網(wǎng)-Scratch_Python_教程_免費(fèi)兒童編程學(xué)習(xí)平臺(tái)
content = content.decode('gbk', 'ignore') #將gbk編碼轉(zhuǎn)為unicode編碼 content = content.encode('utf-8', 'ignore') #將unicode編碼轉(zhuǎn)為utf-8編碼中間出現(xiàn)了unicode編碼,我們需要轉(zhuǎn)為中間編碼unicode,才能向gbk或者utf-8轉(zhuǎn)換。4NQ少兒編程網(wǎng)-Scratch_Python_教程_免費(fèi)兒童編程學(xué)習(xí)平臺(tái)
(3)網(wǎng)頁(yè)中標(biāo)簽不完整,比如有些源代碼中出現(xiàn)了起始標(biāo)簽,但沒(méi)有結(jié)束標(biāo)簽,HTML標(biāo)簽不完整,就會(huì)影響我們抓取結(jié)構(gòu)化數(shù)據(jù),我們可以通過(guò)Python的BeautifulSoup模塊,先對(duì)源代碼進(jìn)行清洗,再分析獲取內(nèi)容。4NQ少兒編程網(wǎng)-Scratch_Python_教程_免費(fèi)兒童編程學(xué)習(xí)平臺(tái)
(4)某些網(wǎng)站使用JS來(lái)生存網(wǎng)頁(yè)內(nèi)容。當(dāng)我們直接查看源代碼的時(shí)候,發(fā)現(xiàn)是一堆讓人頭疼的JS代碼。可以使用mozilla、webkit等可以解析瀏覽器的工具包解析js、ajax,雖然速度會(huì)稍微慢點(diǎn)。4NQ少兒編程網(wǎng)-Scratch_Python_教程_免費(fèi)兒童編程學(xué)習(xí)平臺(tái)
(5)圖片是flash形式存在的。當(dāng)圖片中的內(nèi)容是文字或者數(shù)字組成的字符,那這個(gè)就比較好辦,我們只要利用ocr技術(shù),就能實(shí)現(xiàn)自動(dòng)識(shí)別了,但是如果是flash鏈接,我們將整個(gè)URL存儲(chǔ)起來(lái)了。 4NQ少兒編程網(wǎng)-Scratch_Python_教程_免費(fèi)兒童編程學(xué)習(xí)平臺(tái)
(6)一個(gè)網(wǎng)頁(yè)出現(xiàn)多個(gè)網(wǎng)頁(yè)結(jié)構(gòu)的情況,這樣我們?nèi)绻皇且惶鬃ト∫?guī)則,那肯定不行,所以需要配置多套模擬進(jìn)行協(xié)助配合抓取。4NQ少兒編程網(wǎng)-Scratch_Python_教程_免費(fèi)兒童編程學(xué)習(xí)平臺(tái)
(7)應(yīng)對(duì)源網(wǎng)站的監(jiān)控。抓取別人的東西,畢竟是不太好的事情,所以一般網(wǎng)站都會(huì)有針對(duì)爬蟲(chóng)禁止訪問(wèn)的限制。
一個(gè)好的采集系統(tǒng),應(yīng)該是,不管我們的目標(biāo)數(shù)據(jù)在何處,只要是用戶能夠看到的,我們都能采集回來(lái)。所見(jiàn)即所得的無(wú)阻攔式采集,無(wú)論是否需要登錄的數(shù)據(jù)都能夠順利采集。大部分有價(jià)值的信息,一般都需要登錄才能看到,比如社交網(wǎng)站,為了應(yīng)對(duì)登錄的網(wǎng)站要有模擬用戶登錄的爬蟲(chóng)系統(tǒng),才能正常獲取數(shù)據(jù)。不過(guò)社會(huì)化網(wǎng)站都希望自己形成一個(gè)閉環(huán),不愿意把數(shù)據(jù)放到站外,這種系統(tǒng)也不會(huì)像新聞等內(nèi)容那么開(kāi)放的讓人獲取。這些社會(huì)化網(wǎng)站大部分會(huì)采取一些限制防止機(jī)器人爬蟲(chóng)系統(tǒng)爬取數(shù)據(jù),一般一個(gè)賬號(hào)爬取不了多久就會(huì)被檢測(cè)出來(lái)被禁止訪問(wèn)了。那是不是我們就不能爬取這些網(wǎng)站的數(shù)據(jù)呢?肯定不是這樣的,只要社會(huì)化網(wǎng)站不關(guān)閉網(wǎng)頁(yè)訪問(wèn),正常人能夠訪問(wèn)的數(shù)據(jù),我們也能訪問(wèn)。說(shuō)到底就是模擬人的正常行為操作,專(zhuān)業(yè)一點(diǎn)叫“反監(jiān)控”。4NQ少兒編程網(wǎng)-Scratch_Python_教程_免費(fèi)兒童編程學(xué)習(xí)平臺(tái)
源網(wǎng)站一般會(huì)有下面幾種限制:
4NQ少兒編程網(wǎng)-Scratch_Python_教程_免費(fèi)兒童編程學(xué)習(xí)平臺(tái)
1、一定時(shí)間內(nèi)單個(gè)IP訪問(wèn)次數(shù),一個(gè)正常用戶訪問(wèn)網(wǎng)站,除非是隨意的點(diǎn)著玩,否則不會(huì)在一段持續(xù)時(shí)間內(nèi)過(guò)快訪問(wèn)一個(gè)網(wǎng)站,持續(xù)時(shí)間也不會(huì)太長(zhǎng)。這個(gè)問(wèn)題好辦,我們可以采用大量不規(guī)則代理IP形成一個(gè)代理池,隨機(jī)從代理池中選擇代理,模擬訪問(wèn)。代理IP有兩種,透明代理和匿名代理。4NQ少兒編程網(wǎng)-Scratch_Python_教程_免費(fèi)兒童編程學(xué)習(xí)平臺(tái)
2、一定時(shí)間內(nèi)單個(gè)賬號(hào)訪問(wèn)次數(shù),如果一個(gè)人一天24小時(shí)都在訪問(wèn)一個(gè)數(shù)據(jù)接口,而且速度非常快,那就有可能是機(jī)器人了。我們可以采用大量行為正常的賬號(hào),行為正常就是普通人怎么在社交網(wǎng)站上操作,并且單位時(shí)間內(nèi),訪問(wèn)URL數(shù)目盡量減少,可以在每次訪問(wèn)中間間隔一段時(shí)間,這個(gè)時(shí)間間隔可以是一個(gè)隨機(jī)值,即每次訪問(wèn)完一個(gè)URL,隨機(jī)隨眠一段時(shí)間,再接著訪問(wèn)下一個(gè)URL。
4NQ少兒編程網(wǎng)-Scratch_Python_教程_免費(fèi)兒童編程學(xué)習(xí)平臺(tái)
如果能把賬號(hào)和IP的訪問(wèn)策略控制好了,基本就沒(méi)什么問(wèn)題了。當(dāng)然對(duì)方網(wǎng)站也會(huì)有運(yùn)維會(huì)調(diào)整策略,敵我雙方的一場(chǎng)較量,爬蟲(chóng)必須要能感知到對(duì)方的反監(jiān)控將會(huì)對(duì)我們有影響,通知管理員及時(shí)處理。其實(shí)**理想的是能夠通過(guò)機(jī)器學(xué)習(xí),智能的實(shí)現(xiàn)反監(jiān)控對(duì)抗,實(shí)現(xiàn)不間斷地抓取。
4NQ少兒編程網(wǎng)-Scratch_Python_教程_免費(fèi)兒童編程學(xué)習(xí)平臺(tái)
下面是本人近期正在設(shè)計(jì)的一個(gè)分布式爬蟲(chóng)架構(gòu)圖,如圖1所示:4NQ少兒編程網(wǎng)-Scratch_Python_教程_免費(fèi)兒童編程學(xué)習(xí)平臺(tái)
4NQ少兒編程網(wǎng)-Scratch_Python_教程_免費(fèi)兒童編程學(xué)習(xí)平臺(tái)
純屬拙作,初步思路正在實(shí)現(xiàn),正在搭建服務(wù)器和客戶端之間的通信,主要使用了Python的Socket模塊實(shí)現(xiàn)服務(wù)器端和客戶端的通信。如果有興趣,可以單獨(dú)和我聯(lián)系,共同探討完成更優(yōu)的方案。
以上就是深入理解Python分布式爬蟲(chóng)原理的詳細(xì)內(nèi)容,更多請(qǐng)關(guān)注少兒編程網(wǎng)其它相關(guān)文章!4NQ少兒編程網(wǎng)-Scratch_Python_教程_免費(fèi)兒童編程學(xué)習(xí)平臺(tái)

- 上一篇
python為啥運(yùn)行效率不高
簡(jiǎn)介原因:1、python是動(dòng)態(tài)語(yǔ)言;2、python是解釋執(zhí)行,但是不支持JIT;3、python中一切都是對(duì)象,每個(gè)對(duì)象都需要維護(hù)引用計(jì)數(shù),增加了額外的工作。4、pythonGIL;5、垃圾回收。當(dāng)我們提到一門(mén)編程語(yǔ)言的效率時(shí):通常有兩層意思,第一是開(kāi)發(fā)效率,這是對(duì)程序員而言,完成編碼所需要的時(shí)間;
- 下一篇
PostgreSQL9.5服務(wù)不能啟動(dòng)怎么辦
簡(jiǎn)介PostgreSQL9.5服務(wù)不能啟動(dòng)怎么辦檢查及解決方法如下:1、看看服務(wù)里的Postgres服務(wù)的用戶名、密碼,必須用postres用戶啟動(dòng)的。2、若是重啟后啟動(dòng)不了,看看是不是服務(wù)設(shè)置成了手動(dòng),或者是安裝了影子系統(tǒng)3、會(huì)不會(huì)是安裝的時(shí)候,上一次的安裝沒(méi)有卸載干凈?4、手動(dòng)啟動(dòng)服務(wù)試試看,看看系