python高階爬蟲實(shí)戰(zhàn)分析
關(guān)于這篇文章有幾句話想說(shuō),首先給大家道歉,之前學(xué)的時(shí)候真的覺(jué)得下述的是比較厲害的東西,但是后來(lái)發(fā)現(xiàn)真的是基礎(chǔ)中的基礎(chǔ),內(nèi)容還不是很完全。再看一遍自己寫的這篇文章,突然有種想自殺的沖動(dòng)。emmm所以樓主決定本文全文抹掉重寫一遍,并且為之前點(diǎn)進(jìn)來(lái)看的七十多訪問(wèn)量的人,致以最誠(chéng)摯的歉意。好想死。。
在學(xué)完了爬蟲全部?jī)?nèi)容后,樓主覺(jué)得勉強(qiáng)有資格為接觸爬蟲的新人指指路了。那么廢話不多說(shuō),以下正文:
一、獲取內(nèi)容
說(shuō)爬蟲一定要先說(shuō)爬取內(nèi)容的方法,python有這么幾個(gè)支持爬蟲的庫(kù),一個(gè)是urllib和它的后續(xù)版本庫(kù),這個(gè)庫(kù)做爬取的時(shí)候生成的中繼對(duì)象是比較多的,樓主也記不大住都有什么,而且這個(gè)庫(kù)的使用在樓主看來(lái)有些過(guò)時(shí)了。更加建議做爬取的時(shí)候使用requests庫(kù)(ps:不是request)
使用urllib:
html = urllib.request.urlopen(url).read()
使用requests:
r = requests.get(url)
對(duì)于獲取到的內(nèi)容,有以下方法進(jìn)行處理:
1、使用正則表達(dá)式匹配。
2、使用BeautifulSoup對(duì)爬取內(nèi)容標(biāo)簽對(duì)象化。
3、通過(guò)構(gòu)造節(jié)點(diǎn)樹使用Xpath獲取元素。
第一種方法勝在直接,效率高而且不需要安裝三方庫(kù)。第二種方法勝在簡(jiǎn)單,標(biāo)簽對(duì)象化后不需要寫復(fù)雜的正則表達(dá)式,而且提取標(biāo)簽更加方便。第三種方法勝在靈活,獲取內(nèi)容更加靈活,就是語(yǔ)法有點(diǎn)多,不熟的話可以對(duì)著Xpath語(yǔ)法文檔寫。
使用正則表達(dá)式匹配:
pattern_content = '<div class="rich_media_content " id="js_content">(.*?)</div>' content1 = re.findall(pattern_content, html, re.S)
使用BeautifulSoup對(duì)爬取內(nèi)容標(biāo)簽對(duì)象化:
soup = bs4.BeautifulSoup(html, 'lxml')
imgs = soup.find_all('img')
關(guān)于BeautifulSoup的安裝請(qǐng)自行百度,沒(méi)記錯(cuò)的話直接pip是可行的。
通過(guò)構(gòu)造節(jié)點(diǎn)樹使用Xpath獲取元素:
selector=etree.HTML(html)
content=selector.xpath('//div[@id="content"]/ul[@id="ul"]/li/text()')
至此,爬取的基本內(nèi)容就敘述完畢了,這里給出的是最簡(jiǎn)單的范例,如果想深入了解某種方法,建議去查詢更詳細(xì)的技術(shù)文檔。
下面內(nèi)容就是之前的了,略作刪改。
二、偽造表單請(qǐng)求頭
很多網(wǎng)站上的數(shù)據(jù)爬取比較簡(jiǎn)單,只需要直接request那個(gè)網(wǎng)址就可以,很多小型網(wǎng)站都是這樣。面對(duì)這樣的網(wǎng)站數(shù)據(jù),只需要花個(gè)幾分鐘隨便寫幾行代碼,就能爬到我們想要的數(shù)據(jù)。
但是想要爬取稍微大型一些的網(wǎng)站數(shù)據(jù),就不會(huì)這么容易了。這些網(wǎng)站的服務(wù)器,會(huì)分析收到的每一條request,來(lái)判斷該請(qǐng)求是否為用戶操作。這種技術(shù),我們把它稱為反爬技術(shù)。常見的反爬技術(shù),樓主知道的有上面所述的分析請(qǐng)求,還有驗(yàn)證碼技術(shù)。對(duì)于這兩種情況,我們?cè)跇?gòu)造爬蟲程序的時(shí)候就需要稍微費(fèi)點(diǎn)力氣了。
先來(lái)介紹第一種的應(yīng)對(duì)方法。首先我們要知道一條request的組成部分,不同網(wǎng)站的request格式可能會(huì)有點(diǎn)不同。對(duì)于這一點(diǎn),我們可以通過(guò)瀏覽器的開發(fā)者工具,抓到一個(gè)網(wǎng)站的請(qǐng)求數(shù)據(jù)格式。如下圖:
11111
此為使用谷歌瀏覽器抓取的請(qǐng)求信息。
我們可以看到request headers的格式,所以在訪問(wèn)這樣的網(wǎng)站的時(shí)候,我們就不能忘了在postdata中放上一條偽造的headers。
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; rv:32.0) Gecko/20100101 Firefox/32.0',
'Referer': 'Address'}
其中referer鍵對(duì)應(yīng)的值是要訪問(wèn)的網(wǎng)址。
某些網(wǎng)站還會(huì)需要有cookie的用戶驗(yàn)證,我們可以通過(guò)調(diào)用
requests.Session().cookies
來(lái)獲得它。
如果在爬蟲中需要提交某些信息的話,還要構(gòu)造一下postdata的數(shù)據(jù)。比如這樣:
postData = {
'username': ul[i][0],
'password': ul[i][1],
'lt': b.group(1),
'execution': 'e1s1',
'_eventId': 'submit',
'submit': '%B5%C7%C2%BC',
}
三、關(guān)于多網(wǎng)頁(yè)的爬取
如果網(wǎng)頁(yè)地址有規(guī)律,那么構(gòu)造url用個(gè)循環(huán)函數(shù)就好,對(duì)于網(wǎng)頁(yè)地址中包含隨機(jī)碼的時(shí)候,通常就是先爬取根頁(yè)面,獲取到所有想爬取的子頁(yè)面url,把這些url放進(jìn)一個(gè)url池(項(xiàng)目小是一維的列表,項(xiàng)目大的時(shí)候可能會(huì)是高維的列表)里,循環(huán)爬取。
而比較高效的方式是使用多線程技術(shù),demo有點(diǎn)長(zhǎng)只貼關(guān)鍵部分。
class Geturl(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
res = requests.get(url, headers=header)
html = res.text
# print(html)
pattern_href = '<a target="_blank" href="(.*?)" rel="external nofollow" id'
href = re.findall(pattern_href, html, re.S)
for href in href:
href = href.replace('amp;', '')
a.put(href)
a.task_done()
class Spider(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
href = a.get()
res = requests.get(href, headers=header2)
html = res.text
pattern_title = '<title>(.*?)</title>'
title = re.findall(pattern_title, html, re.S)
pattern_content = '<div class="rich_media_content " id="js_content">(.*?)</div>'
content1 = re.findall(pattern_content, html, re.S)
print(title)
# time.sleep(1.5)
pattern_content2 = '>(.*?)<'
content2 = re.findall(pattern_content2, content1[0], re.S)
while '' in content2:
content2.remove('')
content = ''
for i in content2:
content = content + i
content = content.replace(' ','')
print(content)
開兩個(gè)線程,一個(gè)爬取url放進(jìn)url池,一個(gè)從url池里獲取url然后爬取內(nèi)容,再開一個(gè)線程監(jiān)控兩個(gè)線程,如果兩個(gè)線程運(yùn)行完畢,結(jié)束主線程。
python的多線程機(jī)制底層做的其實(shí)不好,理由不多講。另,多線程具體操作很多就不展開講了。
四、關(guān)于使用代理ip
很多網(wǎng)站會(huì)有ip檢測(cè)機(jī)制,當(dāng)同一ip以人力無(wú)法做到的速度多次訪問(wèn)網(wǎng)站時(shí),通常就會(huì)觸發(fā)這種機(jī)制。
代理ip的話,通常通過(guò)爬取一些開源ip網(wǎng)站發(fā)布的ip構(gòu)建ip代理池,比如西刺、蘑菇等。這樣的一些網(wǎng)站,直接百度代理ip就能找到。然后,使用Flask+Redis維護(hù)代理池。這部分詳細(xì)說(shuō)明也比較長(zhǎng),就不細(xì)說(shuō)了。也不是爬蟲必要的東西。另,自己有服務(wù)器的也可以使用SSR的翻墻工具,不過(guò)搭建不是樓主親手做的,所以就不詳細(xì)說(shuō)明了。
五、關(guān)于selenium模仿瀏覽器操作
關(guān)于selenium主要介紹以下幾點(diǎn):
1、selenium 是一套完整的web應(yīng)用程序測(cè)試系統(tǒng),包含了測(cè)試的錄制(selenium IDE),編寫及運(yùn)行(Selenium Remote Control)和測(cè)試的并行處理(Selenium Grid)。
2、Selenium的核心Selenium Core基于JsUnit,完全由JavaScript編寫,因此可以用于任何支持JavaScript的瀏覽器上。
3、selenium可以模擬真實(shí)瀏覽器,自動(dòng)化測(cè)試工具,支持多種瀏覽器,爬蟲中主要用來(lái)解決JavaScript渲染問(wèn)題。
4、用python寫爬蟲的時(shí)候,主要用的是selenium的Webdriver。
這些是某說(shuō)明文檔的內(nèi)容,能看懂就看,看不懂就看樓主的簡(jiǎn)單版:
selenium的話主要用于模仿瀏覽器操作,比如向文本框中賦值,點(diǎn)擊按鈕等。配合高效率瀏覽器的話也是實(shí)現(xiàn)爬蟲的一個(gè)比較好的方法。優(yōu)點(diǎn)是通過(guò)模擬瀏覽器操作,不易被反爬檢測(cè)。缺點(diǎn)是效率低下,非常不適合大型爬蟲,小作坊自己玩玩就好。
六、關(guān)于Scrapy框架
這又是一塊非常非常龐大的內(nèi)容,很多技術(shù)一旦牽扯上框架就麻煩了。當(dāng)然學(xué)會(huì)了的話,做大型項(xiàng)目就簡(jiǎn)單多了。重點(diǎn)就是框架一般針對(duì)比較大型的系統(tǒng)去做,所以其管理和操作會(huì)比較麻煩,內(nèi)部的一些機(jī)制也不是很好說(shuō)明。這一塊的話如果以后有時(shí)間就單獨(dú)寫一篇文章詳細(xì)介紹,畢竟從原理到搭建到配置到使用,內(nèi)容太多。。
七、關(guān)于驗(yàn)證碼處理
對(duì)于處理驗(yàn)證碼的話,目前簡(jiǎn)單點(diǎn)的是直接使用PIL(pillow)做圖像處理,然后使用Tesseract直接識(shí)別。此方法樓主已經(jīng)寫好了單獨(dú)的文章供大家參考。
另,如果學(xué)過(guò)機(jī)器學(xué)習(xí)神經(jīng)網(wǎng)絡(luò)這部分的話,還可以使用卷積神經(jīng)網(wǎng)絡(luò)。這個(gè)方向樓主還正在學(xué),簡(jiǎn)單給大家指條路,不詳述。
以上是樓主想到的爬蟲所有內(nèi)容,若有錯(cuò)誤還望指正。
- 零基礎(chǔ)寫python爬蟲之爬蟲編寫全記錄
- Python爬蟲模擬登錄帶驗(yàn)證碼網(wǎng)站
- 三個(gè)python爬蟲項(xiàng)目實(shí)例代碼
- 33個(gè)Python爬蟲項(xiàng)目實(shí)戰(zhàn)(推薦)
- python抓取網(wǎng)頁(yè)圖片示例(python爬蟲)
- Python實(shí)現(xiàn)抓取頁(yè)面上鏈接的簡(jiǎn)單爬蟲分享
- 10個(gè)python爬蟲入門基礎(chǔ)代碼實(shí)例 + 1個(gè)簡(jiǎn)單的python爬蟲完整實(shí)例
- Python網(wǎng)絡(luò)爬蟲技術(shù)高階用法
相關(guān)文章
表格梳理python內(nèi)置數(shù)學(xué)模塊math分析詳解
這篇文章主要為大家介紹了python內(nèi)置數(shù)學(xué)模塊math的分析詳解,文中通過(guò)表格梳理的方式以便讓大家在學(xué)習(xí)過(guò)程中一目望去清晰明了,有需要的朋友可以借鑒參考下2021-10-10
Python遠(yuǎn)程控制Windows服務(wù)器的方法詳解
在很多企業(yè)會(huì)使用閑置的 Windows 機(jī)器作為臨時(shí)服務(wù)器,有時(shí)候我們想遠(yuǎn)程調(diào)用里面的程序或查看日志文件。本文分享了利用Python遠(yuǎn)程控制Windows服務(wù)器的方法,感興趣的可以學(xué)習(xí)一下2022-05-05
使用matlab或python將txt文件轉(zhuǎn)為excel表格
這篇文章主要介紹了matlab或python代碼將txt文件轉(zhuǎn)為excel表格,本文通過(guò)matlab代碼和python 代碼給大家詳細(xì)介紹,需要的朋友可以參考下2019-11-11
python區(qū)塊鏈創(chuàng)建多個(gè)交易教程
這篇文章主要為大家介紹了python區(qū)塊鏈創(chuàng)建多個(gè)交易的實(shí)現(xiàn)示例教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05
基于Python編寫簡(jiǎn)單實(shí)用的日志裝飾器
在寫代碼的時(shí)候,往往會(huì)漏掉日志這個(gè)關(guān)鍵因素,導(dǎo)致功能在使用的時(shí)候出錯(cuò)卻無(wú)法溯源。這個(gè)時(shí)候只要利用日志裝飾器就能解決,本文將用Python自制一個(gè)簡(jiǎn)單實(shí)用的日志裝飾器,需要的可以參考一下2022-05-05
python 實(shí)現(xiàn)圖片上傳接口開發(fā) 并生成可以訪問(wèn)的圖片url
今天小編就為大家分享一篇python 實(shí)現(xiàn)圖片上傳接口開發(fā) 并生成可以訪問(wèn)的圖片url,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-12-12

