新聞中心
一、前言

創(chuàng)新互聯(lián)服務(wù)項(xiàng)目包括烏魯木齊網(wǎng)站建設(shè)、烏魯木齊網(wǎng)站制作、烏魯木齊網(wǎng)頁(yè)制作以及烏魯木齊網(wǎng)絡(luò)營(yíng)銷策劃等。多年來(lái),我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,烏魯木齊網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到烏魯木齊省份的部分城市,未來(lái)相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!
作為一名合格的數(shù)據(jù)分析師,其完整的技術(shù)知識(shí)體系必須貫穿數(shù)據(jù)獲取、數(shù)據(jù)存儲(chǔ)、數(shù)據(jù)提取、數(shù)據(jù)分析、數(shù)據(jù)挖掘、數(shù)據(jù)可視化等各大部分。
在此作為初出茅廬的數(shù)據(jù)小白,我將會(huì)把自己學(xué)習(xí)數(shù)據(jù)科學(xué)過程中遇到的一些問題記錄下來(lái),以便后續(xù)的查閱,同時(shí)也希望與各路同學(xué)一起交流、一起進(jìn)步。剛好前段時(shí)間學(xué)習(xí)了Python網(wǎng)絡(luò)爬蟲,在此將網(wǎng)絡(luò)爬蟲做一個(gè)總結(jié)。
二、何為網(wǎng)絡(luò)爬蟲?
1. 爬蟲場(chǎng)景
我們先自己想象一下平時(shí)到天貓商城購(gòu)物(PC端)的步驟,可能就是:
打開瀏覽器==》搜索天貓商城==》點(diǎn)擊鏈接進(jìn)入天貓商城==》選擇所需商品類目(站內(nèi)搜索)==》瀏覽商品(價(jià)格、詳情參數(shù)、評(píng)論等)==》點(diǎn)擊鏈接==》進(jìn)入下一個(gè)商品頁(yè)面......
這樣子周而復(fù)始。當(dāng)然這其中的搜索也是爬蟲的應(yīng)用之一。簡(jiǎn)單講,網(wǎng)絡(luò)爬蟲是類似又區(qū)別于上述場(chǎng)景的一種程序。
2. 爬蟲分類
(1)分類與關(guān)系
一般最常用的爬蟲類型主要有通用爬蟲和聚焦爬蟲,其中聚焦爬蟲又分為淺聚焦與深聚焦,三者關(guān)系如下圖:
(2)區(qū)別
通用爬蟲與聚焦爬蟲的區(qū)別就在有沒有對(duì)信息進(jìn)行過濾以盡量保證只抓取與主題相關(guān)的網(wǎng)頁(yè)信息。
(3)聚焦爬蟲過濾方法
- 淺聚焦爬蟲
選取符合目標(biāo)主題的種子URL,例如我們定義抓取的信息為招聘信息,我們便可將招聘網(wǎng)站的URL(拉勾網(wǎng)、大街網(wǎng)等)作為種子URL,這樣便保證了抓取內(nèi)容與我們定義的主題的一致性。
- 深聚焦爬蟲
一般有兩種,一是針對(duì)內(nèi)容二是針對(duì)URL。其中針對(duì)內(nèi)容的如頁(yè)面中絕大部分超鏈接都是帶有錨文本的,我們可以根據(jù)錨文本進(jìn)行篩選。
3. 爬蟲原理
總的來(lái)說(shuō),爬蟲就是從種子URL開始,通過 HTTP 請(qǐng)求獲取頁(yè)面內(nèi)容,并從頁(yè)面內(nèi)容中通過各種技術(shù)手段解析出更多的 URL,遞歸地請(qǐng)求獲取頁(yè)面的程序網(wǎng)絡(luò)爬蟲,總結(jié)其主要原理如下圖(其中紅色為聚焦爬蟲相對(duì)通用爬蟲所需額外進(jìn)行步驟):
4. 爬蟲應(yīng)用
網(wǎng)絡(luò)爬蟲可以做的事情很多,如以下列出:
- 搜索引擎
- 采集數(shù)據(jù)(金融、商品、競(jìng)品等)
- 廣告過濾
- ……
其實(shí)就我們個(gè)人興趣,學(xué)完爬蟲我們可以看看當(dāng)當(dāng)網(wǎng)上哪種技術(shù)圖書賣得比較火(銷量、評(píng)論等信息)、看某個(gè)在線教育網(wǎng)站哪門網(wǎng)絡(luò)課程做得比較成功、看雙十一天貓的活動(dòng)情況等等,只要我們感興趣的數(shù)據(jù),一般的話都可以爬取得到,不過有些網(wǎng)站比較狡猾,設(shè)置各種各樣的反扒機(jī)制。總而言之,網(wǎng)絡(luò)爬蟲可以幫助我們做很多有趣的事情。
三、網(wǎng)絡(luò)爬蟲基礎(chǔ)
個(gè)人建議本章除3.3以外,其他內(nèi)容可以大致先看一下,有些許印象即可,等到后面已經(jīng)完成一些簡(jiǎn)單爬蟲后或者在寫爬蟲過程中遇到一些問題再回頭來(lái)鞏固一下,這樣子或許更有助于我們進(jìn)一步網(wǎng)絡(luò)理解爬蟲。
1. HTTP協(xié)議
HTTP 協(xié)議是爬蟲的基礎(chǔ),通過封裝 TCP/IP 協(xié)議鏈接,簡(jiǎn)化了網(wǎng)絡(luò)請(qǐng)求的流程,使得用戶不需要關(guān)注三次握手,丟包超時(shí)等底層交互。
2. 前端技術(shù)
作為新手,個(gè)人覺得入門的話懂一點(diǎn)HTML與JavaScript就可以實(shí)現(xiàn)基本的爬蟲項(xiàng)目,HTML主要協(xié)助我們處理靜態(tài)頁(yè)面,而實(shí)際上很多數(shù)據(jù)并不是我們簡(jiǎn)單的右擊查看網(wǎng)頁(yè)源碼便可以看到的,而是存在JSON(JavaScript Object Notation)文件中,這時(shí)我們便需要采取抓包分析,詳見《5.2 爬取基于Ajax技術(shù)網(wǎng)頁(yè)數(shù)據(jù)》。
3. 正則表達(dá)式與XPath
做爬蟲必不可少的步驟便是做解析。正則表達(dá)式是文本匹配提取的利器,并且被各種語(yǔ)言支持。XPath即為XML路徑語(yǔ)言,類似Windows的文件路徑,區(qū)別就在XPath是應(yīng)用在網(wǎng)頁(yè)頁(yè)面中來(lái)定位我們所需內(nèi)容的精確位置。
四、網(wǎng)絡(luò)爬蟲常見問題
1. 爬蟲利器——python
Python 是一種十分便利的腳本語(yǔ)言,廣泛被應(yīng)用在各種爬蟲框架。Python提供了如urllib、re、json、pyquery等模塊,同時(shí)前人又利用Python造了許許多多的輪,如Scrapy框架、PySpider爬蟲系統(tǒng)等,所以做爬蟲Python是一大利器。
說(shuō)明:本章開發(fā)環(huán)境細(xì)節(jié)如下
- 系統(tǒng)環(huán)境:windows 8.1
- 開發(fā)語(yǔ)言:Python3.5
- 開發(fā)工具:Spyder、Pycharm
- 輔助工具:Chrome瀏覽器
2. 編碼格式
Python3中,只有Unicode編碼的為str,其他編碼格式如gbk,utf-8,gb2312等都為bytes,在編解碼過程中字節(jié)bytes通過解碼方法decode()解碼為字符串str,然后字符串str通過編碼方法encode()編碼為字節(jié)bytes,關(guān)系如下圖:
實(shí)戰(zhàn)——爬取當(dāng)當(dāng)網(wǎng)
爬取網(wǎng)頁(yè)
- In [5]:import urllib.request
- ...:data = urllib.request.urlopen("http://www.dangdang.com/").read()
- #爬取的data中的
標(biāo)簽中的內(nèi)容如下: \xb5\xb1\xb5\xb1\xa1\xaa\xcd\xf8\xc9\xcf\xb9\xba\xce\xef\xd6\xd0\xd0\xc4\xa3\xba\xcd\xbc\xca\xe9\xa1\xa2\xc4\xb8\xd3\xa4\xa1\xa2\xc3\xc0\xd7\xb1\xa1\xa2\xbc\xd2\xbe\xd3\xa1\xa2\xca\xfd\xc2\xeb\xa1\xa2\xbc\xd2\xb5\xe7\xa1\xa2\xb7\xfe\xd7\xb0\xa1\xa2\xd0\xac\xb0\xfc\xb5\xc8\xa3\xac\xd5\xfd\xc6\xb7\xb5\xcd\xbc\xdb\xa3\xac\xbb\xf5\xb5\xbd\xb8\xb6\xbf\xee
查看編碼格式
- In [5]:import chardet
- ...:chardet.detect(data)
- Out[5]: {'confidence': 0.99, 'encoding': 'GB2312'}
可知爬取到的網(wǎng)頁(yè)是GB2312編碼,這是漢字的國(guó)標(biāo)碼,專門用來(lái)表示漢字。
解碼
- In [5]:decodeData = data.decode("gbk")
- #此時(shí)bytes已經(jīng)解碼成str,
標(biāo)簽內(nèi)容解碼結(jié)果如下: 當(dāng)當(dāng)—網(wǎng)上購(gòu)物中心:圖書、母嬰、美妝、家居、數(shù)碼、家電、服裝、鞋包等,正品低價(jià),貨到付款
重編碼
- dataEncode = decodeData.encode("utf-8","ignore")
- #重編碼結(jié)果
\xe5\xbd\x93\xe5\xbd\x93\xe2\x80\x94\xe7\xbd\x91\xe4\xb8\x8a\xe8\xb4\xad\xe7\x89\xa9\xe4\xb8\xad\xe5\xbf\x83\xef\xbc\x9a\xe5\x9b\xbe\xe4\xb9\xa6\xe3\x80\x81\xe6\xaf\x8d\xe5\xa9\xb4\xe3\x80\x81\xe7\xbe\x8e\xe5\xa6\x86\xe3\x80\x81\xe5\xae\xb6\xe5\xb1\x85\xe3\x80\x81\xe6\x95\xb0\xe7\xa0\x81\xe3\x80\x81\xe5\xae\xb6\xe7\x94\xb5\xe3\x80\x81\xe6\x9c\x8d\xe8\xa3\x85\xe3\x80\x81\xe9\x9e\x8b\xe5\x8c\x85\xe7\xad\x89\xef\xbc\x8c\xe6\xad\xa3\xe5\x93\x81\xe4\xbd\x8e\xe4\xbb\xb7\xef\xbc\x8c\xe8\xb4\xa7\xe5\x88\xb0\xe4\xbb\x98\xe6\xac\xbe
3. 超時(shí)設(shè)置
允許超時(shí)
data = urllib.request.urlopen(“http://www.dangdang.com/”,timeout=3).read()
線程推遲(單位為秒)
import timetime.sleep(3)
4. 異常處理
每個(gè)程序都不可避免地要進(jìn)行異常處理,爬蟲也不例外,假如不進(jìn)行異常處理,可能導(dǎo)致爬蟲程序直接崩掉。
1. 網(wǎng)絡(luò)爬蟲中處理異常的種類與關(guān)系
(1)URLError
通常,URLError在沒有網(wǎng)絡(luò)連接(沒有路由到特定服務(wù)器),或者服務(wù)器不存在的情況下產(chǎn)生。
(2)HTTPError
首先我們要明白服務(wù)器上每一個(gè)HTTP 應(yīng)答對(duì)象response都包含一個(gè)數(shù)字“狀態(tài)碼”,該狀態(tài)碼表示HTTP協(xié)議所返回的響應(yīng)的狀態(tài),這就是HTTPError。比如當(dāng)產(chǎn)生“404 Not Found”的時(shí)候,便表示“沒有找到對(duì)應(yīng)頁(yè)面”,可能是輸錯(cuò)了URL地址,也可能IP被該網(wǎng)站屏蔽了,這時(shí)便要使用代理IP進(jìn)行爬取數(shù)據(jù),關(guān)于代理IP的設(shè)定我們下面會(huì)講到。
(3)兩者關(guān)系
兩者是父類與子類的關(guān)系,即HTTPError是URLError的子類,HTTPError有異常狀態(tài)碼與異常原因,URLError沒有異常狀態(tài)碼。所以,我們?cè)谔幚淼臅r(shí)候,不能使用URLError直接代替HTTPError。同時(shí),Python中所有異常都是基類Exception的成員,所有異常都從此基類繼承,而且都在exceptions模塊中定義。如果要代替,必須要判斷是否有狀態(tài)碼屬性。
2. Python中有一套異常處理機(jī)制語(yǔ)法
(1)try-except語(yǔ)句
- try:
- blockexcept Exception as e:
- blockelse:
- block
- try 語(yǔ)句:捕獲異常
- except語(yǔ)句:處理不同的異常,Exception是異常的種類,在爬蟲中常見如上文所述。
- e:異常的信息,可供后面打印輸出
- else: 表示若沒有發(fā)生異常,當(dāng)try執(zhí)行完畢之后,就會(huì)執(zhí)行else
(2)try-except-finally語(yǔ)句
- try:
- block except Exception as e:
- blockfinally:
- block
假如try沒有捕獲到錯(cuò)誤信息,則直接跳過except語(yǔ)句轉(zhuǎn)而執(zhí)行finally語(yǔ)句,其實(shí)無(wú)論是否捕獲到異常都會(huì)執(zhí)行finally語(yǔ)句,因此一般我們都會(huì)將一些釋放資源的工作放到該步中,如關(guān)閉文件句柄或者關(guān)閉數(shù)據(jù)庫(kù)連接等。
4. 自動(dòng)模擬HTTP請(qǐng)求
一般客戶端需要通過HTTP請(qǐng)求才能與服務(wù)端進(jìn)行通信,常見的HTTP請(qǐng)求有POST與GET兩種。例如我們打開淘寶網(wǎng)頁(yè)后一旦HTML加載完成,瀏覽器將會(huì)發(fā)送GET請(qǐng)求去獲取圖片等,這樣子我們才能看到一個(gè)完整的動(dòng)態(tài)頁(yè)面,假如我們?yōu)g覽后需要下單那么還需要向服務(wù)器傳遞登錄信息。
(1)GET方式
向服務(wù)器發(fā)索取數(shù)據(jù)的一種請(qǐng)求,將請(qǐng)求數(shù)據(jù)融入到URL之中,數(shù)據(jù)在URL中可以看到。
(2)POST方式
向服務(wù)器提交數(shù)據(jù)的一種請(qǐng)求,將數(shù)據(jù)放置在HTML HEADER內(nèi)提交。從安全性講,POST方式相對(duì)于GET方式較為安全,畢竟GET方式是直接將請(qǐng)求數(shù)據(jù)以明文的形式展現(xiàn)在URL中。
5. cookies處理
cookies是某些網(wǎng)站為了辨別用戶身份、進(jìn)行session跟蹤而儲(chǔ)存在用戶本地終端上的數(shù)據(jù)(通常經(jīng)過加密)。
6. 瀏覽器偽裝
(1)原理
瀏覽器偽裝是防屏蔽的方法之一,簡(jiǎn)言之,其原理就是在客戶端在向服務(wù)端發(fā)送的請(qǐng)求中添加報(bào)頭信息,告訴服務(wù)器“我是瀏覽器”
(2)如何查看客戶端信息?
通過Chrome瀏覽器按F12==》選擇Network==》刷新后點(diǎn)擊Name下任一個(gè)地址,便可以看到請(qǐng)求報(bào)文和相應(yīng)報(bào)文信息。以下是在百度上搜索簡(jiǎn)書的請(qǐng)求報(bào)文信息,在爬蟲中我們只需添加報(bào)頭中的User-Agent便可實(shí)現(xiàn)瀏覽器偽裝。
7. 代理服務(wù)器
(1)原理
代理服務(wù)器原理如下圖,利用代理服務(wù)器可以很好處理IP限制問題。
個(gè)人認(rèn)為IP限制這一點(diǎn)對(duì)爬蟲的影響是很大的,畢竟我們一般不會(huì)花錢去購(gòu)買正規(guī)的代理IP,我們一般都是利用互聯(lián)網(wǎng)上提供的一些免費(fèi)代理IP進(jìn)行爬取,而這些免費(fèi)IP的質(zhì)量殘次不齊,出錯(cuò)是在所難免的,所以在使用之前我們要對(duì)其進(jìn)行有效性測(cè)試。
(2)實(shí)戰(zhàn)——代理服務(wù)器爬取百度首頁(yè)
- import urllib.requestdef use_proxy(url,proxy_addr,iHeaders,timeoutSec):
- '''
- 功能:偽裝成瀏覽器并使用代理IP防屏蔽
- @url:目標(biāo)URL
- @proxy_addr:代理IP地址
- @iHeaders:瀏覽器頭信息
- @timeoutSec:超時(shí)設(shè)置(單位:秒)
- '''
- proxy = urllib.request.ProxyHandler({"http":proxy_addr})
- opener = urllib.request.build_opener(proxy,urllib.request.HTTPHandler)
- urllib.request.install_opener(opener)
- try:
- req = urllib.request.Request(url,headers = iHeaders) #偽裝為瀏覽器并封裝request
- data = urllib.request.urlopen(req).read().decode("utf-8","ignore")
- except Exception as er:
- print("爬取時(shí)發(fā)生錯(cuò)誤,具體如下:")
- print(er)
- return data
- url = "http://www.baidu.com"
- proxy_addr = "125.94.0.253:8080"
- iHeaders = {"User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.22 Safari/537.36 SE 2.X MetaSr 1.0"}
- timeoutSec = 10
- data = use_proxy(url,proxy_addr,iHeaders,timeoutSec)
- print(len(data))
8. 抓包分析
(1)Ajax(異步加載)的技術(shù)
網(wǎng)站中用戶需求的數(shù)據(jù)如聯(lián)系人列表,可以從獨(dú)立于實(shí)際網(wǎng)頁(yè)的服務(wù)端取得并且可以被動(dòng)態(tài)地寫入網(wǎng)頁(yè)中。簡(jiǎn)單講就是打開網(wǎng)頁(yè),先展現(xiàn)部分內(nèi)容,再慢慢加載剩下的內(nèi)容。顯然,這樣的網(wǎng)頁(yè)因?yàn)椴挥靡淮渭虞d全部?jī)?nèi)容其加載速度特別快,但對(duì)于我們爬蟲的話就比較麻煩了,我們總爬不到我們想要的內(nèi)容,這時(shí)候就需要進(jìn)行抓包分析。
(2)抓包工具
推薦Fiddler與Chrome瀏覽器
(3)實(shí)戰(zhàn)
請(qǐng)轉(zhuǎn)《5.2 爬取基于Ajax技術(shù)網(wǎng)頁(yè)數(shù)據(jù)》。
9. 多線程爬蟲
一般我們程序是單線程運(yùn)行,但多線程可以充分利用資源,優(yōu)化爬蟲效率。實(shí)際上Python 中的多線程并行化并不是真正的并行化,但是多線程在一定程度上還是能提高爬蟲的執(zhí)行效率,下面我們就針對(duì)單線程和多線程進(jìn)行時(shí)間上的比較。
(1)實(shí)戰(zhàn)——爬取豆瓣科幻電影網(wǎng)頁(yè)
- '''多線程'''import urllibfrom multiprocessing.dummy import Poolimport timedef getResponse(url):
- '''獲取響應(yīng)信息'''
- try:
- req = urllib.request.Request(url)
- res = urllib.request.urlopen(req)
- except Exception as er:
- print("爬取時(shí)發(fā)生錯(cuò)誤,具體如下:")
- print(er)
- return resdef getURLs():
- '''獲取所需爬取的所有URL'''
- urls = []
- for i in range(0, 101,20):#每翻一頁(yè)其start值增加20
- keyword = "科幻"
- keyword = urllib.request.quote(keyword)
- newpage = "https://movie.douban.com/tag/"+keyword+"?start="+str(i)+"&type=T"
- urls.append(newpage)
- return urls def singleTime(urls):
- '''單進(jìn)程計(jì)時(shí)'''
- timetime1 = time.time()
- for i in urls:
- print(i)
- getResponse(i)
- timetime2 = time.time()
- return str(time2 - time1) def multiTime(urls):
- '''多進(jìn)程計(jì)時(shí)'''
- pool = Pool(processes=4) #開啟四個(gè)進(jìn)程
- timetime3 = time.time()
- pool.map(getResponse,urls)
- pool.close()
- pool.join() #等待進(jìn)程池中的worker進(jìn)程執(zhí)行完畢
- timetime4 = time.time()
- return str(time4 - time3) if __name__ == '__main__':
- urls = getURLs()
- singleTimesingleTimes = singleTime(urls) #單線程計(jì)時(shí)
- multiTimemultiTimes = multiTime(urls) #多線程計(jì)時(shí)
- print('單線程耗時(shí) : ' + singleTimes + ' s')
- print('多線程耗時(shí) : ' + multiTimes + ' s')
(2)結(jié)果:
單線程耗時(shí) : 3.850554943084717 s
多線程耗時(shí) : 1.3288819789886475 s
10. 數(shù)據(jù)存儲(chǔ)
- 本地文件(excel、txt)
- 數(shù)據(jù)庫(kù)(如MySQL)
備注:具體實(shí)戰(zhàn)請(qǐng)看5.1
11. 驗(yàn)證碼處理
在登錄過程中我們常遇到驗(yàn)證碼問題,此時(shí)我們有必要對(duì)其進(jìn)行處理。
(1)簡(jiǎn)單驗(yàn)證碼識(shí)別
利用pytesser識(shí)別簡(jiǎn)單圖形驗(yàn)證碼,
(2)復(fù)雜驗(yàn)證碼識(shí)別
這相對(duì)有難度,可以調(diào)用第三方接口(如打碼兔)、利用數(shù)據(jù)挖掘算法如SVM
接下篇文章《一名合格的數(shù)據(jù)分析師分享Python網(wǎng)絡(luò)爬蟲二三事(綜合實(shí)戰(zhàn)案例)》
【本文是專欄機(jī)構(gòu)“豈安科技”的原創(chuàng)文章,轉(zhuǎn)載請(qǐng)通過微信公眾號(hào)(bigsec)聯(lián)系原作者】
文章標(biāo)題:一名合格的數(shù)據(jù)分析師分享Python網(wǎng)絡(luò)爬蟲二三事
文章路徑:http://fisionsoft.com.cn/article/coijoeh.html


咨詢
建站咨詢
