亚洲国产精品无码久久大片,亚洲AV无码乱码麻豆精品国产,亚洲品质自拍网站,少妇伦子伦精品无码STYLES,国产精久久久久久久

c爬蟲(chóng)抓取網(wǎng)頁(yè)數據

c爬蟲(chóng)抓取網(wǎng)頁(yè)數據

c爬蟲(chóng)抓取網(wǎng)頁(yè)數據正常情況下發(fā)生的場(chǎng)景是什么?

網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 103 次瀏覽 ? 2022-09-06 16:02 ? 來(lái)自相關(guān)話(huà)題

  c爬蟲(chóng)抓取網(wǎng)頁(yè)數據正常情況下發(fā)生的場(chǎng)景是什么?
  c爬蟲(chóng)抓取網(wǎng)頁(yè)數據正常情況下發(fā)生的場(chǎng)景是:用戶(hù)發(fā)起一次請求,從瀏覽器的user-agent(瀏覽器上面一個(gè)host或者cookie)里面獲取對應的body,然后交給爬蟲(chóng)解析交給c段發(fā)起連接請求,兩邊繼續一對一的發(fā)起請求,但是一般情況下連接建立得不是太多,所以一般來(lái)說(shuō)單方面只能發(fā)起一次連接請求。但是,機器比較多的情況下,系統可能就要發(fā)起一次連接請求了,比如加入了多種進(jìn)程,那么這個(gè)連接請求可能連接多個(gè)進(jìn)程,甚至數十個(gè)進(jìn)程,在本文中,我們以一個(gè)前端每秒發(fā)起三次連接請求為例,將爬蟲(chóng)和后端連接請求相連接原理一次連接請求解析圖解1:從user-agent我們知道用戶(hù)瀏覽器里面的user-agent,瀏覽器在接收到了連接請求之后,首先會(huì )首先去查看請求里面的參數,看這些參數指定的資源是不是自己想要的,一般的發(fā)送的時(shí)候都會(huì )帶著(zhù)對應的headers,比如cookie之類(lèi)的。
  
  那么連接請求用到了哪些參數?user-agent:你要發(fā)送的user-agent-agent-名:你想發(fā)送的user-agent-agent-數:你想發(fā)送的user-agent-agent-cookie:你發(fā)送的user-agent-agent-數值那么requestheaders就是我們最常用的兩個(gè)參數,頭部的部分跟request沒(méi)什么區別,這里重點(diǎn)看一下服務(wù)端參數第一個(gè)參數是cookie,前面請求里面也提到了,這個(gè)cookie在別的連接請求里面可能會(huì )用到;其次還有一個(gè)cookiebanner,也就是獲取cookie的通道,一般來(lái)說(shuō)可以用httpcookie連接推送http請求推送完cookie之后,后面這些數據就不再重復發(fā)送了。
  
  第二個(gè)是服務(wù)端可以獲取到的參數還有:cookie的host和max-age設置你的端口及子域名之類(lèi)的對第一個(gè)參數進(jìn)行檢查,如果是一個(gè)比較熟悉自己程序請求的人,他會(huì )知道使用自己家的服務(wù)器,或者是自己家的機器,或者是自己家機器的內部連接,實(shí)際上你還可以在后臺找到一些端口。對第二個(gè)參數,我們一般也是根據自己的業(yè)務(wù)來(lái)選擇對應的參數,如果要抓的數據量大,我們的連接請求數可能就會(huì )很多,或者對user-agent提供了頭部的cookie可以直接在相應設置連接請求,如果需要抓多個(gè)不同資源,在不太熟悉的情況下,最好就抓取一個(gè),進(jìn)行連接請求,這樣可以減輕連接請求的負擔,而使得連接效率更高。
  2:給請求加上代理如果要發(fā)送多個(gè)user-agent請求,那么一個(gè)個(gè)的發(fā)送這種連接請求會(huì )很慢的,那么可以加一個(gè)代理服務(wù)器進(jìn)行發(fā)送,代理服務(wù)器可以是公網(wǎng)的,也可以是爬蟲(chóng)自己的機器,速度比在本地發(fā)送要快,而且,代理服務(wù)器里面數據也是你自己配置的,這樣可以防止惡意爬蟲(chóng)連接請求到你的程序。那么。 查看全部

  c爬蟲(chóng)抓取網(wǎng)頁(yè)數據正常情況下發(fā)生的場(chǎng)景是什么?
  c爬蟲(chóng)抓取網(wǎng)頁(yè)數據正常情況下發(fā)生的場(chǎng)景是:用戶(hù)發(fā)起一次請求,從瀏覽器的user-agent(瀏覽器上面一個(gè)host或者cookie)里面獲取對應的body,然后交給爬蟲(chóng)解析交給c段發(fā)起連接請求,兩邊繼續一對一的發(fā)起請求,但是一般情況下連接建立得不是太多,所以一般來(lái)說(shuō)單方面只能發(fā)起一次連接請求。但是,機器比較多的情況下,系統可能就要發(fā)起一次連接請求了,比如加入了多種進(jìn)程,那么這個(gè)連接請求可能連接多個(gè)進(jìn)程,甚至數十個(gè)進(jìn)程,在本文中,我們以一個(gè)前端每秒發(fā)起三次連接請求為例,將爬蟲(chóng)和后端連接請求相連接原理一次連接請求解析圖解1:從user-agent我們知道用戶(hù)瀏覽器里面的user-agent,瀏覽器在接收到了連接請求之后,首先會(huì )首先去查看請求里面的參數,看這些參數指定的資源是不是自己想要的,一般的發(fā)送的時(shí)候都會(huì )帶著(zhù)對應的headers,比如cookie之類(lèi)的。
  
  那么連接請求用到了哪些參數?user-agent:你要發(fā)送的user-agent-agent-名:你想發(fā)送的user-agent-agent-數:你想發(fā)送的user-agent-agent-cookie:你發(fā)送的user-agent-agent-數值那么requestheaders就是我們最常用的兩個(gè)參數,頭部的部分跟request沒(méi)什么區別,這里重點(diǎn)看一下服務(wù)端參數第一個(gè)參數是cookie,前面請求里面也提到了,這個(gè)cookie在別的連接請求里面可能會(huì )用到;其次還有一個(gè)cookiebanner,也就是獲取cookie的通道,一般來(lái)說(shuō)可以用httpcookie連接推送http請求推送完cookie之后,后面這些數據就不再重復發(fā)送了。
  
  第二個(gè)是服務(wù)端可以獲取到的參數還有:cookie的host和max-age設置你的端口及子域名之類(lèi)的對第一個(gè)參數進(jìn)行檢查,如果是一個(gè)比較熟悉自己程序請求的人,他會(huì )知道使用自己家的服務(wù)器,或者是自己家的機器,或者是自己家機器的內部連接,實(shí)際上你還可以在后臺找到一些端口。對第二個(gè)參數,我們一般也是根據自己的業(yè)務(wù)來(lái)選擇對應的參數,如果要抓的數據量大,我們的連接請求數可能就會(huì )很多,或者對user-agent提供了頭部的cookie可以直接在相應設置連接請求,如果需要抓多個(gè)不同資源,在不太熟悉的情況下,最好就抓取一個(gè),進(jìn)行連接請求,這樣可以減輕連接請求的負擔,而使得連接效率更高。
  2:給請求加上代理如果要發(fā)送多個(gè)user-agent請求,那么一個(gè)個(gè)的發(fā)送這種連接請求會(huì )很慢的,那么可以加一個(gè)代理服務(wù)器進(jìn)行發(fā)送,代理服務(wù)器可以是公網(wǎng)的,也可以是爬蟲(chóng)自己的機器,速度比在本地發(fā)送要快,而且,代理服務(wù)器里面數據也是你自己配置的,這樣可以防止惡意爬蟲(chóng)連接請求到你的程序。那么。

c爬蟲(chóng)抓取網(wǎng)頁(yè)數據,使用session使得爬蟲(chóng)程序間隔時(shí)間不需要很長(cháng)

網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 85 次瀏覽 ? 2022-08-28 03:09 ? 來(lái)自相關(guān)話(huà)題

  c爬蟲(chóng)抓取網(wǎng)頁(yè)數據,使用session使得爬蟲(chóng)程序間隔時(shí)間不需要很長(cháng)
  
  c爬蟲(chóng)抓取網(wǎng)頁(yè)數據,使用session使得爬蟲(chóng)程序間隔時(shí)間不需要很長(cháng),節省了很多計算量。url解析,用urllib3本身并不需要session,而采用scrapy框架scrapy框架要實(shí)現不同url間的切換時(shí)候需要session,并且每個(gè)spider的不同url解析采用不同的spiderspider所以三者實(shí)現邏輯差異不大以下代碼是在scrapy框架下實(shí)現的,spider如下:pythonurllib3installscrapyimportscrapyimportseleniumimportrequestsimporttimedefgetpage(url):selenium.webdriver.chrome().executable['chromedriver.exe']2:#文件目錄和文件名有要求,一般>2try:drivermanager(x)exceptexceptionase:print('{0}'.format(e))returnnoneurl=getpage('')drivermanager(x)#使用chrome瀏覽器命令fromin(url)fromax(url)#定位瀏覽器輸入url時(shí)候的錯誤drivermanager(x。 查看全部

  c爬蟲(chóng)抓取網(wǎng)頁(yè)數據,使用session使得爬蟲(chóng)程序間隔時(shí)間不需要很長(cháng)
  
  c爬蟲(chóng)抓取網(wǎng)頁(yè)數據,使用session使得爬蟲(chóng)程序間隔時(shí)間不需要很長(cháng),節省了很多計算量。url解析,用urllib3本身并不需要session,而采用scrapy框架scrapy框架要實(shí)現不同url間的切換時(shí)候需要session,并且每個(gè)spider的不同url解析采用不同的spiderspider所以三者實(shí)現邏輯差異不大以下代碼是在scrapy框架下實(shí)現的,spider如下:pythonurllib3installscrapyimportscrapyimportseleniumimportrequestsimporttimedefgetpage(url):selenium.webdriver.chrome().executable['chromedriver.exe']2:#文件目錄和文件名有要求,一般>2try:drivermanager(x)exceptexceptionase:print('{0}'.format(e))returnnoneurl=getpage('')drivermanager(x)#使用chrome瀏覽器命令fromin(url)fromax(url)#定位瀏覽器輸入url時(shí)候的錯誤drivermanager(x。

網(wǎng)絡(luò )爬蟲(chóng)入門(mén)之python

網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 89 次瀏覽 ? 2022-08-09 02:18 ? 來(lái)自相關(guān)話(huà)題

  網(wǎng)絡(luò )爬蟲(chóng)入門(mén)之python
  網(wǎng)絡(luò )爬蟲(chóng)定義:
 ?。▉?lái)自于百度百科):網(wǎng)絡(luò )爬蟲(chóng)(又稱(chēng)為網(wǎng)頁(yè)蜘蛛,網(wǎng)絡(luò )機器人,在FOAF社區中間,更經(jīng)常的稱(chēng)為網(wǎng)頁(yè)追逐者),是一種按照一定的規則,自動(dòng)地抓取萬(wàn)維網(wǎng)信息的程序或者腳本。另外一些不常使用的名字還有螞蟻、自動(dòng)索引、模擬程序或者蠕蟲(chóng)。
  為什么要學(xué):
  在數據爆發(fā)式增長(cháng)時(shí)代,如果這些數據得以分析利用,可以幫助企業(yè)更好的做出決策。網(wǎng)絡(luò )爬蟲(chóng)技術(shù),也是大數據分析的第一個(gè)環(huán)節。
  Robots協(xié)議(爬蟲(chóng)協(xié)議)
  全稱(chēng)是網(wǎng)絡(luò )爬蟲(chóng)排除標準,通過(guò)該協(xié)議告訴搜索引擎哪些頁(yè)面可以抓取,哪些不能抓取。是國際互聯(lián)網(wǎng)通行的道德規范,雖然沒(méi)有寫(xiě)入法律,但每一個(gè)爬蟲(chóng)都應該遵守這項協(xié)議。
  python
 ?。▉?lái)自于百度百科):Python由荷蘭數學(xué)和計算機科學(xué)研究學(xué)會(huì )的吉多·范羅蘇姆于1990年代初設計,作為一門(mén)叫做ABC語(yǔ)言的替代品。Python提供了高效的高級數據結構,還能簡(jiǎn)單有效地面向對象編程。Python語(yǔ)法和動(dòng)態(tài)類(lèi)型,以及解釋型語(yǔ)言的本質(zhì),使它成為多數平臺上寫(xiě)腳本和快速開(kāi)發(fā)應用的編程語(yǔ)言, 隨著(zhù)版本的不斷更新和語(yǔ)言新功能的添加,逐漸被用于獨立的、大型項目的開(kāi)發(fā)。
  Python解釋器易于擴展,可以使用C語(yǔ)言或C++(或者其他可以通過(guò)C調用的語(yǔ)言)擴展新的功能和數據類(lèi)型。Python也可用于可定制化軟件中的擴展程序語(yǔ)言。Python豐富的標準庫,提供了適用于各個(gè)主要系統平臺的源碼或機器碼。
  2021年10月,語(yǔ)言流行指數的編譯器Tiobe將Python加冕為最受歡迎的編程語(yǔ)言,20年來(lái)首次將其置于Java、C和JavaScript之上。
  
  版本很多,本次使用python3
  python爬蟲(chóng)流程
  重要知識點(diǎn):
  獲取網(wǎng)頁(yè):requests、urllib、selenium
  解析網(wǎng)頁(yè):re正則表達式、BeautifulSoup、lxml
  存儲數據:存入txt、csv、存入mysql、redis、mongodb等
  框架:scrapy
  python 安裝
  使用Anaconda科學(xué)計算環(huán)境下載python
  安裝步驟 自行搜索百度,有很多,其實(shí)就是下一步下一步。使用pip安裝第三方庫或者使用Anaconda安裝第三方庫。
  
  編輯器:Pycharm
  如果你使用Python安裝包下載的python,推薦使用pycharm編輯器。下載免費版即可,官網(wǎng)好像被墻了。
  python之初嘗試
  python之爬蟲(chóng)初嘗試 查看全部

  網(wǎng)絡(luò )爬蟲(chóng)入門(mén)之python
  網(wǎng)絡(luò )爬蟲(chóng)定義:
 ?。▉?lái)自于百度百科):網(wǎng)絡(luò )爬蟲(chóng)(又稱(chēng)為網(wǎng)頁(yè)蜘蛛,網(wǎng)絡(luò )機器人,在FOAF社區中間,更經(jīng)常的稱(chēng)為網(wǎng)頁(yè)追逐者),是一種按照一定的規則,自動(dòng)地抓取萬(wàn)維網(wǎng)信息的程序或者腳本。另外一些不常使用的名字還有螞蟻、自動(dòng)索引、模擬程序或者蠕蟲(chóng)。
  為什么要學(xué):
  在數據爆發(fā)式增長(cháng)時(shí)代,如果這些數據得以分析利用,可以幫助企業(yè)更好的做出決策。網(wǎng)絡(luò )爬蟲(chóng)技術(shù),也是大數據分析的第一個(gè)環(huán)節。
  Robots協(xié)議(爬蟲(chóng)協(xié)議)
  全稱(chēng)是網(wǎng)絡(luò )爬蟲(chóng)排除標準,通過(guò)該協(xié)議告訴搜索引擎哪些頁(yè)面可以抓取,哪些不能抓取。是國際互聯(lián)網(wǎng)通行的道德規范,雖然沒(méi)有寫(xiě)入法律,但每一個(gè)爬蟲(chóng)都應該遵守這項協(xié)議。
  python
 ?。▉?lái)自于百度百科):Python由荷蘭數學(xué)和計算機科學(xué)研究學(xué)會(huì )的吉多·范羅蘇姆于1990年代初設計,作為一門(mén)叫做ABC語(yǔ)言的替代品。Python提供了高效的高級數據結構,還能簡(jiǎn)單有效地面向對象編程。Python語(yǔ)法和動(dòng)態(tài)類(lèi)型,以及解釋型語(yǔ)言的本質(zhì),使它成為多數平臺上寫(xiě)腳本和快速開(kāi)發(fā)應用的編程語(yǔ)言, 隨著(zhù)版本的不斷更新和語(yǔ)言新功能的添加,逐漸被用于獨立的、大型項目的開(kāi)發(fā)。
  Python解釋器易于擴展,可以使用C語(yǔ)言或C++(或者其他可以通過(guò)C調用的語(yǔ)言)擴展新的功能和數據類(lèi)型。Python也可用于可定制化軟件中的擴展程序語(yǔ)言。Python豐富的標準庫,提供了適用于各個(gè)主要系統平臺的源碼或機器碼。
  2021年10月,語(yǔ)言流行指數的編譯器Tiobe將Python加冕為最受歡迎的編程語(yǔ)言,20年來(lái)首次將其置于Java、C和JavaScript之上。
  
  版本很多,本次使用python3
  python爬蟲(chóng)流程
  重要知識點(diǎn):
  獲取網(wǎng)頁(yè):requests、urllib、selenium
  解析網(wǎng)頁(yè):re正則表達式、BeautifulSoup、lxml
  存儲數據:存入txt、csv、存入mysql、redis、mongodb等
  框架:scrapy
  python 安裝
  使用Anaconda科學(xué)計算環(huán)境下載python
  安裝步驟 自行搜索百度,有很多,其實(shí)就是下一步下一步。使用pip安裝第三方庫或者使用Anaconda安裝第三方庫。
  
  編輯器:Pycharm
  如果你使用Python安裝包下載的python,推薦使用pycharm編輯器。下載免費版即可,官網(wǎng)好像被墻了。
  python之初嘗試
  python之爬蟲(chóng)初嘗試

c爬蟲(chóng)抓取網(wǎng)頁(yè)數據,比如百度全部關(guān)鍵詞爬蟲(chóng)。

網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 116 次瀏覽 ? 2022-08-05 14:05 ? 來(lái)自相關(guān)話(huà)題

  c爬蟲(chóng)抓取網(wǎng)頁(yè)數據,比如百度全部關(guān)鍵詞爬蟲(chóng)。
  c爬蟲(chóng)抓取網(wǎng)頁(yè)數據,比如百度全部關(guān)鍵詞爬蟲(chóng)。update2:20190913又看了一下,問(wèn)題中是純元數據。本身元數據沒(méi)有地域歸屬。這樣設置,useragent提供的信息僅限于ip和mac地址,而你能爬取的并不是這些信息。你需要axios+request來(lái)注冊scrapy,才能爬取以外的信息。以下為20190710補充:github上有提供examples:examples|scrapy學(xué)習。
  
  nlp方面,有一些國內論壇可以去學(xué)習。比如,通過(guò)python的poc文本識別正則表達式(抓取百度網(wǎng)頁(yè)上的文本信息,并翻譯英文,但非微信的文章信息)。
  如果你是零基礎的話(huà),推薦去csdn看看一個(gè)和你問(wèn)題有相似需求的人在使用什么框架和數據庫。web的話(huà),爬蟲(chóng)爬取評論數據用前端selenium。找相關(guān)的網(wǎng)站翻譯一下。如果可以看懂的話(huà)可以試著(zhù)寫(xiě)一個(gè)爬蟲(chóng)這樣。我目前是這么干的,具體不太懂。感覺(jué)時(shí)間比較緊,
  
  回答你的問(wèn)題首先要說(shuō)明的是,市面上比較多,國內的,國外的,mongodb等等很多,我只知道其中的一款,如果你想學(xué)習爬蟲(chóng)的話(huà),建議去學(xué)習一下,因為爬蟲(chóng)要對各種兼容性進(jìn)行分析,可能你需要寫(xiě)幾個(gè)框架,從最開(kāi)始的caffe到其他的,從此要自己寫(xiě)框架,初學(xué)的話(huà),這些框架你可以選擇一個(gè),其實(shí)安卓,ios都可以搭建自己的網(wǎng)站,反正不都是web嗎,所以你也可以去學(xué)習一下。
  并不是不會(huì ),是因為沒(méi)經(jīng)歷過(guò),作為初學(xué)者,建議還是先學(xué)一些框架,比如requests+xpath+beautifulsoup4(因為本人java基礎不是很好,所以選擇了前三個(gè),做練習可以選擇其他的)lxmlpyquery等等或者直接學(xué)一下flaskpyramid都可以。自己先去學(xué)一下其他的,然后了解一下api,通過(guò)各種api寫(xiě)一個(gè)網(wǎng)站,網(wǎng)站出來(lái)以后在選擇一個(gè)框架,這樣一來(lái),一切都會(huì )水到渠成。 查看全部

  c爬蟲(chóng)抓取網(wǎng)頁(yè)數據,比如百度全部關(guān)鍵詞爬蟲(chóng)。
  c爬蟲(chóng)抓取網(wǎng)頁(yè)數據,比如百度全部關(guān)鍵詞爬蟲(chóng)。update2:20190913又看了一下,問(wèn)題中是純元數據。本身元數據沒(méi)有地域歸屬。這樣設置,useragent提供的信息僅限于ip和mac地址,而你能爬取的并不是這些信息。你需要axios+request來(lái)注冊scrapy,才能爬取以外的信息。以下為20190710補充:github上有提供examples:examples|scrapy學(xué)習。
  
  nlp方面,有一些國內論壇可以去學(xué)習。比如,通過(guò)python的poc文本識別正則表達式(抓取百度網(wǎng)頁(yè)上的文本信息,并翻譯英文,但非微信的文章信息)。
  如果你是零基礎的話(huà),推薦去csdn看看一個(gè)和你問(wèn)題有相似需求的人在使用什么框架和數據庫。web的話(huà),爬蟲(chóng)爬取評論數據用前端selenium。找相關(guān)的網(wǎng)站翻譯一下。如果可以看懂的話(huà)可以試著(zhù)寫(xiě)一個(gè)爬蟲(chóng)這樣。我目前是這么干的,具體不太懂。感覺(jué)時(shí)間比較緊,
  
  回答你的問(wèn)題首先要說(shuō)明的是,市面上比較多,國內的,國外的,mongodb等等很多,我只知道其中的一款,如果你想學(xué)習爬蟲(chóng)的話(huà),建議去學(xué)習一下,因為爬蟲(chóng)要對各種兼容性進(jìn)行分析,可能你需要寫(xiě)幾個(gè)框架,從最開(kāi)始的caffe到其他的,從此要自己寫(xiě)框架,初學(xué)的話(huà),這些框架你可以選擇一個(gè),其實(shí)安卓,ios都可以搭建自己的網(wǎng)站,反正不都是web嗎,所以你也可以去學(xué)習一下。
  并不是不會(huì ),是因為沒(méi)經(jīng)歷過(guò),作為初學(xué)者,建議還是先學(xué)一些框架,比如requests+xpath+beautifulsoup4(因為本人java基礎不是很好,所以選擇了前三個(gè),做練習可以選擇其他的)lxmlpyquery等等或者直接學(xué)一下flaskpyramid都可以。自己先去學(xué)一下其他的,然后了解一下api,通過(guò)各種api寫(xiě)一個(gè)網(wǎng)站,網(wǎng)站出來(lái)以后在選擇一個(gè)框架,這樣一來(lái),一切都會(huì )水到渠成。

c爬蟲(chóng)抓取網(wǎng)頁(yè)數據更新的步驟是什么?怎么做

網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 294 次瀏覽 ? 2022-06-29 07:02 ? 來(lái)自相關(guān)話(huà)題

  c爬蟲(chóng)抓取網(wǎng)頁(yè)數據更新的步驟是什么?怎么做
  c爬蟲(chóng)抓取網(wǎng)頁(yè)數據更新的步驟:1.首先是獲取目標網(wǎng)頁(yè)的數據的方法,即獲取這個(gè)網(wǎng)頁(yè)所需要的數據。2.再是打包成數據包,下載到本地。然后對下載下來(lái)的數據做分析計算。有了本地的數據包,才能通過(guò)腳本更新網(wǎng)頁(yè)。3.網(wǎng)頁(yè)的更新即是用人工手動(dòng)的方式取得網(wǎng)頁(yè)最新的數據。這個(gè)過(guò)程需要使用抓包工具。4.http請求的代碼以https格式寫(xiě)在代碼最后。5.有人會(huì )問(wèn),這個(gè)代碼在哪里?運行代碼的時(shí)候,會(huì )用到瀏覽器開(kāi)發(fā)者工具。
  做爬蟲(chóng)的時(shí)候經(jīng)常會(huì )用到一些爬蟲(chóng)工具,
  
  可以使用多線(xiàn)程抓取,
  我個(gè)人認為,
  有個(gè)叫說(shuō)手機app的那哥們,整天干這個(gè)。
  
  曾經(jīng)做過(guò)一段android全開(kāi)源爬蟲(chóng),可以爬lbs相關(guān),更新比較及時(shí),速度可以達到1000+,現在想想那是多年前的事了。
  如果只爬公開(kāi)數據(包括大數據),可以通過(guò)反爬蟲(chóng)機制。在androidapi409范圍之內,比如:大商家之間的投票、大的賽事、大型論壇。在recaptcha加密機制之內,拿到中間地址。然后:翻墻找數據。(外國網(wǎng)站監控比較牛逼)在上一條的基礎上,自己編寫(xiě)getheader或者cookie對爬蟲(chóng),這個(gè)可以crawl,不過(guò)有點(diǎn)坑。
  在自己程序中使用第三方爬蟲(chóng),會(huì )和代理廣告相關(guān),自己肯定清楚相關(guān)的東西?;蛘遖gentdetector來(lái)監控哪個(gè)瀏覽器加速。有實(shí)力做爬蟲(chóng)網(wǎng)站比如一些專(zhuān)門(mén)做分析數據爬蟲(chóng)之類(lèi)的東西,就是收費的東西,多爬一些數據吧。 查看全部

  c爬蟲(chóng)抓取網(wǎng)頁(yè)數據更新的步驟是什么?怎么做
  c爬蟲(chóng)抓取網(wǎng)頁(yè)數據更新的步驟:1.首先是獲取目標網(wǎng)頁(yè)的數據的方法,即獲取這個(gè)網(wǎng)頁(yè)所需要的數據。2.再是打包成數據包,下載到本地。然后對下載下來(lái)的數據做分析計算。有了本地的數據包,才能通過(guò)腳本更新網(wǎng)頁(yè)。3.網(wǎng)頁(yè)的更新即是用人工手動(dòng)的方式取得網(wǎng)頁(yè)最新的數據。這個(gè)過(guò)程需要使用抓包工具。4.http請求的代碼以https格式寫(xiě)在代碼最后。5.有人會(huì )問(wèn),這個(gè)代碼在哪里?運行代碼的時(shí)候,會(huì )用到瀏覽器開(kāi)發(fā)者工具。
  做爬蟲(chóng)的時(shí)候經(jīng)常會(huì )用到一些爬蟲(chóng)工具,
  
  可以使用多線(xiàn)程抓取,
  我個(gè)人認為,
  有個(gè)叫說(shuō)手機app的那哥們,整天干這個(gè)。
  
  曾經(jīng)做過(guò)一段android全開(kāi)源爬蟲(chóng),可以爬lbs相關(guān),更新比較及時(shí),速度可以達到1000+,現在想想那是多年前的事了。
  如果只爬公開(kāi)數據(包括大數據),可以通過(guò)反爬蟲(chóng)機制。在androidapi409范圍之內,比如:大商家之間的投票、大的賽事、大型論壇。在recaptcha加密機制之內,拿到中間地址。然后:翻墻找數據。(外國網(wǎng)站監控比較牛逼)在上一條的基礎上,自己編寫(xiě)getheader或者cookie對爬蟲(chóng),這個(gè)可以crawl,不過(guò)有點(diǎn)坑。
  在自己程序中使用第三方爬蟲(chóng),會(huì )和代理廣告相關(guān),自己肯定清楚相關(guān)的東西?;蛘遖gentdetector來(lái)監控哪個(gè)瀏覽器加速。有實(shí)力做爬蟲(chóng)網(wǎng)站比如一些專(zhuān)門(mén)做分析數據爬蟲(chóng)之類(lèi)的東西,就是收費的東西,多爬一些數據吧。

數據分析|爬蟲(chóng)抓取東方財富網(wǎng)股吧帖子

網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 86 次瀏覽 ? 2022-06-24 23:39 ? 來(lái)自相關(guān)話(huà)題

  數據分析|爬蟲(chóng)抓取東方財富網(wǎng)股吧帖子
  1前言
  量化交易策略的研究主要涵蓋了微觀(guān)和宏觀(guān)這兩個(gè)方面,微觀(guān)方面更多地是從市場(chǎng)價(jià)格和成交持倉這些基礎信息為研究對象,通過(guò)算法計算出技術(shù)指標,再從技術(shù)指標的變化上構建交易模型。宏觀(guān)方面則是基于更多的市場(chǎng)資訊開(kāi)發(fā)交易模型,比如從CPI、PPI、貨幣發(fā)行量這些宏觀(guān)經(jīng)濟指標為研究對象構建交易模型;或者是利用數據挖掘技術(shù)從新聞事件中挖掘出可能造成市場(chǎng)異常波動(dòng)的事件,從而獲得交易的時(shí)機。
  我們知道知名股票論壇有點(diǎn)金投資家園、股天下、東方財富網(wǎng)股吧、和訊股吧、創(chuàng )幻論壇、MACD股市等等,筆者用的比較多的是東方財富網(wǎng)股吧。在課程《構建基于股票的量化交易系統》中我們以爬取東方財富網(wǎng)行業(yè)板塊當日的行情數據為案例,介紹了網(wǎng)絡(luò )爬蟲(chóng)的原理和方法,本節我們再介紹下如何爬取東方財富網(wǎng)股吧帖子的內容。
  2
  解析股吧帖子URL
  首先通過(guò)瀏覽器訪(fǎng)問(wèn)偉星新材的股吧,查看該網(wǎng)頁(yè)的URL為:
  ,002372.html,網(wǎng)頁(yè)內容如下圖所示:
  當我們點(diǎn)擊第2頁(yè)、第3頁(yè)后,查看下當前的URL分別為:
  http://guba.eastmoney.com/list,002372_2.htmlhttp://guba.eastmoney.com/list,002372_3.html
  因此得到了個(gè)股股吧URL的規律為:
  , 002372_%d.html形式表示,
  其中的規律比較直白,%d為論壇第幾頁(yè),不過(guò)這個(gè)形式是按評論時(shí)間排列的網(wǎng)址,如果按發(fā)帖時(shí)間的排列網(wǎng)址是:
  ,002372,f_%d.html。
  股吧的帖子由兩部分組成,一部分為“財經(jīng)評論”或“東方財富網(wǎng)”發(fā)布的公告或官方消息,另一部分為散戶(hù)發(fā)布的討論帖子,如下圖所示:
  
  前者的帖子URL為:
  ,cjpl,902659513.html,
  后者的帖子URL為:
  ,002372,902629178.html
  兩者的URL都可在當前該股股吧HTML文件內容中搜尋到,如下所示:
  
  因此“財經(jīng)評論”、“東方財富網(wǎng)”或者散戶(hù)發(fā)布的帖子,主要的特征為/news,在實(shí)現上我們可以先爬取到股吧HTML內容,然后通過(guò)正則表達式來(lái)篩選得到帖子的URL。
  關(guān)于讀取網(wǎng)頁(yè)HTML內容的關(guān)鍵代碼我們已經(jīng)在課程《爬蟲(chóng)方式獲取行業(yè)板塊數據》一節中具體介紹過(guò)。需要注意的是Python2的urllib、urllib2和urlparse,已經(jīng)在Python3中全部被整合到了urllib中,其中Python2的urllib和urllib2中的內容整合為urllib.request模塊,urlparse整合為urllib.parse模塊。
  獲取到HTML代碼部分內容如下:
  正則表達式篩選帖子URL,采用了pile和re.findall,實(shí)現代碼如下:
  其中正則表達式的\S+表示匹配多次非空白字符,然后使用findall函數找到匹配的所有字符串,并把它們作為一個(gè)列表返回。
  然后是使用urljoin方法把整個(gè)url拼接好用于爬取單個(gè)帖子的標題內容,關(guān)鍵代碼如下所示:
  
  3創(chuàng )建爬蟲(chóng)URL隊列
  接下來(lái)我們把所有需要爬取的股吧頁(yè)以及每頁(yè)中的帖子的URL以隊列的方式進(jìn)行管理。Python中存儲序列的類(lèi)型有list、tuple、dict和set,它們之間的區別和特點(diǎn)簡(jiǎn)單的說(shuō):tuple不能修改其中的元素;set是無(wú)序集合,會(huì )自動(dòng)去除重復元素;list是有序的集合;dict是一組key和value的組合。此次我們選擇list作為隊列的存儲類(lèi)型。
  創(chuàng )建target_url_manager類(lèi),該類(lèi)包含以下幾個(gè)方法:
  創(chuàng )建隊列形式如下所示:
  完整代碼可見(jiàn)課程《加推篇!爬蟲(chóng)抓取東方財富網(wǎng)股吧帖子》。
  4
  解析股吧帖子內容
  單個(gè)帖子爬取的內容包括三部分,帖子發(fā)表時(shí)間、作者及帖子標題,如下所示:
  
  我們可以通過(guò)正則表達式進(jìn)行提取,其中在組合正則表達式時(shí),需要考慮到HTML代碼中是否有重復的匹配關(guān)鍵字。作者和帖子標題正則代碼如下,mainbody、zwcontentmain這些關(guān)鍵字在文本中僅出現一次,匹配程度較高。由于網(wǎng)站HTML代碼的改動(dòng),表達式需要經(jīng)常調整。
  關(guān)鍵代碼如下所示:
  com_cont = re.compile(r'.*?zwconttbn.*?(.*?).*?social clearfix',re.DOTALL)
  發(fā)布時(shí)間正則代碼如下,分兩步逐漸明晰的去提取時(shí)間,由于search是掃描字符串找到這個(gè)RE 匹配的位置,因此增加group()返回匹配字符串。
  pub_elems?=?re.search('.*?',html_cont2).group()#發(fā)表于 2020-02-11 09:54:48 東方財富Android版<br />pub_time?=?re.search('\d\d\d\d-\d\d-\d\d',pub_elems).group()#2020-02-06
  <br />
  另外,論壇帖子與當前的股價(jià)走勢有時(shí)間聯(lián)系,太早的帖子對現在無(wú)參考作用,因此需要刪選近期的帖子。我們可以對時(shí)間進(jìn)行判斷,只有一個(gè)月之內發(fā)布的帖子才進(jìn)行爬取并存儲。獲取今天的日期使用datetime.now().date(),然后與爬取的帖子時(shí)間日期比較,timedelta可在日期上做天days時(shí)間計算,但需要將時(shí)間轉換為時(shí)間形式。
  實(shí)現部分關(guān)鍵代碼如下所示:
  
  完成了單個(gè)帖子的內容爬取之后,我們采用迭代方法把全部帖子爬取一遍。我們通過(guò)兩層迭代方法,第一層為頁(yè)數,第二層為一頁(yè)的股吧帖子數,將每個(gè)帖子的URL存儲在列表中,通過(guò)迭代的方式一個(gè)個(gè)爬取帖子的內容。<br />
  實(shí)現部分關(guān)鍵代碼如下:
  
  當我們爬取時(shí)發(fā)現某個(gè)帖子不存在,出現爬取信息異常時(shí),可使用try...except...進(jìn)行異常處理。
  最終爬取到的帖子內容如下圖所示:
  完整代碼可見(jiàn)課程《加推篇!爬蟲(chóng)抓取東方財富網(wǎng)股吧帖子》。
  5
  帖子內容存儲為txt
  我們可以將爬取信息寫(xiě)到txt文件中,打開(kāi)方式的代碼實(shí)現如下所示,a+為在文本尾部追加寫(xiě)入,而不是覆蓋寫(xiě)入,codecs.open這個(gè)方法可以指定編碼打開(kāi)文件,而使用Python內置的open打開(kāi)文件只能寫(xiě)入str類(lèi)型。
  f=codecs.open(name,'a+','utf-8')
  此處我們創(chuàng )建一個(gè)output_txt類(lèi),該類(lèi)中我們會(huì )分別實(shí)現打開(kāi)文件、寫(xiě)文件和關(guān)閉文件這幾個(gè)方法。代碼如下所示:
  
  接下來(lái)就可以一邊爬取帖子內容,一邊把內容寫(xiě)入到txt文件中。實(shí)現關(guān)鍵代碼如下所示:
  
  寫(xiě)入txt文件的效果如下所示:
  
  我們也可以把爬取信息寫(xiě)到GUI工具中,我們知道在wxPython中文本框為wx.TextCtrl類(lèi),該類(lèi)可以顯示和編輯文本,這樣一來(lái)就可以把帖子信息寫(xiě)到GUI工具中。顯示效果如下所示:
  
  6
  總結
  本小節我們通過(guò)爬蟲(chóng)方式得到股吧帖子中的各種內容,那么這些內容對于我們來(lái)說(shuō)有什么意義嗎?我們發(fā)現總有些人一直在唱空,制造恐慌的情緒,不過(guò)我們可以通過(guò)分類(lèi)分析下這些空頭評論和股價(jià)的漲跌有沒(méi)有什么關(guān)聯(lián),是不是有寫(xiě)ID是專(zhuān)門(mén)來(lái)唱空的呢?感興趣的朋友們可以試試!比如用詞云這種方式,如下所示:
  
   查看全部

  數據分析|爬蟲(chóng)抓取東方財富網(wǎng)股吧帖子
  1前言
  量化交易策略的研究主要涵蓋了微觀(guān)和宏觀(guān)這兩個(gè)方面,微觀(guān)方面更多地是從市場(chǎng)價(jià)格和成交持倉這些基礎信息為研究對象,通過(guò)算法計算出技術(shù)指標,再從技術(shù)指標的變化上構建交易模型。宏觀(guān)方面則是基于更多的市場(chǎng)資訊開(kāi)發(fā)交易模型,比如從CPI、PPI、貨幣發(fā)行量這些宏觀(guān)經(jīng)濟指標為研究對象構建交易模型;或者是利用數據挖掘技術(shù)從新聞事件中挖掘出可能造成市場(chǎng)異常波動(dòng)的事件,從而獲得交易的時(shí)機。
  我們知道知名股票論壇有點(diǎn)金投資家園、股天下、東方財富網(wǎng)股吧、和訊股吧、創(chuàng )幻論壇、MACD股市等等,筆者用的比較多的是東方財富網(wǎng)股吧。在課程《構建基于股票的量化交易系統》中我們以爬取東方財富網(wǎng)行業(yè)板塊當日的行情數據為案例,介紹了網(wǎng)絡(luò )爬蟲(chóng)的原理和方法,本節我們再介紹下如何爬取東方財富網(wǎng)股吧帖子的內容。
  2
  解析股吧帖子URL
  首先通過(guò)瀏覽器訪(fǎng)問(wèn)偉星新材的股吧,查看該網(wǎng)頁(yè)的URL為:
  ,002372.html,網(wǎng)頁(yè)內容如下圖所示:
  當我們點(diǎn)擊第2頁(yè)、第3頁(yè)后,查看下當前的URL分別為:
  http://guba.eastmoney.com/list,002372_2.htmlhttp://guba.eastmoney.com/list,002372_3.html
  因此得到了個(gè)股股吧URL的規律為:
  , 002372_%d.html形式表示,
  其中的規律比較直白,%d為論壇第幾頁(yè),不過(guò)這個(gè)形式是按評論時(shí)間排列的網(wǎng)址,如果按發(fā)帖時(shí)間的排列網(wǎng)址是:
  ,002372,f_%d.html。
  股吧的帖子由兩部分組成,一部分為“財經(jīng)評論”或“東方財富網(wǎng)”發(fā)布的公告或官方消息,另一部分為散戶(hù)發(fā)布的討論帖子,如下圖所示:
  
  前者的帖子URL為:
  ,cjpl,902659513.html,
  后者的帖子URL為:
  ,002372,902629178.html
  兩者的URL都可在當前該股股吧HTML文件內容中搜尋到,如下所示:
  
  因此“財經(jīng)評論”、“東方財富網(wǎng)”或者散戶(hù)發(fā)布的帖子,主要的特征為/news,在實(shí)現上我們可以先爬取到股吧HTML內容,然后通過(guò)正則表達式來(lái)篩選得到帖子的URL。
  關(guān)于讀取網(wǎng)頁(yè)HTML內容的關(guān)鍵代碼我們已經(jīng)在課程《爬蟲(chóng)方式獲取行業(yè)板塊數據》一節中具體介紹過(guò)。需要注意的是Python2的urllib、urllib2和urlparse,已經(jīng)在Python3中全部被整合到了urllib中,其中Python2的urllib和urllib2中的內容整合為urllib.request模塊,urlparse整合為urllib.parse模塊。
  獲取到HTML代碼部分內容如下:
  正則表達式篩選帖子URL,采用了pile和re.findall,實(shí)現代碼如下:
  其中正則表達式的\S+表示匹配多次非空白字符,然后使用findall函數找到匹配的所有字符串,并把它們作為一個(gè)列表返回。
  然后是使用urljoin方法把整個(gè)url拼接好用于爬取單個(gè)帖子的標題內容,關(guān)鍵代碼如下所示:
  
  3創(chuàng )建爬蟲(chóng)URL隊列
  接下來(lái)我們把所有需要爬取的股吧頁(yè)以及每頁(yè)中的帖子的URL以隊列的方式進(jìn)行管理。Python中存儲序列的類(lèi)型有list、tuple、dict和set,它們之間的區別和特點(diǎn)簡(jiǎn)單的說(shuō):tuple不能修改其中的元素;set是無(wú)序集合,會(huì )自動(dòng)去除重復元素;list是有序的集合;dict是一組key和value的組合。此次我們選擇list作為隊列的存儲類(lèi)型。
  創(chuàng )建target_url_manager類(lèi),該類(lèi)包含以下幾個(gè)方法:
  創(chuàng )建隊列形式如下所示:
  完整代碼可見(jiàn)課程《加推篇!爬蟲(chóng)抓取東方財富網(wǎng)股吧帖子》。
  4
  解析股吧帖子內容
  單個(gè)帖子爬取的內容包括三部分,帖子發(fā)表時(shí)間、作者及帖子標題,如下所示:
  
  我們可以通過(guò)正則表達式進(jìn)行提取,其中在組合正則表達式時(shí),需要考慮到HTML代碼中是否有重復的匹配關(guān)鍵字。作者和帖子標題正則代碼如下,mainbody、zwcontentmain這些關(guān)鍵字在文本中僅出現一次,匹配程度較高。由于網(wǎng)站HTML代碼的改動(dòng),表達式需要經(jīng)常調整。
  關(guān)鍵代碼如下所示:
  com_cont = re.compile(r'.*?zwconttbn.*?(.*?).*?social clearfix',re.DOTALL)
  發(fā)布時(shí)間正則代碼如下,分兩步逐漸明晰的去提取時(shí)間,由于search是掃描字符串找到這個(gè)RE 匹配的位置,因此增加group()返回匹配字符串。
  pub_elems?=?re.search('.*?',html_cont2).group()#發(fā)表于 2020-02-11 09:54:48 東方財富Android版<br />pub_time?=?re.search('\d\d\d\d-\d\d-\d\d',pub_elems).group()#2020-02-06
  <br />
  另外,論壇帖子與當前的股價(jià)走勢有時(shí)間聯(lián)系,太早的帖子對現在無(wú)參考作用,因此需要刪選近期的帖子。我們可以對時(shí)間進(jìn)行判斷,只有一個(gè)月之內發(fā)布的帖子才進(jìn)行爬取并存儲。獲取今天的日期使用datetime.now().date(),然后與爬取的帖子時(shí)間日期比較,timedelta可在日期上做天days時(shí)間計算,但需要將時(shí)間轉換為時(shí)間形式。
  實(shí)現部分關(guān)鍵代碼如下所示:
  
  完成了單個(gè)帖子的內容爬取之后,我們采用迭代方法把全部帖子爬取一遍。我們通過(guò)兩層迭代方法,第一層為頁(yè)數,第二層為一頁(yè)的股吧帖子數,將每個(gè)帖子的URL存儲在列表中,通過(guò)迭代的方式一個(gè)個(gè)爬取帖子的內容。<br />
  實(shí)現部分關(guān)鍵代碼如下:
  
  當我們爬取時(shí)發(fā)現某個(gè)帖子不存在,出現爬取信息異常時(shí),可使用try...except...進(jìn)行異常處理。
  最終爬取到的帖子內容如下圖所示:
  完整代碼可見(jiàn)課程《加推篇!爬蟲(chóng)抓取東方財富網(wǎng)股吧帖子》。
  5
  帖子內容存儲為txt
  我們可以將爬取信息寫(xiě)到txt文件中,打開(kāi)方式的代碼實(shí)現如下所示,a+為在文本尾部追加寫(xiě)入,而不是覆蓋寫(xiě)入,codecs.open這個(gè)方法可以指定編碼打開(kāi)文件,而使用Python內置的open打開(kāi)文件只能寫(xiě)入str類(lèi)型。
  f=codecs.open(name,'a+','utf-8')
  此處我們創(chuàng )建一個(gè)output_txt類(lèi),該類(lèi)中我們會(huì )分別實(shí)現打開(kāi)文件、寫(xiě)文件和關(guān)閉文件這幾個(gè)方法。代碼如下所示:
  
  接下來(lái)就可以一邊爬取帖子內容,一邊把內容寫(xiě)入到txt文件中。實(shí)現關(guān)鍵代碼如下所示:
  
  寫(xiě)入txt文件的效果如下所示:
  
  我們也可以把爬取信息寫(xiě)到GUI工具中,我們知道在wxPython中文本框為wx.TextCtrl類(lèi),該類(lèi)可以顯示和編輯文本,這樣一來(lái)就可以把帖子信息寫(xiě)到GUI工具中。顯示效果如下所示:
  
  6
  總結
  本小節我們通過(guò)爬蟲(chóng)方式得到股吧帖子中的各種內容,那么這些內容對于我們來(lái)說(shuō)有什么意義嗎?我們發(fā)現總有些人一直在唱空,制造恐慌的情緒,不過(guò)我們可以通過(guò)分類(lèi)分析下這些空頭評論和股價(jià)的漲跌有沒(méi)有什么關(guān)聯(lián),是不是有寫(xiě)ID是專(zhuān)門(mén)來(lái)唱空的呢?感興趣的朋友們可以試試!比如用詞云這種方式,如下所示:
  
  

數據抓取學(xué)習3|web scraper爬蟲(chóng)使用方法—進(jìn)階篇

網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 788 次瀏覽 ? 2022-06-20 04:44 ? 來(lái)自相關(guān)話(huà)題

  數據抓取學(xué)習3|web scraper爬蟲(chóng)使用方法—進(jìn)階篇
  上一篇文章講了web scraper的基礎操作,今天跟大家分享web scraper爬蟲(chóng)的一些進(jìn)階使用方法,學(xué)會(huì )了它,大概80%的網(wǎng)站元素都可以抓取了。
  它的步驟都是:
  創(chuàng )建一個(gè)站點(diǎn)Create sitemap—新增選擇器Add new selector—點(diǎn)擊Scrape抓取,不同的是選擇器中Type的選擇。
  在進(jìn)階篇中,主要講的就是這幾個(gè)Type的使用。
  
  目錄
  頁(yè)內提取多個(gè)字段Type=Element
  選擇樹(shù)Selector graph
  選擇快捷鍵Enable key
  不規則分頁(yè)Type=Element scroll down/Element click
  二三級頁(yè)面元素采集Type=Type=Link
  抓取表單Type=Table
  Delay的設置
  1.頁(yè)內提取多個(gè)字段(Type=Element)
  
  如上圖,如果想要同時(shí)抓取這個(gè)回答中的標題、點(diǎn)贊人數、回答的正文,就要用到Element這個(gè)選擇器,它表示的是元素集,各個(gè)元素組成的一個(gè)元素集。比如上圖中的回答中的標題、點(diǎn)贊人數、回答的正文、評論數就在一個(gè)元素集里。
  具體的操作步驟如下:
  新建一個(gè)站點(diǎn)地圖Create sitemap—新建選擇器Add new selector—新建子選擇器—抓取
  
  點(diǎn)擊Select選取元素,這個(gè)是元素集,所以選擇時(shí)要把整個(gè)元素集都框選中。具體步驟如下圖,在基礎篇中講過(guò),在選擇時(shí)如果是type(1),說(shuō)明這個(gè)頁(yè)面的元素沒(méi)有選完,這里再選擇下一個(gè)元素集就可以了。
  
  在新建選擇器時(shí)選擇Element這個(gè)選擇器,勾選Multiple。
  建好之后,點(diǎn)擊這個(gè)選擇器,進(jìn)入到選擇子器頁(yè)面,然后再新建子選擇器,選擇需要抓取的頁(yè)面元素。比如:標題、正文、點(diǎn)贊數、評論數。
  
  
  子元素:標題、正文、點(diǎn)贊數、評論數這些都是文本,Type選擇Text就可以了。
  2.選擇樹(shù)Selector graph
  在Sitemap的下拉菜單中有一個(gè)Selector graph的選擇,通過(guò)它可以查看選擇器之間的邏輯關(guān)系。
  
  這個(gè)例子中元素集與元素之間的關(guān)系。
  
  3.選擇快捷鍵(Enable key)
  用鼠標選擇頁(yè)面元素,有時(shí)候會(huì )出現選擇錯誤或者是一點(diǎn)擊就跳到的另外一個(gè)頁(yè)面,這時(shí)候可以利用Enable key這個(gè)快捷操作去選取元素。
  勾選Enable key ,把鼠標懸停在你要選擇的元素上,待采集字段變綠后點(diǎn)擊鍵盤(pán)S鍵選擇。
  4.不規則分頁(yè)Type=Element scroll down/Element click
  像下圖中這種,需要鼠標向下滾動(dòng)和點(diǎn)擊“加載更多”,網(wǎng)頁(yè)才會(huì )加載出新的內容。
  這類(lèi)網(wǎng)站的元素,可以分別利用選擇器Type中的Element scroll down和Element click來(lái)進(jìn)行抓取。
  
  下面這個(gè)實(shí)例:收集IT桔子中金融類(lèi)公司的公司名,公司簡(jiǎn)介。
  這里需要鼠標點(diǎn)擊“加載更多”才會(huì )出現新的內容。
  新建一個(gè)站點(diǎn)地圖后,新增選擇器,在Type中選擇Element click,點(diǎn)擊Selector中的Select,選擇元素集。
  在Click selector點(diǎn)擊Select,選擇“加載更多”。
  Click type 中選擇Click more,因為這條類(lèi)目?jì)热莺芏?,需要點(diǎn)擊多次的“加載更多”,如果需要點(diǎn)擊一次的話(huà),選擇Click once就可以。
  Click element uniquenss選擇unique CSS Selector。
  勾選Multiple,注意在子選擇器中就不用勾選。
  這里加載可能會(huì )出現一點(diǎn)延時(shí),所以可以加一個(gè)1000ms的延時(shí)。
  
  然后再分別建立公司標題和公司簡(jiǎn)介的子選擇器,進(jìn)行抓取即可。
  
  5.二三級頁(yè)面元素采集Type=Link
  還是知乎的例子,如果還想要收集這個(gè)問(wèn)題的關(guān)注人數和瀏覽量,但這兩個(gè)數據在另外一個(gè)頁(yè)面,這里就需要用到選擇器中Type=Link的選項,它表示的是指向這個(gè)文本背后的鏈接。
  
  具體的操作步驟如下:
  在元素集的子選擇器中新建一個(gè)link的子選擇器。
  
  Type選擇Link,選中標題,這里會(huì )看到出現標題的鏈接。
  在link的下面再新建兩個(gè)選擇器,分別抓取關(guān)注和瀏覽量的數據。
  
  看下這個(gè)抓取的邏輯樹(shù),理解就更清晰了:
  
  6.抓取表單Type=Table
  利用Type=Table
  以抓取優(yōu)采云票余票信息為例子。
  網(wǎng)址鏈接:
  在選擇器中選擇Type=Table,Selector選擇整個(gè)表格。
  Header row selector,選擇表頭,這例子中選擇數據第一行為表頭,再修改表頭的名字,如果選擇第一行為表頭的話(huà),只能抓取出發(fā)地、目的地、余票數量三個(gè)元素,詳細的每日余票量抓取不了。
  修改表頭的標注
  Data rows selector中選擇所以抓取的數據項。
  7.Delay的設置
  在操作過(guò)程中,但選擇器多了之后,大家會(huì )看到很多Delay的設置,下面說(shuō)說(shuō)需要設置Delay的情況。
  點(diǎn)擊Scrape后,這里的Delay,它針對的是全局,所有鏈接發(fā)生變化的情況。
  
  點(diǎn)擊分頁(yè)、加載更多、滾動(dòng)下拉這類(lèi)頁(yè)面需要時(shí)間加載是,就設置delay,推薦2000ms。
  元素集中的子選擇器可以不設置delay。
  小結
  講解了web scraper的進(jìn)階操作后,是不是發(fā)現又有很多網(wǎng)站數據可以抓取了。
  進(jìn)階篇中主要的知識點(diǎn)有:
  1.根據抓取元素的不同情況,選擇不同的Type
  
  2.選擇樹(shù)Selector graph
  選擇器之間的邏輯關(guān)系。
  3.選擇快捷鍵Enable key
  4.Delay的設置
  頁(yè)面需要時(shí)間加載的情況設置Delay,元素集中的子選擇器可以不設 置。
  5.子選擇器中的Multiple不用勾選
  6.常見(jiàn)的問(wèn)題
  操作過(guò)程中會(huì )需要兩個(gè)常見(jiàn)問(wèn)題:
  思考題
  
  在知乎例子的這個(gè)抓取結果中,回答正文中,沒(méi)有把回答的全文抓取完。在網(wǎng)站上“閱讀全文”這四個(gè)字需要用鼠標點(diǎn)開(kāi),爬蟲(chóng)才能把全部回答抓取完,怎么設置這個(gè)選擇器呢?
  大家可以先思考,嘗試自己操作一下。
  公眾號回復“答案”,就可獲取具體的操作步驟。
  注:我學(xué)習課程為三節課的《人人都能學(xué)會(huì )的數據爬蟲(chóng)課》,此次僅為純粹的學(xué)習分享。
  搬運工的苦勞
  蘋(píng)果專(zhuān)用贊賞二維碼 查看全部

  數據抓取學(xué)習3|web scraper爬蟲(chóng)使用方法—進(jìn)階篇
  上一篇文章講了web scraper的基礎操作,今天跟大家分享web scraper爬蟲(chóng)的一些進(jìn)階使用方法,學(xué)會(huì )了它,大概80%的網(wǎng)站元素都可以抓取了。
  它的步驟都是:
  創(chuàng )建一個(gè)站點(diǎn)Create sitemap—新增選擇器Add new selector—點(diǎn)擊Scrape抓取,不同的是選擇器中Type的選擇。
  在進(jìn)階篇中,主要講的就是這幾個(gè)Type的使用。
  
  目錄
  頁(yè)內提取多個(gè)字段Type=Element
  選擇樹(shù)Selector graph
  選擇快捷鍵Enable key
  不規則分頁(yè)Type=Element scroll down/Element click
  二三級頁(yè)面元素采集Type=Type=Link
  抓取表單Type=Table
  Delay的設置
  1.頁(yè)內提取多個(gè)字段(Type=Element)
  
  如上圖,如果想要同時(shí)抓取這個(gè)回答中的標題、點(diǎn)贊人數、回答的正文,就要用到Element這個(gè)選擇器,它表示的是元素集,各個(gè)元素組成的一個(gè)元素集。比如上圖中的回答中的標題、點(diǎn)贊人數、回答的正文、評論數就在一個(gè)元素集里。
  具體的操作步驟如下:
  新建一個(gè)站點(diǎn)地圖Create sitemap—新建選擇器Add new selector—新建子選擇器—抓取
  
  點(diǎn)擊Select選取元素,這個(gè)是元素集,所以選擇時(shí)要把整個(gè)元素集都框選中。具體步驟如下圖,在基礎篇中講過(guò),在選擇時(shí)如果是type(1),說(shuō)明這個(gè)頁(yè)面的元素沒(méi)有選完,這里再選擇下一個(gè)元素集就可以了。
  
  在新建選擇器時(shí)選擇Element這個(gè)選擇器,勾選Multiple。
  建好之后,點(diǎn)擊這個(gè)選擇器,進(jìn)入到選擇子器頁(yè)面,然后再新建子選擇器,選擇需要抓取的頁(yè)面元素。比如:標題、正文、點(diǎn)贊數、評論數。
  
  
  子元素:標題、正文、點(diǎn)贊數、評論數這些都是文本,Type選擇Text就可以了。
  2.選擇樹(shù)Selector graph
  在Sitemap的下拉菜單中有一個(gè)Selector graph的選擇,通過(guò)它可以查看選擇器之間的邏輯關(guān)系。
  
  這個(gè)例子中元素集與元素之間的關(guān)系。
  
  3.選擇快捷鍵(Enable key)
  用鼠標選擇頁(yè)面元素,有時(shí)候會(huì )出現選擇錯誤或者是一點(diǎn)擊就跳到的另外一個(gè)頁(yè)面,這時(shí)候可以利用Enable key這個(gè)快捷操作去選取元素。
  勾選Enable key ,把鼠標懸停在你要選擇的元素上,待采集字段變綠后點(diǎn)擊鍵盤(pán)S鍵選擇。
  4.不規則分頁(yè)Type=Element scroll down/Element click
  像下圖中這種,需要鼠標向下滾動(dòng)和點(diǎn)擊“加載更多”,網(wǎng)頁(yè)才會(huì )加載出新的內容。
  這類(lèi)網(wǎng)站的元素,可以分別利用選擇器Type中的Element scroll down和Element click來(lái)進(jìn)行抓取。
  
  下面這個(gè)實(shí)例:收集IT桔子中金融類(lèi)公司的公司名,公司簡(jiǎn)介。
  這里需要鼠標點(diǎn)擊“加載更多”才會(huì )出現新的內容。
  新建一個(gè)站點(diǎn)地圖后,新增選擇器,在Type中選擇Element click,點(diǎn)擊Selector中的Select,選擇元素集。
  在Click selector點(diǎn)擊Select,選擇“加載更多”。
  Click type 中選擇Click more,因為這條類(lèi)目?jì)热莺芏?,需要點(diǎn)擊多次的“加載更多”,如果需要點(diǎn)擊一次的話(huà),選擇Click once就可以。
  Click element uniquenss選擇unique CSS Selector。
  勾選Multiple,注意在子選擇器中就不用勾選。
  這里加載可能會(huì )出現一點(diǎn)延時(shí),所以可以加一個(gè)1000ms的延時(shí)。
  
  然后再分別建立公司標題和公司簡(jiǎn)介的子選擇器,進(jìn)行抓取即可。
  
  5.二三級頁(yè)面元素采集Type=Link
  還是知乎的例子,如果還想要收集這個(gè)問(wèn)題的關(guān)注人數和瀏覽量,但這兩個(gè)數據在另外一個(gè)頁(yè)面,這里就需要用到選擇器中Type=Link的選項,它表示的是指向這個(gè)文本背后的鏈接。
  
  具體的操作步驟如下:
  在元素集的子選擇器中新建一個(gè)link的子選擇器。
  
  Type選擇Link,選中標題,這里會(huì )看到出現標題的鏈接。
  在link的下面再新建兩個(gè)選擇器,分別抓取關(guān)注和瀏覽量的數據。
  
  看下這個(gè)抓取的邏輯樹(shù),理解就更清晰了:
  
  6.抓取表單Type=Table
  利用Type=Table
  以抓取優(yōu)采云票余票信息為例子。
  網(wǎng)址鏈接:
  在選擇器中選擇Type=Table,Selector選擇整個(gè)表格。
  Header row selector,選擇表頭,這例子中選擇數據第一行為表頭,再修改表頭的名字,如果選擇第一行為表頭的話(huà),只能抓取出發(fā)地、目的地、余票數量三個(gè)元素,詳細的每日余票量抓取不了。
  修改表頭的標注
  Data rows selector中選擇所以抓取的數據項。
  7.Delay的設置
  在操作過(guò)程中,但選擇器多了之后,大家會(huì )看到很多Delay的設置,下面說(shuō)說(shuō)需要設置Delay的情況。
  點(diǎn)擊Scrape后,這里的Delay,它針對的是全局,所有鏈接發(fā)生變化的情況。
  
  點(diǎn)擊分頁(yè)、加載更多、滾動(dòng)下拉這類(lèi)頁(yè)面需要時(shí)間加載是,就設置delay,推薦2000ms。
  元素集中的子選擇器可以不設置delay。
  小結
  講解了web scraper的進(jìn)階操作后,是不是發(fā)現又有很多網(wǎng)站數據可以抓取了。
  進(jìn)階篇中主要的知識點(diǎn)有:
  1.根據抓取元素的不同情況,選擇不同的Type
  
  2.選擇樹(shù)Selector graph
  選擇器之間的邏輯關(guān)系。
  3.選擇快捷鍵Enable key
  4.Delay的設置
  頁(yè)面需要時(shí)間加載的情況設置Delay,元素集中的子選擇器可以不設 置。
  5.子選擇器中的Multiple不用勾選
  6.常見(jiàn)的問(wèn)題
  操作過(guò)程中會(huì )需要兩個(gè)常見(jiàn)問(wèn)題:
  思考題
  
  在知乎例子的這個(gè)抓取結果中,回答正文中,沒(méi)有把回答的全文抓取完。在網(wǎng)站上“閱讀全文”這四個(gè)字需要用鼠標點(diǎn)開(kāi),爬蟲(chóng)才能把全部回答抓取完,怎么設置這個(gè)選擇器呢?
  大家可以先思考,嘗試自己操作一下。
  公眾號回復“答案”,就可獲取具體的操作步驟。
  注:我學(xué)習課程為三節課的《人人都能學(xué)會(huì )的數據爬蟲(chóng)課》,此次僅為純粹的學(xué)習分享。
  搬運工的苦勞
  蘋(píng)果專(zhuān)用贊賞二維碼

Python爬蟲(chóng)之三:抓取貓眼電影TOP100

網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 112 次瀏覽 ? 2022-06-18 02:42 ? 來(lái)自相關(guān)話(huà)題

  Python爬蟲(chóng)之三:抓取貓眼電影TOP100
  今天我要利用requests庫和正則表達式抓取貓眼電影Top100榜單。
  運行平臺:Windows
  Python版本:Python3.6
  IDE:Sublime Text
  其他工具:Chrome瀏覽器
  1. 抓取單頁(yè)內容
  瀏覽器打開(kāi)貓眼電影首頁(yè),點(diǎn)擊“榜單”,然后再點(diǎn)擊"TOP100榜",就能看到想要的了。
  接下來(lái)通過(guò)代碼來(lái)獲取網(wǎng)頁(yè)的HTML代碼。
  運行結果如下:
  2. 正則表達式提取有用信息
  在上圖中,已經(jīng)標注出我們將要提取的內容,下面用代碼實(shí)現:
  運行結果如下:
  3. 保存信息
  獲取電影信息之后,要保存起來(lái)留用。要保存的有文本信息和電影封面。
  下面為保存結果:
  
  4.下載TOP100所有電影信息
  通過(guò)點(diǎn)擊標簽頁(yè)發(fā)現只是URL變化了:
  修改main函數以動(dòng)態(tài)改變URL:
  到此我們已經(jīng)將TOP100的電影信息和封面全部得到了。
  5.多線(xiàn)程抓取
  此次抓取的數據不算多,但是為了學(xué)習,使用多進(jìn)程進(jìn)行抓取,以應對以后大量的數據抓取。
  
  下面為普通抓取和多進(jìn)程抓取的時(shí)間對比:
  以下為完整代碼: 查看全部

  Python爬蟲(chóng)之三:抓取貓眼電影TOP100
  今天我要利用requests庫和正則表達式抓取貓眼電影Top100榜單。
  運行平臺:Windows
  Python版本:Python3.6
  IDE:Sublime Text
  其他工具:Chrome瀏覽器
  1. 抓取單頁(yè)內容
  瀏覽器打開(kāi)貓眼電影首頁(yè),點(diǎn)擊“榜單”,然后再點(diǎn)擊"TOP100榜",就能看到想要的了。
  接下來(lái)通過(guò)代碼來(lái)獲取網(wǎng)頁(yè)的HTML代碼。
  運行結果如下:
  2. 正則表達式提取有用信息
  在上圖中,已經(jīng)標注出我們將要提取的內容,下面用代碼實(shí)現:
  運行結果如下:
  3. 保存信息
  獲取電影信息之后,要保存起來(lái)留用。要保存的有文本信息和電影封面。
  下面為保存結果:
  
  4.下載TOP100所有電影信息
  通過(guò)點(diǎn)擊標簽頁(yè)發(fā)現只是URL變化了:
  修改main函數以動(dòng)態(tài)改變URL:
  到此我們已經(jīng)將TOP100的電影信息和封面全部得到了。
  5.多線(xiàn)程抓取
  此次抓取的數據不算多,但是為了學(xué)習,使用多進(jìn)程進(jìn)行抓取,以應對以后大量的數據抓取。
  
  下面為普通抓取和多進(jìn)程抓取的時(shí)間對比:
  以下為完整代碼:

高性能異步并發(fā)爬蟲(chóng)!- colly 自動(dòng)抓取資訊

網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 226 次瀏覽 ? 2022-06-12 08:31 ? 來(lái)自相關(guān)話(huà)題

  高性能異步并發(fā)爬蟲(chóng)!- colly 自動(dòng)抓取資訊
  colly 在 golang 中的地位,比之 scrapy 在 python 的作用,都是爬蟲(chóng)界的大佬。本文用其抓取博文資訊,從收集器實(shí)例配置,goQuery 進(jìn)行 dom 節點(diǎn)數據抓取,自動(dòng)分頁(yè)訪(fǎng)問(wèn),到 csv 數據持久化,json 控制臺輸出,全程簡(jiǎn)單直觀(guān)。
  
  Code
  抓取數據入口為社區某用戶(hù)博客列表頁(yè),比如
  package main<br /><br />import (<br /> "encoding/csv"<br /> "encoding/json"<br /> "log"<br /> "os"<br /> "regexp"<br /> "strconv"<br /> "strings"<br /><br /> "github.com/gocolly/colly"<br />)<br /><br />// Article 抓取blog數據<br />type Article struct {<br /> ID int `json:"id,omitempty"`<br /> Title string `json:"title,omitempty"`<br /> URL string `json:"url,omitempty"`<br /> Created string `json:"created,omitempty"`<br /> Reads string `json:"reads,omitempty"`<br /> Comments string `json:"comments,omitempty"`<br /> Feeds string `json:"feeds,omitempty"`<br />}<br /><br />// 數據持久化<br />func csvSave(fName string, data []Article) error {<br /> file, err := os.Create(fName)<br /> if err != nil {<br /> log.Fatalf("Cannot create file %q: %s\n", fName, err)<br /> }<br /> defer file.Close()<br /> writer := csv.NewWriter(file)<br /> defer writer.Flush()<br /><br /> writer.Write([]string{"ID", "Title", "URL", "Created", "Reads", "Comments", "Feeds"})<br /> for _, v := range data {<br /> writer.Write([]string{strconv.Itoa(v.ID), v.Title, v.URL, v.Created, v.Reads, v.Comments, v.Feeds})<br /> }<br /> return nil<br />}<br /><br />func main() {<br /> articles := make([]Article, 0, 200)<br /> // 1.準備收集器實(shí)例<br /> c := colly.NewCollector(<br /> // 開(kāi)啟本機debug<br /> // colly.Debugger(&debug.LogDebugger{}),<br /> colly.AllowedDomains("learnku.com"),<br /> // 防止頁(yè)面重復下載<br /> // colly.CacheDir("./learnku_cache"),<br /> )<br /><br /> // 2.分析頁(yè)面數據<br /> c.OnHTML("div.blog-article-list > .event", func(e *colly.HTMLElement) {<br /> article := Article{<br /> Title: e.ChildText("div.content > div.summary"),<br /> URL: e.ChildAttr("div.content a.title", "href"),<br /> Feeds: e.ChildText("div.item-meta > a:first-child"),<br /> }<br /> // 查找同一集合不同子項<br /> e.ForEach("div.content > div.meta > div.date>a", func(i int, el *colly.HTMLElement) {<br /> switch i {<br /> case 1:<br /> article.Created = el.Attr("data-tooltip")<br /> case 2:<br /> // 用空白切割字符串<br /> article.Reads = strings.Fields(el.Text)[1]<br /> case 3:<br /> article.Comments = strings.Fields(el.Text)[1]<br /> }<br /> })<br /> // 正則匹配替換,字符串轉整型<br /> article.ID, _ = strconv.Atoi(regexp.MustCompile(`\d+`).FindAllString(article.URL, -1)[0])<br /> articles = append(articles, article)<br /> })<br /><br /> // 下一頁(yè)<br /> c.OnHTML("a[href].page-link", func(e *colly.HTMLElement) {<br /> e.Request.Visit(e.Attr("href"))<br /> })<br /><br /> // 啟動(dòng)<br /> c.Visit("https://learnku.com/blog/pardon")<br /><br /> // 輸出<br /> csvSave("pardon.csv", articles)<br /> enc := json.NewEncoder(os.Stdout)<br /> enc.SetIndent("", " ")<br /> enc.Encode(articles)<br /><br /> // 顯示收集器的打印信息<br /> log.Println(c)<br />}<br />
  Output
  控制臺輸出
  ....<br /> "id": 30604,<br /> "title": "教程: TodoMVC 與 director 路由",<br /> "url": "https://learnku.com/articles/30604",<br /> "created": "2019-07-01 12:42:01",<br /> "reads": "650",<br /> "comments": "0",<br /> "feeds": "0"<br /> },<br /> {<br /> "id": 30579,<br /> "title": "flaskr 進(jìn)階筆記",<br /> "url": "https://learnku.com/articles/30579",<br /> "created": "2019-06-30 19:01:04",<br /> "reads": "895",<br /> "comments": "0",<br /> "feeds": "0"<br /> },<br /> {<br /> "id": 30542,<br /> "title": "教程 Redis+ flask+vue 在線(xiàn)聊天",<br /> "url": "https://learnku.com/articles/30542",<br /> "created": "2019-06-29 12:19:45",<br /> "reads": "2760",<br /> "comments": "1",<br /> "feeds": "2"<br /> }<br />]<br />2019/12/20 15:50:14 Requests made: 5 (5 responses) | Callbacks: OnRequest: 0, OnHTML: 2, OnResponse: 0, OnError: 0
  csv 文本輸出
  ID,Title,URL,Created,Reads,Comments,Feeds<br />37991,ferret 爬取動(dòng)態(tài)網(wǎng)頁(yè),https://learnku.com/articles/37991,2019-12-15 10:43:03,219,0,3<br />37803,匿名類(lèi) 與 索引重建,https://learnku.com/articles/37803,2019-12-09 19:35:09,323,1,0<br />37476,大話(huà)并發(fā),https://learnku.com/articles/37476,2019-12-08 21:17:55,612,0,4<br />37738,三元運算符,https://learnku.com/articles/37738,2019-12-08 09:44:36,606,0,0<br />37719,筆試之 模板變量替換,https://learnku.com/articles/37719,2019-12-07 18:30:42,843,0,0<br />37707,筆試之 連續數增維,https://learnku.com/articles/37707,2019-12-07 13:50:17,872,0,0<br />37616,筆試之 一行代碼求重,https://learnku.com/articles/37616,2019-12-05 12:10:24,792,0,0<br />....
  Colly 查看全部

  高性能異步并發(fā)爬蟲(chóng)!- colly 自動(dòng)抓取資訊
  colly 在 golang 中的地位,比之 scrapy 在 python 的作用,都是爬蟲(chóng)界的大佬。本文用其抓取博文資訊,從收集器實(shí)例配置,goQuery 進(jìn)行 dom 節點(diǎn)數據抓取,自動(dòng)分頁(yè)訪(fǎng)問(wèn),到 csv 數據持久化,json 控制臺輸出,全程簡(jiǎn)單直觀(guān)。
  
  Code
  抓取數據入口為社區某用戶(hù)博客列表頁(yè),比如
  package main<br /><br />import (<br /> "encoding/csv"<br /> "encoding/json"<br /> "log"<br /> "os"<br /> "regexp"<br /> "strconv"<br /> "strings"<br /><br /> "github.com/gocolly/colly"<br />)<br /><br />// Article 抓取blog數據<br />type Article struct {<br /> ID int `json:"id,omitempty"`<br /> Title string `json:"title,omitempty"`<br /> URL string `json:"url,omitempty"`<br /> Created string `json:"created,omitempty"`<br /> Reads string `json:"reads,omitempty"`<br /> Comments string `json:"comments,omitempty"`<br /> Feeds string `json:"feeds,omitempty"`<br />}<br /><br />// 數據持久化<br />func csvSave(fName string, data []Article) error {<br /> file, err := os.Create(fName)<br /> if err != nil {<br /> log.Fatalf("Cannot create file %q: %s\n", fName, err)<br /> }<br /> defer file.Close()<br /> writer := csv.NewWriter(file)<br /> defer writer.Flush()<br /><br /> writer.Write([]string{"ID", "Title", "URL", "Created", "Reads", "Comments", "Feeds"})<br /> for _, v := range data {<br /> writer.Write([]string{strconv.Itoa(v.ID), v.Title, v.URL, v.Created, v.Reads, v.Comments, v.Feeds})<br /> }<br /> return nil<br />}<br /><br />func main() {<br /> articles := make([]Article, 0, 200)<br /> // 1.準備收集器實(shí)例<br /> c := colly.NewCollector(<br /> // 開(kāi)啟本機debug<br /> // colly.Debugger(&debug.LogDebugger{}),<br /> colly.AllowedDomains("learnku.com"),<br /> // 防止頁(yè)面重復下載<br /> // colly.CacheDir("./learnku_cache"),<br /> )<br /><br /> // 2.分析頁(yè)面數據<br /> c.OnHTML("div.blog-article-list > .event", func(e *colly.HTMLElement) {<br /> article := Article{<br /> Title: e.ChildText("div.content > div.summary"),<br /> URL: e.ChildAttr("div.content a.title", "href"),<br /> Feeds: e.ChildText("div.item-meta > a:first-child"),<br /> }<br /> // 查找同一集合不同子項<br /> e.ForEach("div.content > div.meta > div.date>a", func(i int, el *colly.HTMLElement) {<br /> switch i {<br /> case 1:<br /> article.Created = el.Attr("data-tooltip")<br /> case 2:<br /> // 用空白切割字符串<br /> article.Reads = strings.Fields(el.Text)[1]<br /> case 3:<br /> article.Comments = strings.Fields(el.Text)[1]<br /> }<br /> })<br /> // 正則匹配替換,字符串轉整型<br /> article.ID, _ = strconv.Atoi(regexp.MustCompile(`\d+`).FindAllString(article.URL, -1)[0])<br /> articles = append(articles, article)<br /> })<br /><br /> // 下一頁(yè)<br /> c.OnHTML("a[href].page-link", func(e *colly.HTMLElement) {<br /> e.Request.Visit(e.Attr("href"))<br /> })<br /><br /> // 啟動(dòng)<br /> c.Visit("https://learnku.com/blog/pardon";)<br /><br /> // 輸出<br /> csvSave("pardon.csv", articles)<br /> enc := json.NewEncoder(os.Stdout)<br /> enc.SetIndent("", " ")<br /> enc.Encode(articles)<br /><br /> // 顯示收集器的打印信息<br /> log.Println(c)<br />}<br />
  Output
  控制臺輸出
  ....<br /> "id": 30604,<br /> "title": "教程: TodoMVC 與 director 路由",<br /> "url": "https://learnku.com/articles/30604",<br /> "created": "2019-07-01 12:42:01",<br /> "reads": "650",<br /> "comments": "0",<br /> "feeds": "0"<br /> },<br /> {<br /> "id": 30579,<br /> "title": "flaskr 進(jìn)階筆記",<br /> "url": "https://learnku.com/articles/30579",<br /> "created": "2019-06-30 19:01:04",<br /> "reads": "895",<br /> "comments": "0",<br /> "feeds": "0"<br /> },<br /> {<br /> "id": 30542,<br /> "title": "教程 Redis+ flask+vue 在線(xiàn)聊天",<br /> "url": "https://learnku.com/articles/30542",<br /> "created": "2019-06-29 12:19:45",<br /> "reads": "2760",<br /> "comments": "1",<br /> "feeds": "2"<br /> }<br />]<br />2019/12/20 15:50:14 Requests made: 5 (5 responses) | Callbacks: OnRequest: 0, OnHTML: 2, OnResponse: 0, OnError: 0
  csv 文本輸出
  ID,Title,URL,Created,Reads,Comments,Feeds<br />37991,ferret 爬取動(dòng)態(tài)網(wǎng)頁(yè),https://learnku.com/articles/37991,2019-12-15 10:43:03,219,0,3<br />37803,匿名類(lèi) 與 索引重建,https://learnku.com/articles/37803,2019-12-09 19:35:09,323,1,0<br />37476,大話(huà)并發(fā),https://learnku.com/articles/37476,2019-12-08 21:17:55,612,0,4<br />37738,三元運算符,https://learnku.com/articles/37738,2019-12-08 09:44:36,606,0,0<br />37719,筆試之 模板變量替換,https://learnku.com/articles/37719,2019-12-07 18:30:42,843,0,0<br />37707,筆試之 連續數增維,https://learnku.com/articles/37707,2019-12-07 13:50:17,872,0,0<br />37616,筆試之 一行代碼求重,https://learnku.com/articles/37616,2019-12-05 12:10:24,792,0,0<br />....
  Colly

Python網(wǎng)頁(yè)爬蟲(chóng)&文本處理&科學(xué)計算&機器學(xué)習&數據挖掘兵器譜(轉)

網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 71 次瀏覽 ? 2022-06-07 06:58 ? 來(lái)自相關(guān)話(huà)題

  Python網(wǎng)頁(yè)爬蟲(chóng)&文本處理&科學(xué)計算&機器學(xué)習&數據挖掘兵器譜(轉)
  已獲得授權
  周末時(shí)看到這篇不錯的文章,其中介紹了諸多python第三方庫和工具,與大家分享下,也算是門(mén)可羅雀的本號第一次轉載文章。后續看到精彩的文章也會(huì )繼續分享。
  
  Image Photograph by Pavliha Getty
  曾經(jīng)因為NLTK的緣故開(kāi)始學(xué)習Python,之后漸漸成為我工作中的第一輔助腳本語(yǔ)言,雖然開(kāi)發(fā)語(yǔ)言是C/C++,但平時(shí)的很多文本數據處理任務(wù)都交給了Python。
  離開(kāi)騰訊創(chuàng )業(yè)后,第一個(gè)作品課程圖譜也是選擇了Python系的Flask框架,漸漸的將自己的絕大部分工作交給了Python。這些年來(lái),接觸和使用了很多Python工具包,特別是在文本處理,科學(xué)計算,機器學(xué)習和數據挖掘領(lǐng)域,有很多很多優(yōu)秀的Python工具包可供使用,所以作為Pythoner,也是相當幸福的。
  其實(shí)如果仔細留意微博,你會(huì )發(fā)現很多這方面的分享,自己也Google了一下,發(fā)現也有同學(xué)總結了“Python機器學(xué)習庫”,不過(guò)總感覺(jué)缺少點(diǎn)什么。最近流行一個(gè)詞,全棧工程師(full stack engineer),作為一個(gè)苦逼的創(chuàng )業(yè)者,天然的要把自己打造成一個(gè)full stack engineer,而這個(gè)過(guò)程中,這些Python工具包給自己提供了足夠的火力,所以想起了這個(gè)系列。
  當然,這也僅僅是拋磚引玉,希望大家能提供更多的線(xiàn)索,來(lái)匯總整理一套Python網(wǎng)頁(yè)爬蟲(chóng),文本處理,科學(xué)計算,機器學(xué)習和數據挖掘的兵器譜。
  一、Python網(wǎng)頁(yè)爬蟲(chóng)工具集
  一個(gè)真實(shí)的項目,一定是從獲取數據開(kāi)始的。無(wú)論文本處理,機器學(xué)習和數據挖掘,都需要數據,除了通過(guò)一些渠道購買(mǎi)或者下載的專(zhuān)業(yè)數據外,常常需要大家自己動(dòng)手爬數據,這個(gè)時(shí)候,爬蟲(chóng)就顯得格外重要了,幸好,Python提供了一批很不錯的網(wǎng)頁(yè)爬蟲(chóng)工具框架,既能爬取數據,也能獲取和清洗數據,我們也就從這里開(kāi)始了:
  1.Scrapy
  Scrapy, a fast high-level screen scraping and web crawling framework for Python.
  鼎鼎大名的Scrapy,相信不少同學(xué)都有耳聞,課程圖譜中的很多課程都是依靠Scrapy抓去的,這方面的介紹文章有很多,推薦大牛pluskid早年的一篇文章:《Scrapy 輕松定制網(wǎng)絡(luò )爬蟲(chóng)》,歷久彌新。
  官方主頁(yè):
  Github代碼頁(yè):
  2.Beautiful Soup
  You didn’t write that awful page. You’re just trying to get some data out of it. Beautiful Soup is here to help. Since 2004, it’s been saving programmers hours or days of work on quick-turnaround screen scraping projects.
  讀書(shū)的時(shí)候通過(guò)《集體智慧編程》這本書(shū)知道Beautiful Soup的,后來(lái)也偶爾會(huì )用用,非常棒的一套工具??陀^(guān)的說(shuō),Beautifu Soup不完全是一套爬蟲(chóng)工具,需要配合urllib使用,而是一套HTML/XML數據分析,清洗和獲取工具。
  官方主頁(yè):
  3.Python-Goose
  Html Content / Article Extractor, web scrapping lib in Python
  Goose最早是用Java寫(xiě)得,后來(lái)用Scala重寫(xiě),是一個(gè)Scala項目。Python-Goose用Python重寫(xiě),依賴(lài)了Beautiful Soup。前段時(shí)間用過(guò),感覺(jué)很不錯,給定一個(gè)文章的URL, 獲取文章的標題和內容很方便。
  Github主頁(yè):
  二、Python文本處理工具集
  從網(wǎng)頁(yè)上獲取文本數據之后,依據任務(wù)的不同,就需要進(jìn)行基本的文本處理了,譬如對于英文來(lái)說(shuō),需要基本的tokenize,對于中文,則需要常見(jiàn)的中文分詞,進(jìn)一步的話(huà),無(wú)論英文中文,還可以詞性標注,句法分析,關(guān)鍵詞提取,文本分類(lèi),情感分析等等。這個(gè)方面,特別是面向英文領(lǐng)域,有很多優(yōu)秀的工具包,我們一一道來(lái)。
  1.NLTK— Natural Language Toolkit
  NLTK is a leading platform for building Python programs to work with human language data. It provides easy-to-use interfaces to over 50 corpora and lexical resources such as WordNet, along with a suite of text processing libraries for classification, tokenization, stemming, tagging, parsing, and semantic reasoning, and an active discussion forum.
  搞自然語(yǔ)言處理的同學(xué)應該沒(méi)有人不知道NLTK吧,這里也就不多說(shuō)了。不過(guò)推薦兩本書(shū)籍給剛剛接觸NLTK或者需要詳細了解NLTK的同學(xué): 一個(gè)是官方的《Natural Language Processing with Python》,以介紹NLTK里的功能用法為主,同時(shí)附帶一些Python知識,同時(shí)國內陳濤同學(xué)友情翻譯了一個(gè)中文版,這里可以看到:推薦《用Python進(jìn)行自然語(yǔ)言處理》中文翻譯-NLTK配套書(shū);另外一本是《Python Text Processing with NLTK 2.0 Cookbook》,這本書(shū)要深入一些,會(huì )涉及到NLTK的代碼結構,同時(shí)會(huì )介紹如何定制自己的語(yǔ)料和模型等,相當不錯。
  官方主頁(yè):
  Github代碼頁(yè):
  2.Pattern
  Pattern is a web mining module for the Python programming language.
  It has tools for data mining (Google, Twitter and Wikipedia API, a web crawler, a HTML DOM parser), natural language processing (part-of-speech taggers, n-gram search, sentiment analysis, WordNet), machine learning (vector space model, clustering, SVM), network analysis and canvas visualization.
  Pattern由比利時(shí)安特衛普大學(xué)CLiPS實(shí)驗室出品,客觀(guān)的說(shuō),Pattern不僅僅是一套文本處理工具,它更是一套web數據挖掘工具,囊括了數據抓取模塊(包括Google, Twitter, 維基百科的API,以及爬蟲(chóng)和HTML分析器),文本處理模塊(詞性標注,情感分析等),機器學(xué)習模塊(VSM, 聚類(lèi),SVM)以及可視化模塊等,可以說(shuō),Pattern的這一整套邏輯也是這篇文章的組織邏輯,不過(guò)這里我們暫且把Pattern放到文本處理部分。我個(gè)人主要使用的是它的英文處理模塊Pattern.en, 有很多很不錯的文本處理功能,包括基礎的tokenize, 詞性標注,句子切分,語(yǔ)法檢查,拼寫(xiě)糾錯,情感分析,句法分析等,相當不錯。
  官方主頁(yè):
  3.TextBlob: Simplified Text Processing
  TextBlob is a Python (2 and 3) library for processing textual data. It provides a simple API for diving into common natural language processing (NLP) tasks such as part-of-speech tagging, noun phrase extraction, sentiment analysis, classification, translation, and more.
  TextBlob是一個(gè)很有意思的Python文本處理工具包,它其實(shí)是基于上面兩個(gè)Python工具包NLKT和Pattern做了封裝(TextBlob stands on the giant shoulders of NLTK and pattern, and plays nicely with both),同時(shí)提供了很多文本處理功能的接口,包括詞性標注,名詞短語(yǔ)提取,情感分析,文本分類(lèi),拼寫(xiě)檢查等,甚至包括翻譯和語(yǔ)言檢測,不過(guò)這個(gè)是基于Google的API的,有調用次數限制。TextBlob相對比較年輕,有興趣的同學(xué)可以關(guān)注。
  官方主頁(yè):
  Github代碼頁(yè):
  4.MBSPfor Python
  MBSP is a text analysis system based on the TiMBL and MBT memory based learning applications developed at CLiPS and ILK. It provides tools for Tokenization and Sentence Splitting, Part of Speech Tagging, Chunking, Lemmatization, Relation Finding and Prepositional Phrase Attachment.
  MBSP與Pattern同源,同出自比利時(shí)安特衛普大學(xué)CLiPS實(shí)驗室,提供了Word Tokenization, 句子切分,詞性標注,Chunking, Lemmatization,句法分析等基本的文本處理功能,感興趣的同學(xué)可以關(guān)注。
  官方主頁(yè):
  5.Gensim: Topic modeling for humans
  Gensim是一個(gè)相當專(zhuān)業(yè)的主題模型Python工具包,無(wú)論是代碼還是文檔,我們曾經(jīng)用《如何計算兩個(gè)文檔的相似度》介紹過(guò)Gensim的安裝和使用過(guò)程,這里就不多說(shuō)了。
  官方主頁(yè):
  github代碼頁(yè):
  6.langid.py: Stand-alone language identification system
  語(yǔ)言檢測是一個(gè)很有意思的話(huà)題,不過(guò)相對比較成熟,這方面的解決方案很多,也有很多不錯的開(kāi)源工具包,不過(guò)對于Python來(lái)說(shuō),我使用過(guò)langid這個(gè)工具包,也非常愿意推薦它。langid目前支持97種語(yǔ)言的檢測,提供了很多易用的功能,包括可以啟動(dòng)一個(gè)建議的server,通過(guò)json調用其API,可定制訓練自己的語(yǔ)言檢測模型等,可以說(shuō)是“麻雀雖小,五臟俱全”。
  Github主頁(yè):
  7.Jieba: 結巴中文分詞
  “結巴”中文分詞:做最好的Python中文分詞組件 “Jieba” (Chinese for “to stutter”) Chinese text segmentation: built to be the best Python Chinese word segmentation module.
  好了,終于可以說(shuō)一個(gè)國內的Python文本處理工具包了:結巴分詞,其功能包括支持三種分詞模式(精確模式、全模式、搜索引擎模式),支持繁體分詞,支持自定義詞典等,是目前一個(gè)非常不錯的Python中文分詞解決方案。
  Github主頁(yè):
  8.xTAS
  xtas, the eXtensible Text Analysis Suite, a distributed text analysis package based on Celery and Elasticsearch.
  感謝微博朋友@大山坡的春提供的線(xiàn)索:我們組同事之前發(fā)布了xTAS,也是基于python的text mining工具包,歡迎使用,鏈接:??雌饋?lái)很不錯的樣子,回頭試用一下。
  Github代碼頁(yè):
  三、Python科學(xué)計算工具包
  說(shuō)起科學(xué)計算,大家首先想起的是Matlab,集數值計算,可視化工具及交互于一身,不過(guò)可惜是一個(gè)商業(yè)產(chǎn)品。開(kāi)源方面除了GNU Octave在嘗試做一個(gè)類(lèi)似Matlab的工具包外,Python的這幾個(gè)工具包集合到一起也可以替代Matlab的相應功能:NumPy+SciPy+Matplotlib+iPython。同時(shí),這幾個(gè)工具包,特別是NumPy和SciPy,也是很多Python文本處理 & 機器學(xué)習 & 數據挖掘工具包的基礎,非常重要。最后再推薦一個(gè)系列《用Python做科學(xué)計算》,將會(huì )涉及到NumPy, SciPy, Matplotlib,可以做參考。
  1.NumPy
  NumPy is the fundamental package for scientific computing with Python. It contains among other things:
  1)a powerful N-dimensional array object
  2)sophisticated (broadcasting) functions
  3)tools for integrating C/C++ and Fortran code
  4) useful linear algebra, Fourier transform, and random number capabilities
  Besides its obvious scientific uses, NumPy can also be used as an efficient multi-dimensional container of generic data. Arbitrary data-types can be defined. This allows NumPy to seamlessly and speedily integrate with a wide variety of databases.
  NumPy幾乎是一個(gè)無(wú)法回避的科學(xué)計算工具包,最常用的也許是它的N維數組對象,其他還包括一些成熟的函數庫,用于整合C/C++和Fortran代碼的工具包,線(xiàn)性代數、傅里葉變換和隨機數生成函數等。NumPy提供了兩種基本的對象:ndarray(N-dimensional array object)和 ufunc(universal function object)。ndarray是存儲單一數據類(lèi)型的多維數組,而ufunc則是能夠對數組進(jìn)行處理的函數。
  官方主頁(yè):
  2.SciPy:Scientific Computing Tools for Python
  SciPy refers to several related but distinct entities:
  1)The SciPy Stack, a collection of open source software for scientific computing in Python, and particularly a specified set of core packages.
  2)The community of people who use and develop this stack.
  3)Several conferences dedicated to scientific computing in Python – SciPy, EuroSciPy and SciPy.in.
  4)The SciPy library, one component of the SciPy stack, providing many numerical routines.
  “SciPy是一個(gè)開(kāi)源的Python算法庫和數學(xué)工具包,SciPy包含的模塊有最優(yōu)化、線(xiàn)性代數、積分、插值、特殊函數、快速傅里葉變換、信號處理和圖像處理、常微分方程求解和其他科學(xué)與工程中常用的計算。其功能與軟件MATLAB、Scilab和GNU Octave類(lèi)似。 Numpy和Scipy常常結合著(zhù)使用,Python大多數機器學(xué)習庫都依賴(lài)于這兩個(gè)模塊?!薄?引用自“Python機器學(xué)習庫”
  官方主頁(yè):
  3.Matplotlib
  matplotlib is a python 2D plotting library which produces publication quality figures in a variety of hardcopy formats and interactive environments across platforms. matplotlib can be used in python scripts, the python and ipython shell (ala MATLAB?* or Mathematica??), web application servers, and six graphical user interface toolkits.
  matplotlib 是python最著(zhù)名的繪圖庫,它提供了一整套和matlab相似的命令API,十分適合交互式地進(jìn)行制圖。而且也可以方便地將它作為繪圖控件,嵌入GUI應用程序中。Matplotlib可以配合ipython shell使用,提供不亞于Matlab的繪圖體驗,總之用過(guò)了都說(shuō)好。
  官方主頁(yè):
  4.iPython
  IPython provides a rich architecture for interactive computing with:
  1)Powerful interactive shells (terminal and Qt-based).
  2)A browser-based notebook with support for code, text, mathematical expressions, inline plots and other rich media.
  3)Support for interactive data visualization and use of GUI toolkits.
  4)Flexible, embeddable interpreters to load into your own projects.
  5)Easy to use, high performance tools for parallel computing.
  “iPython 是一個(gè)Python 的交互式Shell,比默認的Python Shell 好用得多,功能也更強大。 她支持語(yǔ)法高亮、自動(dòng)完成、代碼調試、對象自省,支持 Bash Shell 命令,內置了許多很有用的功能和函式等,非常容易使用。 ” 啟動(dòng)iPython的時(shí)候用這個(gè)命令“ipython –pylab”,默認開(kāi)啟了matploblib的繪圖交互,用起來(lái)很方便。
  官方主頁(yè):
  四、Python 機器學(xué)習 & 數據挖掘 工具包
  機器學(xué)習和數據挖掘這兩個(gè)概念不太好區分,這里就放到一起了。這方面的開(kāi)源Python工具包有很多,這里先從熟悉的講起,再補充其他來(lái)源的資料,也歡迎大家補充。
  1.scikit-learn: Machine Learning in Python
  scikit-learn (formerly scikits.learn) is an open source machine learning library for the Python programming language. It features various classification, regression and clustering algorithms including support vector machines, logistic regression, naive Bayes, random forests, gradient boosting, k-means and DBSCAN, and is designed to interoperate with the Python numerical and scientific libraries NumPy and SciPy.
  首先推薦大名鼎鼎的scikit-learn,scikit-learn是一個(gè)基于NumPy, SciPy, Matplotlib的開(kāi)源機器學(xué)習工具包,主要涵蓋分類(lèi),回歸和聚類(lèi)算法,例如SVM, 邏輯回歸,樸素貝葉斯,隨機森林,k-means等算法,代碼和文檔都非常不錯,在許多Python項目中都有應用。例如在我們熟悉的NLTK中,分類(lèi)器方面就有專(zhuān)門(mén)針對scikit-learn的接口,可以調用scikit-learn的分類(lèi)算法以及訓練數據來(lái)訓練分類(lèi)器模型。這里推薦一個(gè)視頻,也是我早期遇到scikit-learn的時(shí)候推薦過(guò)的:推薦一個(gè)Python機器學(xué)習工具包Scikit-learn以及相關(guān)視頻–Tutorial: scikit-learn – Machine Learning in Python
  官方主頁(yè):
  2.Pandas: Python Data Analysis Library
  Pandas is a software library written for the Python programming language for data manipulation and analysis. In particular, it offers data structures and operations for manipulating numerical tables and time series.
  第一次接觸Pandas是由于Udacity上的一門(mén)數據分析課程“Introduction to Data Science” 的Project需要用Pandas庫,所以學(xué)習了一下Pandas。Pandas也是基于NumPy和Matplotlib開(kāi)發(fā)的,主要用于數據分析和數據可視化,它的數據結構DataFrame和R語(yǔ)言里的data.frame很像,特別是對于時(shí)間序列數據有自己的一套分析機制,非常不錯。這里推薦一本書(shū)《Python for Data Analysis》,作者是Pandas的主力開(kāi)發(fā),依次介紹了iPython, NumPy, Pandas里的相關(guān)功能,數據可視化,數據清洗和加工,時(shí)間數據處理等,案例包括金融股票數據挖掘等,相當不錯。
  官方主頁(yè):
  =====================================================
  分割線(xiàn),以上工具包基本上都是自己用過(guò)的,以下來(lái)源于其他同學(xué)的線(xiàn)索,特別是《Python機器學(xué)習庫》,《23個(gè)python的機器學(xué)習包》,做了一點(diǎn)增刪修改,歡迎大家補充
  =====================================================
  3.mlpy – Machine Learning Python
  mlpy is a Python module for Machine Learning built on top of NumPy/SciPy and the GNU Scientific Libraries.
  mlpy provides a wide range of state-of-the-art machine learning methods for supervised and unsupervised problems and it is aimed at finding a reasonable compromise among modularity, maintainability, reproducibility, usability and efficiency. mlpy is multiplatform, it works with Python 2 and 3 and it is Open Source, distributed under the GNU General Public License version 3.
  官方主頁(yè):
  4.MDP:The Modular toolkit for Data Processing
  Modular toolkit for Data Processing (MDP) is a Python data processing framework.
  From the user’s perspective, MDP is a collection of supervised and unsupervised learning algorithms and other data processing units that can be combined into data processing sequences and more complex feed-forward network architectures.
  From the scientific developer’s perspective, MDP is a modular framework, which can easily be expanded. The implementation of new algorithms is easy and intuitive. The new implemented units are then automatically integrated with the rest of the library.
  The base of available algorithms is steadily increasing and includes signal processing methods (Principal Component Analysis, Independent Component Analysis, Slow Feature Analysis), manifold learning methods ([Hessian] Locally Linear Embedding), several classifiers, probabilistic methods (Factor Analysis, RBM), data pre-processing methods, and many others.
  “MDP用于數據處理的模塊化工具包,一個(gè)Python數據處理框架。 從用戶(hù)的觀(guān)點(diǎn),MDP是能夠被整合到數據處理序列和更復雜的前饋網(wǎng)絡(luò )結構的一批監督學(xué)習和非監督學(xué)習算法和其他數據處理單元。計算依照速度和內存需求而高效的執行。從科學(xué)開(kāi)發(fā)者的觀(guān)點(diǎn),MDP是一個(gè)模塊框架,它能夠被容易地擴展。新算法的實(shí)現是容易且直觀(guān)的。新實(shí)現的單元然后被自動(dòng)地與程序庫的其余部件進(jìn)行整合。MDP在神經(jīng)科學(xué)的理論研究背景下被編寫(xiě),但是它已經(jīng)被設計為在使用可訓練數據處理算法的任何情況中都是有用的。其站在用戶(hù)一邊的簡(jiǎn)單性,各種不同的隨時(shí)可用的算法,及應用單元的可重用性,使得它也是一個(gè)有用的教學(xué)工具?!?
  官方主頁(yè):
  5.PyBrain
  PyBrain is a modular Machine Learning Library for Python. Its goal is to offer flexible, easy-to-use yet still powerful algorithms for Machine Learning Tasks and a variety of predefined environments to test and compare your algorithms.
  PyBrain is short for Python-Based Reinforcement Learning, Artificial Intelligence and Neural Network Library. In fact, we came up with the name first and later reverse-engineered this quite descriptive “Backronym”.
  “PyBrain(Python-Based Reinforcement Learning, Artificial Intelligence and Neural Network)是Python的一個(gè)機器學(xué)習模塊,它的目標是為機器學(xué)習任務(wù)提供靈活、易應、強大的機器學(xué)習算法。(這名字很霸氣)
  PyBrain正如其名,包括神經(jīng)網(wǎng)絡(luò )、強化學(xué)習(及二者結合)、無(wú)監督學(xué)習、進(jìn)化算法。因為目前的許多問(wèn)題需要處理連續態(tài)和行為空間,必須使用函數逼近(如神經(jīng)網(wǎng)絡(luò ))以應對高維數據。PyBrain以神經(jīng)網(wǎng)絡(luò )為核心,所有的訓練方法都以神經(jīng)網(wǎng)絡(luò )為一個(gè)實(shí)例?!?
  官方主頁(yè):
  6.PyML– machine learning in Python
  PyML is an interactive object oriented framework for machine learning written in Python. PyML focuses on SVMs and other kernel methods. It is supported on Linux and Mac OS X.
  “PyML是一個(gè)Python機器學(xué)習工具包,為各分類(lèi)和回歸方法提供靈活的架構。它主要提供特征選擇、模型選擇、組合分類(lèi)器、分類(lèi)評估等功能?!?
  項目主頁(yè):
  7.Milk:Machine learning toolkit in Python.
  Its focus is on supervised classification with several classifiers available:
  SVMs (based on libsvm), k-NN, random forests, decision trees. It also performs
  feature selection. These classifiers can be combined in many ways to form
  different classification systems.
  “Milk是Python的一個(gè)機器學(xué)習工具箱,其重點(diǎn)是提供監督分類(lèi)法與幾種有效的分類(lèi)分析:SVMs(基于libsvm),K-NN,隨機森林經(jīng)濟和決策樹(shù)。它還可以進(jìn)行特征選擇。這些分類(lèi)可以在許多方面相結合,形成不同的分類(lèi)系統。對于無(wú)監督學(xué)習,它提供K-means和affinity propagation聚類(lèi)算法?!?
  官方主頁(yè):
  8.PyMVPA: MultiVariate Pattern Analysis (MVPA) in Python
  PyMVPA is a Python package intended to ease statistical learning analyses of large datasets. It offers an extensible framework with a high-level interface to a broad range of algorithms for classification, regression, feature selection, data import and export. It is designed to integrate well with related software packages, such as scikit-learn, and MDP. While it is not limited to the neuroimaging domain, it is eminently suited for such datasets. PyMVPA is free software and requires nothing but free-software to run.
  “PyMVPA(Multivariate Pattern Analysis in Python)是為大數據集提供統計學(xué)習分析的Python工具包,它提供了一個(gè)靈活可擴展的框架。它提供的功能有分類(lèi)、回歸、特征選擇、數據導入導出、可視化等”
  官方主頁(yè):
  9.Pyrallel– Parallel Data Analytics in Python
  Experimental project to investigate distributed computation patterns for machine learning and other semi-interactive data analytics tasks.
  “Pyrallel(Parallel Data Analytics in Python)基于分布式計算模式的機器學(xué)習和半交互式的試驗項目,可在小型集群上運行”
  Github代碼頁(yè):
  10.Monte– gradient based learning in Python
  Monte (python) is a Python framework for building gradient based learning machines, like neural networks, conditional random fields, logistic regression, etc. Monte contains modules (that hold parameters, a cost-function and a gradient-function) and trainers (that can adapt a module’s parameters by minimizing its cost-function on training data).
  Modules are usually composed of other modules, which can in turn contain other modules, etc. Gradients of decomposable systems like these can be computed with back-propagation.
  “Monte (machine learning in pure Python)是一個(gè)純Python機器學(xué)習庫。它可以迅速構建神經(jīng)網(wǎng)絡(luò )、條件隨機場(chǎng)、邏輯回歸等模型,使用inline-C優(yōu)化,極易使用和擴展?!?
  官方主頁(yè):
  11.Theano
  Theano is a Python library that allows you to define, optimize, and evaluate mathematical expressions involving multi-dimensional arrays efficiently. Theano features:
  1)tight integration with NumPy – Use numpy.ndarray in Theano-compiled functions.
  2)transparent use of a GPU – Perform data-intensive calculations up to 140x faster than with CPU.(float32 only)
  3)efficient symbolic differentiation – Theano does your derivatives for function with one or many inputs.
  4)speed and stability optimizations – Get the right answer for log(1+x) even when x is really tiny.
  5)dynamic C code generation – Evaluate expressions faster.
  6) extensive unit-testing and self-verification – Detect and diagnose many types of mistake.
  Theano has been powering large-scale computationally intensive scientific investigations since 2007. But it is also approachable enough to be used in the classroom (IFT6266 at the University of Montreal).
  “Theano 是一個(gè) Python 庫,用來(lái)定義、優(yōu)化和模擬數學(xué)表達式計算,用于高效的解決多維數組的計算問(wèn)題。Theano的特點(diǎn):緊密集成Numpy;高效的數據密集型GPU計算;高效的符號微分運算;高速和穩定的優(yōu)化;動(dòng)態(tài)生成c代碼;廣泛的單元測試和自我驗證。自2007年以來(lái),Theano已被廣泛應用于科學(xué)運算。theano使得構建深度學(xué)習模型更加容易,可以快速實(shí)現多種模型。PS:Theano,一位希臘美女,Croton最有權勢的Milo的女兒,后來(lái)成為了畢達哥拉斯的老婆?!?
  12.Pylearn2
  Pylearn2 is a machine learning library. Most of its functionality is built on top of Theano. This means you can write Pylearn2 plugins (new models, algorithms, etc) using mathematical expressions, and theano will optimize and stabilize those expressions for you, and compile them to a backend of your choice (CPU or GPU).
  “Pylearn2建立在theano上,部分依賴(lài)scikit-learn上,目前Pylearn2正處于開(kāi)發(fā)中,將可以處理向量、圖像、視頻等數據,提供MLP、RBM、SDA等深度學(xué)習模型?!?
  官方主頁(yè):
  其他的,歡迎大家補充。
  歡迎關(guān)注“牛衣古柳”
  門(mén)可羅雀,快來(lái)捕鳥(niǎo)!
   查看全部

  Python網(wǎng)頁(yè)爬蟲(chóng)&文本處理&科學(xué)計算&機器學(xué)習&數據挖掘兵器譜(轉)
  已獲得授權
  周末時(shí)看到這篇不錯的文章,其中介紹了諸多python第三方庫和工具,與大家分享下,也算是門(mén)可羅雀的本號第一次轉載文章。后續看到精彩的文章也會(huì )繼續分享。
  
  Image Photograph by Pavliha Getty
  曾經(jīng)因為NLTK的緣故開(kāi)始學(xué)習Python,之后漸漸成為我工作中的第一輔助腳本語(yǔ)言,雖然開(kāi)發(fā)語(yǔ)言是C/C++,但平時(shí)的很多文本數據處理任務(wù)都交給了Python。
  離開(kāi)騰訊創(chuàng )業(yè)后,第一個(gè)作品課程圖譜也是選擇了Python系的Flask框架,漸漸的將自己的絕大部分工作交給了Python。這些年來(lái),接觸和使用了很多Python工具包,特別是在文本處理,科學(xué)計算,機器學(xué)習和數據挖掘領(lǐng)域,有很多很多優(yōu)秀的Python工具包可供使用,所以作為Pythoner,也是相當幸福的。
  其實(shí)如果仔細留意微博,你會(huì )發(fā)現很多這方面的分享,自己也Google了一下,發(fā)現也有同學(xué)總結了“Python機器學(xué)習庫”,不過(guò)總感覺(jué)缺少點(diǎn)什么。最近流行一個(gè)詞,全棧工程師(full stack engineer),作為一個(gè)苦逼的創(chuàng )業(yè)者,天然的要把自己打造成一個(gè)full stack engineer,而這個(gè)過(guò)程中,這些Python工具包給自己提供了足夠的火力,所以想起了這個(gè)系列。
  當然,這也僅僅是拋磚引玉,希望大家能提供更多的線(xiàn)索,來(lái)匯總整理一套Python網(wǎng)頁(yè)爬蟲(chóng),文本處理,科學(xué)計算,機器學(xué)習和數據挖掘的兵器譜。
  一、Python網(wǎng)頁(yè)爬蟲(chóng)工具集
  一個(gè)真實(shí)的項目,一定是從獲取數據開(kāi)始的。無(wú)論文本處理,機器學(xué)習和數據挖掘,都需要數據,除了通過(guò)一些渠道購買(mǎi)或者下載的專(zhuān)業(yè)數據外,常常需要大家自己動(dòng)手爬數據,這個(gè)時(shí)候,爬蟲(chóng)就顯得格外重要了,幸好,Python提供了一批很不錯的網(wǎng)頁(yè)爬蟲(chóng)工具框架,既能爬取數據,也能獲取和清洗數據,我們也就從這里開(kāi)始了:
  1.Scrapy
  Scrapy, a fast high-level screen scraping and web crawling framework for Python.
  鼎鼎大名的Scrapy,相信不少同學(xué)都有耳聞,課程圖譜中的很多課程都是依靠Scrapy抓去的,這方面的介紹文章有很多,推薦大牛pluskid早年的一篇文章:《Scrapy 輕松定制網(wǎng)絡(luò )爬蟲(chóng)》,歷久彌新。
  官方主頁(yè):
  Github代碼頁(yè):
  2.Beautiful Soup
  You didn’t write that awful page. You’re just trying to get some data out of it. Beautiful Soup is here to help. Since 2004, it’s been saving programmers hours or days of work on quick-turnaround screen scraping projects.
  讀書(shū)的時(shí)候通過(guò)《集體智慧編程》這本書(shū)知道Beautiful Soup的,后來(lái)也偶爾會(huì )用用,非常棒的一套工具??陀^(guān)的說(shuō),Beautifu Soup不完全是一套爬蟲(chóng)工具,需要配合urllib使用,而是一套HTML/XML數據分析,清洗和獲取工具。
  官方主頁(yè):
  3.Python-Goose
  Html Content / Article Extractor, web scrapping lib in Python
  Goose最早是用Java寫(xiě)得,后來(lái)用Scala重寫(xiě),是一個(gè)Scala項目。Python-Goose用Python重寫(xiě),依賴(lài)了Beautiful Soup。前段時(shí)間用過(guò),感覺(jué)很不錯,給定一個(gè)文章的URL, 獲取文章的標題和內容很方便。
  Github主頁(yè):
  二、Python文本處理工具集
  從網(wǎng)頁(yè)上獲取文本數據之后,依據任務(wù)的不同,就需要進(jìn)行基本的文本處理了,譬如對于英文來(lái)說(shuō),需要基本的tokenize,對于中文,則需要常見(jiàn)的中文分詞,進(jìn)一步的話(huà),無(wú)論英文中文,還可以詞性標注,句法分析,關(guān)鍵詞提取,文本分類(lèi),情感分析等等。這個(gè)方面,特別是面向英文領(lǐng)域,有很多優(yōu)秀的工具包,我們一一道來(lái)。
  1.NLTK— Natural Language Toolkit
  NLTK is a leading platform for building Python programs to work with human language data. It provides easy-to-use interfaces to over 50 corpora and lexical resources such as WordNet, along with a suite of text processing libraries for classification, tokenization, stemming, tagging, parsing, and semantic reasoning, and an active discussion forum.
  搞自然語(yǔ)言處理的同學(xué)應該沒(méi)有人不知道NLTK吧,這里也就不多說(shuō)了。不過(guò)推薦兩本書(shū)籍給剛剛接觸NLTK或者需要詳細了解NLTK的同學(xué): 一個(gè)是官方的《Natural Language Processing with Python》,以介紹NLTK里的功能用法為主,同時(shí)附帶一些Python知識,同時(shí)國內陳濤同學(xué)友情翻譯了一個(gè)中文版,這里可以看到:推薦《用Python進(jìn)行自然語(yǔ)言處理》中文翻譯-NLTK配套書(shū);另外一本是《Python Text Processing with NLTK 2.0 Cookbook》,這本書(shū)要深入一些,會(huì )涉及到NLTK的代碼結構,同時(shí)會(huì )介紹如何定制自己的語(yǔ)料和模型等,相當不錯。
  官方主頁(yè):
  Github代碼頁(yè):
  2.Pattern
  Pattern is a web mining module for the Python programming language.
  It has tools for data mining (Google, Twitter and Wikipedia API, a web crawler, a HTML DOM parser), natural language processing (part-of-speech taggers, n-gram search, sentiment analysis, WordNet), machine learning (vector space model, clustering, SVM), network analysis and canvas visualization.
  Pattern由比利時(shí)安特衛普大學(xué)CLiPS實(shí)驗室出品,客觀(guān)的說(shuō),Pattern不僅僅是一套文本處理工具,它更是一套web數據挖掘工具,囊括了數據抓取模塊(包括Google, Twitter, 維基百科的API,以及爬蟲(chóng)和HTML分析器),文本處理模塊(詞性標注,情感分析等),機器學(xué)習模塊(VSM, 聚類(lèi),SVM)以及可視化模塊等,可以說(shuō),Pattern的這一整套邏輯也是這篇文章的組織邏輯,不過(guò)這里我們暫且把Pattern放到文本處理部分。我個(gè)人主要使用的是它的英文處理模塊Pattern.en, 有很多很不錯的文本處理功能,包括基礎的tokenize, 詞性標注,句子切分,語(yǔ)法檢查,拼寫(xiě)糾錯,情感分析,句法分析等,相當不錯。
  官方主頁(yè):
  3.TextBlob: Simplified Text Processing
  TextBlob is a Python (2 and 3) library for processing textual data. It provides a simple API for diving into common natural language processing (NLP) tasks such as part-of-speech tagging, noun phrase extraction, sentiment analysis, classification, translation, and more.
  TextBlob是一個(gè)很有意思的Python文本處理工具包,它其實(shí)是基于上面兩個(gè)Python工具包NLKT和Pattern做了封裝(TextBlob stands on the giant shoulders of NLTK and pattern, and plays nicely with both),同時(shí)提供了很多文本處理功能的接口,包括詞性標注,名詞短語(yǔ)提取,情感分析,文本分類(lèi),拼寫(xiě)檢查等,甚至包括翻譯和語(yǔ)言檢測,不過(guò)這個(gè)是基于Google的API的,有調用次數限制。TextBlob相對比較年輕,有興趣的同學(xué)可以關(guān)注。
  官方主頁(yè):
  Github代碼頁(yè):
  4.MBSPfor Python
  MBSP is a text analysis system based on the TiMBL and MBT memory based learning applications developed at CLiPS and ILK. It provides tools for Tokenization and Sentence Splitting, Part of Speech Tagging, Chunking, Lemmatization, Relation Finding and Prepositional Phrase Attachment.
  MBSP與Pattern同源,同出自比利時(shí)安特衛普大學(xué)CLiPS實(shí)驗室,提供了Word Tokenization, 句子切分,詞性標注,Chunking, Lemmatization,句法分析等基本的文本處理功能,感興趣的同學(xué)可以關(guān)注。
  官方主頁(yè):
  5.Gensim: Topic modeling for humans
  Gensim是一個(gè)相當專(zhuān)業(yè)的主題模型Python工具包,無(wú)論是代碼還是文檔,我們曾經(jīng)用《如何計算兩個(gè)文檔的相似度》介紹過(guò)Gensim的安裝和使用過(guò)程,這里就不多說(shuō)了。
  官方主頁(yè):
  github代碼頁(yè):
  6.langid.py: Stand-alone language identification system
  語(yǔ)言檢測是一個(gè)很有意思的話(huà)題,不過(guò)相對比較成熟,這方面的解決方案很多,也有很多不錯的開(kāi)源工具包,不過(guò)對于Python來(lái)說(shuō),我使用過(guò)langid這個(gè)工具包,也非常愿意推薦它。langid目前支持97種語(yǔ)言的檢測,提供了很多易用的功能,包括可以啟動(dòng)一個(gè)建議的server,通過(guò)json調用其API,可定制訓練自己的語(yǔ)言檢測模型等,可以說(shuō)是“麻雀雖小,五臟俱全”。
  Github主頁(yè):
  7.Jieba: 結巴中文分詞
  “結巴”中文分詞:做最好的Python中文分詞組件 “Jieba” (Chinese for “to stutter”) Chinese text segmentation: built to be the best Python Chinese word segmentation module.
  好了,終于可以說(shuō)一個(gè)國內的Python文本處理工具包了:結巴分詞,其功能包括支持三種分詞模式(精確模式、全模式、搜索引擎模式),支持繁體分詞,支持自定義詞典等,是目前一個(gè)非常不錯的Python中文分詞解決方案。
  Github主頁(yè):
  8.xTAS
  xtas, the eXtensible Text Analysis Suite, a distributed text analysis package based on Celery and Elasticsearch.
  感謝微博朋友@大山坡的春提供的線(xiàn)索:我們組同事之前發(fā)布了xTAS,也是基于python的text mining工具包,歡迎使用,鏈接:??雌饋?lái)很不錯的樣子,回頭試用一下。
  Github代碼頁(yè):
  三、Python科學(xué)計算工具包
  說(shuō)起科學(xué)計算,大家首先想起的是Matlab,集數值計算,可視化工具及交互于一身,不過(guò)可惜是一個(gè)商業(yè)產(chǎn)品。開(kāi)源方面除了GNU Octave在嘗試做一個(gè)類(lèi)似Matlab的工具包外,Python的這幾個(gè)工具包集合到一起也可以替代Matlab的相應功能:NumPy+SciPy+Matplotlib+iPython。同時(shí),這幾個(gè)工具包,特別是NumPy和SciPy,也是很多Python文本處理 & 機器學(xué)習 & 數據挖掘工具包的基礎,非常重要。最后再推薦一個(gè)系列《用Python做科學(xué)計算》,將會(huì )涉及到NumPy, SciPy, Matplotlib,可以做參考。
  1.NumPy
  NumPy is the fundamental package for scientific computing with Python. It contains among other things:
  1)a powerful N-dimensional array object
  2)sophisticated (broadcasting) functions
  3)tools for integrating C/C++ and Fortran code
  4) useful linear algebra, Fourier transform, and random number capabilities
  Besides its obvious scientific uses, NumPy can also be used as an efficient multi-dimensional container of generic data. Arbitrary data-types can be defined. This allows NumPy to seamlessly and speedily integrate with a wide variety of databases.
  NumPy幾乎是一個(gè)無(wú)法回避的科學(xué)計算工具包,最常用的也許是它的N維數組對象,其他還包括一些成熟的函數庫,用于整合C/C++和Fortran代碼的工具包,線(xiàn)性代數、傅里葉變換和隨機數生成函數等。NumPy提供了兩種基本的對象:ndarray(N-dimensional array object)和 ufunc(universal function object)。ndarray是存儲單一數據類(lèi)型的多維數組,而ufunc則是能夠對數組進(jìn)行處理的函數。
  官方主頁(yè):
  2.SciPy:Scientific Computing Tools for Python
  SciPy refers to several related but distinct entities:
  1)The SciPy Stack, a collection of open source software for scientific computing in Python, and particularly a specified set of core packages.
  2)The community of people who use and develop this stack.
  3)Several conferences dedicated to scientific computing in Python – SciPy, EuroSciPy and SciPy.in.
  4)The SciPy library, one component of the SciPy stack, providing many numerical routines.
  “SciPy是一個(gè)開(kāi)源的Python算法庫和數學(xué)工具包,SciPy包含的模塊有最優(yōu)化、線(xiàn)性代數、積分、插值、特殊函數、快速傅里葉變換、信號處理和圖像處理、常微分方程求解和其他科學(xué)與工程中常用的計算。其功能與軟件MATLAB、Scilab和GNU Octave類(lèi)似。 Numpy和Scipy常常結合著(zhù)使用,Python大多數機器學(xué)習庫都依賴(lài)于這兩個(gè)模塊?!薄?引用自“Python機器學(xué)習庫”
  官方主頁(yè):
  3.Matplotlib
  matplotlib is a python 2D plotting library which produces publication quality figures in a variety of hardcopy formats and interactive environments across platforms. matplotlib can be used in python scripts, the python and ipython shell (ala MATLAB?* or Mathematica??), web application servers, and six graphical user interface toolkits.
  matplotlib 是python最著(zhù)名的繪圖庫,它提供了一整套和matlab相似的命令API,十分適合交互式地進(jìn)行制圖。而且也可以方便地將它作為繪圖控件,嵌入GUI應用程序中。Matplotlib可以配合ipython shell使用,提供不亞于Matlab的繪圖體驗,總之用過(guò)了都說(shuō)好。
  官方主頁(yè):
  4.iPython
  IPython provides a rich architecture for interactive computing with:
  1)Powerful interactive shells (terminal and Qt-based).
  2)A browser-based notebook with support for code, text, mathematical expressions, inline plots and other rich media.
  3)Support for interactive data visualization and use of GUI toolkits.
  4)Flexible, embeddable interpreters to load into your own projects.
  5)Easy to use, high performance tools for parallel computing.
  “iPython 是一個(gè)Python 的交互式Shell,比默認的Python Shell 好用得多,功能也更強大。 她支持語(yǔ)法高亮、自動(dòng)完成、代碼調試、對象自省,支持 Bash Shell 命令,內置了許多很有用的功能和函式等,非常容易使用。 ” 啟動(dòng)iPython的時(shí)候用這個(gè)命令“ipython –pylab”,默認開(kāi)啟了matploblib的繪圖交互,用起來(lái)很方便。
  官方主頁(yè):
  四、Python 機器學(xué)習 & 數據挖掘 工具包
  機器學(xué)習和數據挖掘這兩個(gè)概念不太好區分,這里就放到一起了。這方面的開(kāi)源Python工具包有很多,這里先從熟悉的講起,再補充其他來(lái)源的資料,也歡迎大家補充。
  1.scikit-learn: Machine Learning in Python
  scikit-learn (formerly scikits.learn) is an open source machine learning library for the Python programming language. It features various classification, regression and clustering algorithms including support vector machines, logistic regression, naive Bayes, random forests, gradient boosting, k-means and DBSCAN, and is designed to interoperate with the Python numerical and scientific libraries NumPy and SciPy.
  首先推薦大名鼎鼎的scikit-learn,scikit-learn是一個(gè)基于NumPy, SciPy, Matplotlib的開(kāi)源機器學(xué)習工具包,主要涵蓋分類(lèi),回歸和聚類(lèi)算法,例如SVM, 邏輯回歸,樸素貝葉斯,隨機森林,k-means等算法,代碼和文檔都非常不錯,在許多Python項目中都有應用。例如在我們熟悉的NLTK中,分類(lèi)器方面就有專(zhuān)門(mén)針對scikit-learn的接口,可以調用scikit-learn的分類(lèi)算法以及訓練數據來(lái)訓練分類(lèi)器模型。這里推薦一個(gè)視頻,也是我早期遇到scikit-learn的時(shí)候推薦過(guò)的:推薦一個(gè)Python機器學(xué)習工具包Scikit-learn以及相關(guān)視頻–Tutorial: scikit-learn – Machine Learning in Python
  官方主頁(yè):
  2.Pandas: Python Data Analysis Library
  Pandas is a software library written for the Python programming language for data manipulation and analysis. In particular, it offers data structures and operations for manipulating numerical tables and time series.
  第一次接觸Pandas是由于Udacity上的一門(mén)數據分析課程“Introduction to Data Science” 的Project需要用Pandas庫,所以學(xué)習了一下Pandas。Pandas也是基于NumPy和Matplotlib開(kāi)發(fā)的,主要用于數據分析和數據可視化,它的數據結構DataFrame和R語(yǔ)言里的data.frame很像,特別是對于時(shí)間序列數據有自己的一套分析機制,非常不錯。這里推薦一本書(shū)《Python for Data Analysis》,作者是Pandas的主力開(kāi)發(fā),依次介紹了iPython, NumPy, Pandas里的相關(guān)功能,數據可視化,數據清洗和加工,時(shí)間數據處理等,案例包括金融股票數據挖掘等,相當不錯。
  官方主頁(yè):
  =====================================================
  分割線(xiàn),以上工具包基本上都是自己用過(guò)的,以下來(lái)源于其他同學(xué)的線(xiàn)索,特別是《Python機器學(xué)習庫》,《23個(gè)python的機器學(xué)習包》,做了一點(diǎn)增刪修改,歡迎大家補充
  =====================================================
  3.mlpy – Machine Learning Python
  mlpy is a Python module for Machine Learning built on top of NumPy/SciPy and the GNU Scientific Libraries.
  mlpy provides a wide range of state-of-the-art machine learning methods for supervised and unsupervised problems and it is aimed at finding a reasonable compromise among modularity, maintainability, reproducibility, usability and efficiency. mlpy is multiplatform, it works with Python 2 and 3 and it is Open Source, distributed under the GNU General Public License version 3.
  官方主頁(yè):
  4.MDP:The Modular toolkit for Data Processing
  Modular toolkit for Data Processing (MDP) is a Python data processing framework.
  From the user’s perspective, MDP is a collection of supervised and unsupervised learning algorithms and other data processing units that can be combined into data processing sequences and more complex feed-forward network architectures.
  From the scientific developer’s perspective, MDP is a modular framework, which can easily be expanded. The implementation of new algorithms is easy and intuitive. The new implemented units are then automatically integrated with the rest of the library.
  The base of available algorithms is steadily increasing and includes signal processing methods (Principal Component Analysis, Independent Component Analysis, Slow Feature Analysis), manifold learning methods ([Hessian] Locally Linear Embedding), several classifiers, probabilistic methods (Factor Analysis, RBM), data pre-processing methods, and many others.
  “MDP用于數據處理的模塊化工具包,一個(gè)Python數據處理框架。 從用戶(hù)的觀(guān)點(diǎn),MDP是能夠被整合到數據處理序列和更復雜的前饋網(wǎng)絡(luò )結構的一批監督學(xué)習和非監督學(xué)習算法和其他數據處理單元。計算依照速度和內存需求而高效的執行。從科學(xué)開(kāi)發(fā)者的觀(guān)點(diǎn),MDP是一個(gè)模塊框架,它能夠被容易地擴展。新算法的實(shí)現是容易且直觀(guān)的。新實(shí)現的單元然后被自動(dòng)地與程序庫的其余部件進(jìn)行整合。MDP在神經(jīng)科學(xué)的理論研究背景下被編寫(xiě),但是它已經(jīng)被設計為在使用可訓練數據處理算法的任何情況中都是有用的。其站在用戶(hù)一邊的簡(jiǎn)單性,各種不同的隨時(shí)可用的算法,及應用單元的可重用性,使得它也是一個(gè)有用的教學(xué)工具?!?
  官方主頁(yè):
  5.PyBrain
  PyBrain is a modular Machine Learning Library for Python. Its goal is to offer flexible, easy-to-use yet still powerful algorithms for Machine Learning Tasks and a variety of predefined environments to test and compare your algorithms.
  PyBrain is short for Python-Based Reinforcement Learning, Artificial Intelligence and Neural Network Library. In fact, we came up with the name first and later reverse-engineered this quite descriptive “Backronym”.
  “PyBrain(Python-Based Reinforcement Learning, Artificial Intelligence and Neural Network)是Python的一個(gè)機器學(xué)習模塊,它的目標是為機器學(xué)習任務(wù)提供靈活、易應、強大的機器學(xué)習算法。(這名字很霸氣)
  PyBrain正如其名,包括神經(jīng)網(wǎng)絡(luò )、強化學(xué)習(及二者結合)、無(wú)監督學(xué)習、進(jìn)化算法。因為目前的許多問(wèn)題需要處理連續態(tài)和行為空間,必須使用函數逼近(如神經(jīng)網(wǎng)絡(luò ))以應對高維數據。PyBrain以神經(jīng)網(wǎng)絡(luò )為核心,所有的訓練方法都以神經(jīng)網(wǎng)絡(luò )為一個(gè)實(shí)例?!?
  官方主頁(yè):
  6.PyML– machine learning in Python
  PyML is an interactive object oriented framework for machine learning written in Python. PyML focuses on SVMs and other kernel methods. It is supported on Linux and Mac OS X.
  “PyML是一個(gè)Python機器學(xué)習工具包,為各分類(lèi)和回歸方法提供靈活的架構。它主要提供特征選擇、模型選擇、組合分類(lèi)器、分類(lèi)評估等功能?!?
  項目主頁(yè):
  7.Milk:Machine learning toolkit in Python.
  Its focus is on supervised classification with several classifiers available:
  SVMs (based on libsvm), k-NN, random forests, decision trees. It also performs
  feature selection. These classifiers can be combined in many ways to form
  different classification systems.
  “Milk是Python的一個(gè)機器學(xué)習工具箱,其重點(diǎn)是提供監督分類(lèi)法與幾種有效的分類(lèi)分析:SVMs(基于libsvm),K-NN,隨機森林經(jīng)濟和決策樹(shù)。它還可以進(jìn)行特征選擇。這些分類(lèi)可以在許多方面相結合,形成不同的分類(lèi)系統。對于無(wú)監督學(xué)習,它提供K-means和affinity propagation聚類(lèi)算法?!?
  官方主頁(yè):
  8.PyMVPA: MultiVariate Pattern Analysis (MVPA) in Python
  PyMVPA is a Python package intended to ease statistical learning analyses of large datasets. It offers an extensible framework with a high-level interface to a broad range of algorithms for classification, regression, feature selection, data import and export. It is designed to integrate well with related software packages, such as scikit-learn, and MDP. While it is not limited to the neuroimaging domain, it is eminently suited for such datasets. PyMVPA is free software and requires nothing but free-software to run.
  “PyMVPA(Multivariate Pattern Analysis in Python)是為大數據集提供統計學(xué)習分析的Python工具包,它提供了一個(gè)靈活可擴展的框架。它提供的功能有分類(lèi)、回歸、特征選擇、數據導入導出、可視化等”
  官方主頁(yè):
  9.Pyrallel– Parallel Data Analytics in Python
  Experimental project to investigate distributed computation patterns for machine learning and other semi-interactive data analytics tasks.
  “Pyrallel(Parallel Data Analytics in Python)基于分布式計算模式的機器學(xué)習和半交互式的試驗項目,可在小型集群上運行”
  Github代碼頁(yè):
  10.Monte– gradient based learning in Python
  Monte (python) is a Python framework for building gradient based learning machines, like neural networks, conditional random fields, logistic regression, etc. Monte contains modules (that hold parameters, a cost-function and a gradient-function) and trainers (that can adapt a module’s parameters by minimizing its cost-function on training data).
  Modules are usually composed of other modules, which can in turn contain other modules, etc. Gradients of decomposable systems like these can be computed with back-propagation.
  “Monte (machine learning in pure Python)是一個(gè)純Python機器學(xué)習庫。它可以迅速構建神經(jīng)網(wǎng)絡(luò )、條件隨機場(chǎng)、邏輯回歸等模型,使用inline-C優(yōu)化,極易使用和擴展?!?
  官方主頁(yè):
  11.Theano
  Theano is a Python library that allows you to define, optimize, and evaluate mathematical expressions involving multi-dimensional arrays efficiently. Theano features:
  1)tight integration with NumPy – Use numpy.ndarray in Theano-compiled functions.
  2)transparent use of a GPU – Perform data-intensive calculations up to 140x faster than with CPU.(float32 only)
  3)efficient symbolic differentiation – Theano does your derivatives for function with one or many inputs.
  4)speed and stability optimizations – Get the right answer for log(1+x) even when x is really tiny.
  5)dynamic C code generation – Evaluate expressions faster.
  6) extensive unit-testing and self-verification – Detect and diagnose many types of mistake.
  Theano has been powering large-scale computationally intensive scientific investigations since 2007. But it is also approachable enough to be used in the classroom (IFT6266 at the University of Montreal).
  “Theano 是一個(gè) Python 庫,用來(lái)定義、優(yōu)化和模擬數學(xué)表達式計算,用于高效的解決多維數組的計算問(wèn)題。Theano的特點(diǎn):緊密集成Numpy;高效的數據密集型GPU計算;高效的符號微分運算;高速和穩定的優(yōu)化;動(dòng)態(tài)生成c代碼;廣泛的單元測試和自我驗證。自2007年以來(lái),Theano已被廣泛應用于科學(xué)運算。theano使得構建深度學(xué)習模型更加容易,可以快速實(shí)現多種模型。PS:Theano,一位希臘美女,Croton最有權勢的Milo的女兒,后來(lái)成為了畢達哥拉斯的老婆?!?
  12.Pylearn2
  Pylearn2 is a machine learning library. Most of its functionality is built on top of Theano. This means you can write Pylearn2 plugins (new models, algorithms, etc) using mathematical expressions, and theano will optimize and stabilize those expressions for you, and compile them to a backend of your choice (CPU or GPU).
  “Pylearn2建立在theano上,部分依賴(lài)scikit-learn上,目前Pylearn2正處于開(kāi)發(fā)中,將可以處理向量、圖像、視頻等數據,提供MLP、RBM、SDA等深度學(xué)習模型?!?
  官方主頁(yè):
  其他的,歡迎大家補充。
  歡迎關(guān)注“牛衣古柳”
  門(mén)可羅雀,快來(lái)捕鳥(niǎo)!
  

如何用C/C++寫(xiě)一個(gè)基于事件的爬蟲(chóng)

網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 84 次瀏覽 ? 2022-06-06 17:06 ? 來(lái)自相關(guān)話(huà)題

  如何用C/C++寫(xiě)一個(gè)基于事件的爬蟲(chóng)
  
  在去年三月份的時(shí)候,寫(xiě)過(guò)一篇文章,講了一下如何寫(xiě)一個(gè)知乎爬蟲(chóng),爬下最高票的答案,并且把代碼放到了github,。在這一年多的時(shí)間里,前前后后有很多人來(lái)問(wèn)我關(guān)于這個(gè)爬蟲(chóng)的一些實(shí)現細節,在回答他們的同時(shí)發(fā)現自己原來(lái)的代碼真是寫(xiě)得太爛了,最近正好有空,把代碼和架構都重寫(xiě)了一下,不能再誤人子弟了。
  所以有了這篇文章,記錄下自己的一些改進(jìn),以及盡可能說(shuō)清楚如何用C++實(shí)現一個(gè)高性能爬蟲(chóng)。
  為什么要用C++寫(xiě)
  在繼續往下看之前一定要先想清楚一個(gè)問(wèn)題,現在用Python或者NodeJS可以非??焖俚亻_(kāi)發(fā)出一個(gè)爬蟲(chóng),庫齊全,開(kāi)發(fā)成本非常低,那為什么還要用C來(lái)寫(xiě)爬蟲(chóng)?答案是這要看你的目的。如果你單純是為了完成一個(gè)數據抓取的任務(wù),當然是任務(wù)完成得越快越好,以后代碼越好修改越好,首選就是那些庫齊全的動(dòng)態(tài)語(yǔ)言,但如果你的目的是為了理解底層系統,理解抓取數據的每一個(gè)環(huán)節,那么我的推薦是用C++寫(xiě)吧,并且所有輪子都自己造。我的目的是后者,所以選擇了用C來(lái)寫(xiě)。既然所有輪子都自己造了,那這篇文章應該叫,如何不用任何第三方庫,只用C/C++內建函數來(lái)完成一個(gè)網(wǎng)絡(luò )爬蟲(chóng)。
  用Python寫(xiě)會(huì )是什么樣子?有Requests庫來(lái)封裝HTTP請求,有BeautifulSoup來(lái)解析HTML,大大減少了開(kāi)發(fā)難度,你只需要知道爬蟲(chóng)的一般流程,很容易寫(xiě)出一個(gè)能跑的代碼,用NodeJS也是一樣的。
  知乎爬蟲(chóng)原理
  如果有讀者不太清楚爬蟲(chóng)的原理,請先看一下這篇入門(mén)文章。
  接下來(lái)簡(jiǎn)單說(shuō)一個(gè)我的zhihu爬蟲(chóng)的原理,因為我的目標是爬下最高贊/最高關(guān)注這些類(lèi)型的答案和問(wèn)題,所以從用戶(hù)主頁(yè)出發(fā)是最好不過(guò)的,比如從用戶(hù)主頁(yè)點(diǎn)擊“回答”,就可以看到用戶(hù)的所有回答,然后抓下來(lái),點(diǎn)擊“提問(wèn)”,就可以看到用戶(hù)所有的提問(wèn)。把所有用戶(hù)的所有回答/提問(wèn)都抓下來(lái)然后根據點(diǎn)贊數/關(guān)注數排序,就是我想要的結果。那所有用戶(hù)怎么得到?從一個(gè)用戶(hù)出發(fā)(即隊列中的初始URL),把TA的所有關(guān)注的人和關(guān)注者都爬下來(lái),不重復地放入URL隊列中,等到當前用戶(hù)處理完,再從URL隊列里拿下一個(gè)用戶(hù),如此循環(huán)即可。
  仔細想想,這個(gè)方法會(huì )有一個(gè)問(wèn)題,如果一個(gè)人即不關(guān)注別人也不被別人關(guān)注,且不在初始URL隊列中,那么這個(gè)用戶(hù)的回答和提問(wèn)永遠不會(huì )被抓到。更一般的結論是,如果有用戶(hù)群構成“孤島”,那么這些用戶(hù)群都不會(huì )被爬蟲(chóng)訪(fǎng)問(wèn)。舉個(gè)例子,A、B互相關(guān)注,C、D互相關(guān)注,如果我們將A放入初始URL隊列,那么爬蟲(chóng)只可能抓下A、B的數據,因為C、D構成了“孤島”,怎么解決這個(gè)問(wèn)題?
  再想想,這個(gè)問(wèn)題真的有必要解決嗎?這個(gè)問(wèn)題會(huì )對我們造成困擾的情況是,一個(gè)大V答了一個(gè)贊數很高的問(wèn)題,但是TA竟然在某座“孤島”上,如果我們稱(chēng)大部分人所構成的連通圖叫主圖,那么這個(gè)大V構成的“孤島”和主圖上的人一點(diǎn)關(guān)系都沒(méi)有,即不被關(guān)注也不關(guān)注別人,這幾乎是不可能的事情,所以這個(gè)問(wèn)題不需要解決。
  如何用C++寫(xiě)爬蟲(chóng)
  無(wú)論用Python或者C++寫(xiě)爬蟲(chóng),底層都是一樣的,都是和server建立若干個(gè)TCP連接,然后把HTTP請求寫(xiě)入這個(gè)TCP socket中,等待server的數據返回。為了高效處理I/O,在linux平臺下需要用epoll(別的平臺請用各自的機制)。
  所以一個(gè)C++爬蟲(chóng)步驟大概是這樣的,本質(zhì)上就是一個(gè)事件循環(huán)(event loop):
  初始化epoll,并和server建立TCP連接
  從URL隊列中拿出url,并準備好http請求
  將http請求寫(xiě)入到這個(gè)TCP socket中,并把這個(gè)socket加入epoll中
  檢查活動(dòng)事件(epoll_wait)
  處理事件,讀取HTML,解析HTML,處理HTML,然后把相關(guān)未處理過(guò)的URL放入URL隊列中
  回到第2步
  原來(lái)的代碼結構
  先簡(jiǎn)單描述一下去年寫(xiě)的爬蟲(chóng)代碼是怎么誤人子弟的。
  程序從隊列里拿到一個(gè)URL后,需要去下載這個(gè)URL的頁(yè)面,解析出我需要的數據,然后把它的下一層URL加入隊列中。原來(lái)的爬蟲(chóng)代碼就老老實(shí)實(shí)地實(shí)現了這個(gè)步驟,阻塞地等待頁(yè)面下載完成,再去處理這個(gè)頁(yè)面。其實(shí)這是很低效的,因為阻塞的這段時(shí)期我們什么都干不了,浪費了帶寬。為什么不把隊列里的其它URL請求一起發(fā)出去呢,然后有數據來(lái)了我就處理。這就是為什么爬蟲(chóng)為什么要用基于事件來(lái)寫(xiě)的原因。
  這里需要理解爬蟲(chóng)這種程序的本質(zhì),它是網(wǎng)絡(luò )I/O密集程序,不是CPU密集,而處理I/O密集最高效的做法就是事件循環(huán)。
  所以我做的一個(gè)做大的改善就是把原來(lái)的阻塞爬蟲(chóng)改成了基于事件的爬蟲(chóng),它得到的好處是可以完全把帶寬跑滿(mǎn),爬取速度最大化。
  除此之外,還有一個(gè)改善是把多線(xiàn)程模型改成了單進(jìn)程模型。有同學(xué)可能會(huì )產(chǎn)生疑惑,難道利用多核還會(huì )比單核性能差?我們從以下兩點(diǎn)來(lái)分析:
  根據amdahl定律,對系統中一個(gè)模塊的加速,不僅取決于加速比,還取決于這個(gè)模塊在原來(lái)系統中占的比例。爬蟲(chóng)是I/O密集程序,絕大部分時(shí)間都花在了網(wǎng)絡(luò )I/O上,CPU大部分時(shí)間是空閑的,所以提高CPU的利用率其實(shí)效果很小。
  多線(xiàn)程會(huì )引入額外的開(kāi)銷(xiāo),最大的開(kāi)銷(xiāo)可能就是鎖了。比如你要把新的URL加入隊列,這時(shí)候在多線(xiàn)程環(huán)境下肯定要對隊列加鎖。
  那么問(wèn)題就是,第一點(diǎn)所帶來(lái)的性能提升和第二點(diǎn)所帶來(lái)的開(kāi)銷(xiāo),哪個(gè)更大一點(diǎn)?如果第二點(diǎn)大,我們果斷要換成單進(jìn)程。答案是看環(huán)境,我們極端點(diǎn)看,如果你的帶寬無(wú)窮大,網(wǎng)絡(luò )情況無(wú)窮好,那么請求一發(fā)出去立刻就回復了,這個(gè)網(wǎng)絡(luò )I/O密集程序硬生生變成了CPU密集,多線(xiàn)程會(huì )好;如果你的帶寬無(wú)窮小,那么鎖帶來(lái)的開(kāi)銷(xiāo)會(huì )占比更大,一個(gè)任務(wù)來(lái)了多線(xiàn)程之間還要競爭一下,單線(xiàn)程就直接處理了且沒(méi)有鎖的性能開(kāi)銷(xiāo),用單線(xiàn)程會(huì )好。我們需要在不同的環(huán)境下選擇最好的辦法,不過(guò)一般來(lái)說(shuō),現實(shí)中最大的時(shí)間開(kāi)銷(xiāo)一定在網(wǎng)絡(luò )I/O。
  用C++實(shí)現爬蟲(chóng)時(shí)的難點(diǎn)
  從TCP socket讀取數據到把完整的HTML數據交付上層需要一個(gè)數據層,因為如果調用read返回EAGAIN時(shí),這時(shí)是不知道到底有沒(méi)有接受到完整的HTML,需要保存好當前讀到的網(wǎng)頁(yè)內容,并通過(guò)一個(gè)狀態(tài)機來(lái)解析當前收到的數據,保存當前的狀態(tài),如果解析完成(讀到全部數據了)就返回SUCCESS,否則就就返回ERROR,等待下一次數據來(lái)臨,繼續解析狀態(tài)機。用動(dòng)態(tài)語(yǔ)言不需要考慮這一點(diǎn),會(huì )直接傳遞給用戶(hù)層完整的數據。
  請求得太快,知乎會(huì )返回429錯誤(即提示客戶(hù)請求太多,稍后再試),這個(gè)問(wèn)題怎么解決?乖乖地等待一段時(shí)間再去抓是一種浪費帶寬的行為。服務(wù)器判斷請求太多是看這個(gè)IP在一段時(shí)間的請求數太多了,如果我們IP分散為N個(gè)不同IP,那就解決這個(gè)問(wèn)題了。這個(gè)方案叫動(dòng)態(tài)IP或者代理IP。那么多IP意味著(zhù)要花很多的錢(qián),如果不愿意花錢(qián),還是乖乖等一段時(shí)間再發(fā)請求吧。
  爬蟲(chóng)里一個(gè)需求,要獲得一個(gè)用戶(hù)的所有關(guān)注的人和關(guān)注者,但這些東西都是通過(guò)ajax獲取的,所以要寫(xiě)一個(gè)post請求來(lái)模擬ajax。其中post data里有一個(gè)hash_id和_xsrf,這兩個(gè)值都在哪里可以獲得?后來(lái)在該用戶(hù)的主頁(yè)的HTML里找到了這兩個(gè)值。
  怎么用C++解析HTML?比如上面一點(diǎn)提到的,我要找到這個(gè)頁(yè)面里的hash_id,它可能是某個(gè)HTML元素的屬性,怎么得到這個(gè)屬性值?用過(guò)JQuery的同學(xué)這時(shí)會(huì )想,如果C++里面也有一個(gè)像JQuery那么好用的庫該多好,直接寫(xiě)個(gè)選擇器就獲得屬性的值了。我簡(jiǎn)單地調研了一下,C++還是有這樣的庫的?;趯W(xué)習的目的,最好自己寫(xiě)一個(gè)這樣的庫,所以,問(wèn)題來(lái)了,怎么實(shí)現一個(gè)HTML parser?或者更簡(jiǎn)單的,怎么實(shí)現一個(gè)正則匹配?
  如何管理一個(gè)請求的周期,因為一個(gè)請求的周期中,狀態(tài)太多了。為什么狀態(tài)多,因為一個(gè)請求會(huì )涉及很多異步操作,首先獲取該用戶(hù)的答案頁(yè)面,這時(shí)候要等待server的回復,處理完以后獲得改用戶(hù)所有關(guān)注的人和關(guān)注者的頁(yè)面,也要等待server的回復,再把這些所有用戶(hù)加入隊列后,這個(gè)請求周期才算結束。
  需要自己處理一些HTTP header的細節。比如不希望接受到HTTP response header里Transfer Encoding: chuncked回復,因為它顯然沒(méi)有Content-length直接獲取到數據長(cháng)度來(lái)得方便,該怎么辦?再比如不希望接受到gzip處理過(guò)的數據,希望收到plain text,又該怎么辦?
  架構怎么設計。首先最底層是TCP層,上層應該封裝一個(gè)數據接收層,再上層應該是HTML解析層,最后是事件循環(huán)層。這些層次/模塊怎么做到耦合度最低?
  網(wǎng)絡(luò )異常怎么處理,比如read返回error(eg Connection reset by peer),或者EOF。EOF需要重新建立一個(gè)新的連接,然后繼續前一個(gè)請求(或者說(shuō)繼續狀態(tài)機)。
  用C++相比Python,NodeJS的優(yōu)點(diǎn)
  系統的掌控性。比如我們希望TCP連接數要控制在1000,完全可能很容易地實(shí)現。并且可以知道哪里會(huì )耗內存、CPU,底層在發(fā)生什么我們更容易知道。比如,在HTTP request header里寫(xiě)上Connection: keep-alive可以讓很多請求復用一個(gè)TCP連接,在用C++實(shí)現的時(shí)候,對應的實(shí)現方法很簡(jiǎn)單粗暴:從socket讀完對方服務(wù)器發(fā)來(lái)的response后,再構造一個(gè)header發(fā)過(guò)去即可。
  因為一些內建庫的缺乏,并且出發(fā)點(diǎn)是學(xué)習,我們會(huì )重新造一些輪子,與此同時(shí),提高了編程能力。 比如說(shuō)讀配置文件,格式是json,可以自己用C寫(xiě)個(gè)json parser。再比如上文提到的HTML parser,也可以用C寫(xiě)一個(gè),還有基于epoll的事件循環(huán),可以抽象成一個(gè)通用的網(wǎng)絡(luò )庫。有太多輪子可以造,要把其中任意一個(gè)輪子寫(xiě)好都是非常難的事情。
  高性能??赡苡捎诰W(wǎng)絡(luò )的大延遲使得這個(gè)優(yōu)點(diǎn)不那么明顯。
  總結
  本文基于我一年多之前寫(xiě)的zhihu爬蟲(chóng)以及最近的大規模改進(jìn),總結了如何用C++編寫(xiě)的高效、基于事件驅動(dòng)的知乎爬蟲(chóng),同時(shí)也列出了用C++寫(xiě)爬蟲(chóng)時(shí)的一些難點(diǎn)與收獲。
  如果你有興趣看看竟然有人用C++寫(xiě)了一個(gè)爬蟲(chóng)究竟是什么樣子的,代碼在這里。
  . END.
  看完本文請分享一下吧!讓其他人也可以GET到新知識!
   查看全部

  如何用C/C++寫(xiě)一個(gè)基于事件的爬蟲(chóng)
  
  在去年三月份的時(shí)候,寫(xiě)過(guò)一篇文章,講了一下如何寫(xiě)一個(gè)知乎爬蟲(chóng),爬下最高票的答案,并且把代碼放到了github,。在這一年多的時(shí)間里,前前后后有很多人來(lái)問(wèn)我關(guān)于這個(gè)爬蟲(chóng)的一些實(shí)現細節,在回答他們的同時(shí)發(fā)現自己原來(lái)的代碼真是寫(xiě)得太爛了,最近正好有空,把代碼和架構都重寫(xiě)了一下,不能再誤人子弟了。
  所以有了這篇文章,記錄下自己的一些改進(jìn),以及盡可能說(shuō)清楚如何用C++實(shí)現一個(gè)高性能爬蟲(chóng)。
  為什么要用C++寫(xiě)
  在繼續往下看之前一定要先想清楚一個(gè)問(wèn)題,現在用Python或者NodeJS可以非??焖俚亻_(kāi)發(fā)出一個(gè)爬蟲(chóng),庫齊全,開(kāi)發(fā)成本非常低,那為什么還要用C來(lái)寫(xiě)爬蟲(chóng)?答案是這要看你的目的。如果你單純是為了完成一個(gè)數據抓取的任務(wù),當然是任務(wù)完成得越快越好,以后代碼越好修改越好,首選就是那些庫齊全的動(dòng)態(tài)語(yǔ)言,但如果你的目的是為了理解底層系統,理解抓取數據的每一個(gè)環(huán)節,那么我的推薦是用C++寫(xiě)吧,并且所有輪子都自己造。我的目的是后者,所以選擇了用C來(lái)寫(xiě)。既然所有輪子都自己造了,那這篇文章應該叫,如何不用任何第三方庫,只用C/C++內建函數來(lái)完成一個(gè)網(wǎng)絡(luò )爬蟲(chóng)。
  用Python寫(xiě)會(huì )是什么樣子?有Requests庫來(lái)封裝HTTP請求,有BeautifulSoup來(lái)解析HTML,大大減少了開(kāi)發(fā)難度,你只需要知道爬蟲(chóng)的一般流程,很容易寫(xiě)出一個(gè)能跑的代碼,用NodeJS也是一樣的。
  知乎爬蟲(chóng)原理
  如果有讀者不太清楚爬蟲(chóng)的原理,請先看一下這篇入門(mén)文章。
  接下來(lái)簡(jiǎn)單說(shuō)一個(gè)我的zhihu爬蟲(chóng)的原理,因為我的目標是爬下最高贊/最高關(guān)注這些類(lèi)型的答案和問(wèn)題,所以從用戶(hù)主頁(yè)出發(fā)是最好不過(guò)的,比如從用戶(hù)主頁(yè)點(diǎn)擊“回答”,就可以看到用戶(hù)的所有回答,然后抓下來(lái),點(diǎn)擊“提問(wèn)”,就可以看到用戶(hù)所有的提問(wèn)。把所有用戶(hù)的所有回答/提問(wèn)都抓下來(lái)然后根據點(diǎn)贊數/關(guān)注數排序,就是我想要的結果。那所有用戶(hù)怎么得到?從一個(gè)用戶(hù)出發(fā)(即隊列中的初始URL),把TA的所有關(guān)注的人和關(guān)注者都爬下來(lái),不重復地放入URL隊列中,等到當前用戶(hù)處理完,再從URL隊列里拿下一個(gè)用戶(hù),如此循環(huán)即可。
  仔細想想,這個(gè)方法會(huì )有一個(gè)問(wèn)題,如果一個(gè)人即不關(guān)注別人也不被別人關(guān)注,且不在初始URL隊列中,那么這個(gè)用戶(hù)的回答和提問(wèn)永遠不會(huì )被抓到。更一般的結論是,如果有用戶(hù)群構成“孤島”,那么這些用戶(hù)群都不會(huì )被爬蟲(chóng)訪(fǎng)問(wèn)。舉個(gè)例子,A、B互相關(guān)注,C、D互相關(guān)注,如果我們將A放入初始URL隊列,那么爬蟲(chóng)只可能抓下A、B的數據,因為C、D構成了“孤島”,怎么解決這個(gè)問(wèn)題?
  再想想,這個(gè)問(wèn)題真的有必要解決嗎?這個(gè)問(wèn)題會(huì )對我們造成困擾的情況是,一個(gè)大V答了一個(gè)贊數很高的問(wèn)題,但是TA竟然在某座“孤島”上,如果我們稱(chēng)大部分人所構成的連通圖叫主圖,那么這個(gè)大V構成的“孤島”和主圖上的人一點(diǎn)關(guān)系都沒(méi)有,即不被關(guān)注也不關(guān)注別人,這幾乎是不可能的事情,所以這個(gè)問(wèn)題不需要解決。
  如何用C++寫(xiě)爬蟲(chóng)
  無(wú)論用Python或者C++寫(xiě)爬蟲(chóng),底層都是一樣的,都是和server建立若干個(gè)TCP連接,然后把HTTP請求寫(xiě)入這個(gè)TCP socket中,等待server的數據返回。為了高效處理I/O,在linux平臺下需要用epoll(別的平臺請用各自的機制)。
  所以一個(gè)C++爬蟲(chóng)步驟大概是這樣的,本質(zhì)上就是一個(gè)事件循環(huán)(event loop):
  初始化epoll,并和server建立TCP連接
  從URL隊列中拿出url,并準備好http請求
  將http請求寫(xiě)入到這個(gè)TCP socket中,并把這個(gè)socket加入epoll中
  檢查活動(dòng)事件(epoll_wait)
  處理事件,讀取HTML,解析HTML,處理HTML,然后把相關(guān)未處理過(guò)的URL放入URL隊列中
  回到第2步
  原來(lái)的代碼結構
  先簡(jiǎn)單描述一下去年寫(xiě)的爬蟲(chóng)代碼是怎么誤人子弟的。
  程序從隊列里拿到一個(gè)URL后,需要去下載這個(gè)URL的頁(yè)面,解析出我需要的數據,然后把它的下一層URL加入隊列中。原來(lái)的爬蟲(chóng)代碼就老老實(shí)實(shí)地實(shí)現了這個(gè)步驟,阻塞地等待頁(yè)面下載完成,再去處理這個(gè)頁(yè)面。其實(shí)這是很低效的,因為阻塞的這段時(shí)期我們什么都干不了,浪費了帶寬。為什么不把隊列里的其它URL請求一起發(fā)出去呢,然后有數據來(lái)了我就處理。這就是為什么爬蟲(chóng)為什么要用基于事件來(lái)寫(xiě)的原因。
  這里需要理解爬蟲(chóng)這種程序的本質(zhì),它是網(wǎng)絡(luò )I/O密集程序,不是CPU密集,而處理I/O密集最高效的做法就是事件循環(huán)。
  所以我做的一個(gè)做大的改善就是把原來(lái)的阻塞爬蟲(chóng)改成了基于事件的爬蟲(chóng),它得到的好處是可以完全把帶寬跑滿(mǎn),爬取速度最大化。
  除此之外,還有一個(gè)改善是把多線(xiàn)程模型改成了單進(jìn)程模型。有同學(xué)可能會(huì )產(chǎn)生疑惑,難道利用多核還會(huì )比單核性能差?我們從以下兩點(diǎn)來(lái)分析:
  根據amdahl定律,對系統中一個(gè)模塊的加速,不僅取決于加速比,還取決于這個(gè)模塊在原來(lái)系統中占的比例。爬蟲(chóng)是I/O密集程序,絕大部分時(shí)間都花在了網(wǎng)絡(luò )I/O上,CPU大部分時(shí)間是空閑的,所以提高CPU的利用率其實(shí)效果很小。
  多線(xiàn)程會(huì )引入額外的開(kāi)銷(xiāo),最大的開(kāi)銷(xiāo)可能就是鎖了。比如你要把新的URL加入隊列,這時(shí)候在多線(xiàn)程環(huán)境下肯定要對隊列加鎖。
  那么問(wèn)題就是,第一點(diǎn)所帶來(lái)的性能提升和第二點(diǎn)所帶來(lái)的開(kāi)銷(xiāo),哪個(gè)更大一點(diǎn)?如果第二點(diǎn)大,我們果斷要換成單進(jìn)程。答案是看環(huán)境,我們極端點(diǎn)看,如果你的帶寬無(wú)窮大,網(wǎng)絡(luò )情況無(wú)窮好,那么請求一發(fā)出去立刻就回復了,這個(gè)網(wǎng)絡(luò )I/O密集程序硬生生變成了CPU密集,多線(xiàn)程會(huì )好;如果你的帶寬無(wú)窮小,那么鎖帶來(lái)的開(kāi)銷(xiāo)會(huì )占比更大,一個(gè)任務(wù)來(lái)了多線(xiàn)程之間還要競爭一下,單線(xiàn)程就直接處理了且沒(méi)有鎖的性能開(kāi)銷(xiāo),用單線(xiàn)程會(huì )好。我們需要在不同的環(huán)境下選擇最好的辦法,不過(guò)一般來(lái)說(shuō),現實(shí)中最大的時(shí)間開(kāi)銷(xiāo)一定在網(wǎng)絡(luò )I/O。
  用C++實(shí)現爬蟲(chóng)時(shí)的難點(diǎn)
  從TCP socket讀取數據到把完整的HTML數據交付上層需要一個(gè)數據層,因為如果調用read返回EAGAIN時(shí),這時(shí)是不知道到底有沒(méi)有接受到完整的HTML,需要保存好當前讀到的網(wǎng)頁(yè)內容,并通過(guò)一個(gè)狀態(tài)機來(lái)解析當前收到的數據,保存當前的狀態(tài),如果解析完成(讀到全部數據了)就返回SUCCESS,否則就就返回ERROR,等待下一次數據來(lái)臨,繼續解析狀態(tài)機。用動(dòng)態(tài)語(yǔ)言不需要考慮這一點(diǎn),會(huì )直接傳遞給用戶(hù)層完整的數據。
  請求得太快,知乎會(huì )返回429錯誤(即提示客戶(hù)請求太多,稍后再試),這個(gè)問(wèn)題怎么解決?乖乖地等待一段時(shí)間再去抓是一種浪費帶寬的行為。服務(wù)器判斷請求太多是看這個(gè)IP在一段時(shí)間的請求數太多了,如果我們IP分散為N個(gè)不同IP,那就解決這個(gè)問(wèn)題了。這個(gè)方案叫動(dòng)態(tài)IP或者代理IP。那么多IP意味著(zhù)要花很多的錢(qián),如果不愿意花錢(qián),還是乖乖等一段時(shí)間再發(fā)請求吧。
  爬蟲(chóng)里一個(gè)需求,要獲得一個(gè)用戶(hù)的所有關(guān)注的人和關(guān)注者,但這些東西都是通過(guò)ajax獲取的,所以要寫(xiě)一個(gè)post請求來(lái)模擬ajax。其中post data里有一個(gè)hash_id和_xsrf,這兩個(gè)值都在哪里可以獲得?后來(lái)在該用戶(hù)的主頁(yè)的HTML里找到了這兩個(gè)值。
  怎么用C++解析HTML?比如上面一點(diǎn)提到的,我要找到這個(gè)頁(yè)面里的hash_id,它可能是某個(gè)HTML元素的屬性,怎么得到這個(gè)屬性值?用過(guò)JQuery的同學(xué)這時(shí)會(huì )想,如果C++里面也有一個(gè)像JQuery那么好用的庫該多好,直接寫(xiě)個(gè)選擇器就獲得屬性的值了。我簡(jiǎn)單地調研了一下,C++還是有這樣的庫的?;趯W(xué)習的目的,最好自己寫(xiě)一個(gè)這樣的庫,所以,問(wèn)題來(lái)了,怎么實(shí)現一個(gè)HTML parser?或者更簡(jiǎn)單的,怎么實(shí)現一個(gè)正則匹配?
  如何管理一個(gè)請求的周期,因為一個(gè)請求的周期中,狀態(tài)太多了。為什么狀態(tài)多,因為一個(gè)請求會(huì )涉及很多異步操作,首先獲取該用戶(hù)的答案頁(yè)面,這時(shí)候要等待server的回復,處理完以后獲得改用戶(hù)所有關(guān)注的人和關(guān)注者的頁(yè)面,也要等待server的回復,再把這些所有用戶(hù)加入隊列后,這個(gè)請求周期才算結束。
  需要自己處理一些HTTP header的細節。比如不希望接受到HTTP response header里Transfer Encoding: chuncked回復,因為它顯然沒(méi)有Content-length直接獲取到數據長(cháng)度來(lái)得方便,該怎么辦?再比如不希望接受到gzip處理過(guò)的數據,希望收到plain text,又該怎么辦?
  架構怎么設計。首先最底層是TCP層,上層應該封裝一個(gè)數據接收層,再上層應該是HTML解析層,最后是事件循環(huán)層。這些層次/模塊怎么做到耦合度最低?
  網(wǎng)絡(luò )異常怎么處理,比如read返回error(eg Connection reset by peer),或者EOF。EOF需要重新建立一個(gè)新的連接,然后繼續前一個(gè)請求(或者說(shuō)繼續狀態(tài)機)。
  用C++相比Python,NodeJS的優(yōu)點(diǎn)
  系統的掌控性。比如我們希望TCP連接數要控制在1000,完全可能很容易地實(shí)現。并且可以知道哪里會(huì )耗內存、CPU,底層在發(fā)生什么我們更容易知道。比如,在HTTP request header里寫(xiě)上Connection: keep-alive可以讓很多請求復用一個(gè)TCP連接,在用C++實(shí)現的時(shí)候,對應的實(shí)現方法很簡(jiǎn)單粗暴:從socket讀完對方服務(wù)器發(fā)來(lái)的response后,再構造一個(gè)header發(fā)過(guò)去即可。
  因為一些內建庫的缺乏,并且出發(fā)點(diǎn)是學(xué)習,我們會(huì )重新造一些輪子,與此同時(shí),提高了編程能力。 比如說(shuō)讀配置文件,格式是json,可以自己用C寫(xiě)個(gè)json parser。再比如上文提到的HTML parser,也可以用C寫(xiě)一個(gè),還有基于epoll的事件循環(huán),可以抽象成一個(gè)通用的網(wǎng)絡(luò )庫。有太多輪子可以造,要把其中任意一個(gè)輪子寫(xiě)好都是非常難的事情。
  高性能??赡苡捎诰W(wǎng)絡(luò )的大延遲使得這個(gè)優(yōu)點(diǎn)不那么明顯。
  總結
  本文基于我一年多之前寫(xiě)的zhihu爬蟲(chóng)以及最近的大規模改進(jìn),總結了如何用C++編寫(xiě)的高效、基于事件驅動(dòng)的知乎爬蟲(chóng),同時(shí)也列出了用C++寫(xiě)爬蟲(chóng)時(shí)的一些難點(diǎn)與收獲。
  如果你有興趣看看竟然有人用C++寫(xiě)了一個(gè)爬蟲(chóng)究竟是什么樣子的,代碼在這里。
  . END.
  看完本文請分享一下吧!讓其他人也可以GET到新知識!
  

網(wǎng)站將用戶(hù)資料分門(mén)別類(lèi)的存儲在百度中

網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 77 次瀏覽 ? 2022-06-05 16:01 ? 來(lái)自相關(guān)話(huà)題

  網(wǎng)站將用戶(hù)資料分門(mén)別類(lèi)的存儲在百度中
  c爬蟲(chóng)抓取網(wǎng)頁(yè)數據,可以得到我們想要的各種格式的數據用戶(hù)信息是可以作為數據有價(jià)值的獲取來(lái)源。比如一個(gè)網(wǎng)站將用戶(hù)資料分門(mén)別類(lèi)的存儲在百度中,那么用戶(hù)不僅可以接受百度的url信息,還可以查看百度收錄了哪些對自己有用的用戶(hù)信息。根據產(chǎn)品上線(xiàn)的數據質(zhì)量對用戶(hù)信息的價(jià)值進(jìn)行確定,在這里對用戶(hù)信息的價(jià)值分為初級價(jià)值、中級價(jià)值、高級價(jià)值三類(lèi)(根據產(chǎn)品和相關(guān)業(yè)務(wù)流程的特征進(jìn)行下劃分),初級價(jià)值比如xxx寶馬集團電子商務(wù)平臺用戶(hù)在購物車(chē)不只是購買(mǎi)自己想要的產(chǎn)品,還可以查看新推薦的商品、查看優(yōu)惠券的使用情況中級價(jià)值比如xxx寶馬集團電子商務(wù)平臺用戶(hù)在購物車(chē)不只是購買(mǎi)自己想要的產(chǎn)品,還可以查看優(yōu)惠券的使用情況高級價(jià)值比如某寶同城生活服務(wù)平臺的用戶(hù)在微信上獲取到完整圖片視頻等內容的用戶(hù)信息通過(guò)以上的分類(lèi),一般可以根據產(chǎn)品的定位將用戶(hù)信息劃分出來(lái),放到哪里去獲取都可以。info_data_name。
  根據業(yè)務(wù)特征選擇,設計合理的信息模型和鏈路,及時(shí)對信息進(jìn)行處理對網(wǎng)頁(yè)中的信息進(jìn)行解析,提取信息特征,并儲存起來(lái)需要獲取什么樣的信息信息以數據庫的形式存儲即可,沒(méi)有特定指標來(lái)要求儲存速度,txt或者json,提取關(guān)鍵字,把抽象內容鏈接到一起即可,最重要的是全量的準確性,保證準確性的一點(diǎn)是有足夠快的讀寫(xiě)速度。
  對于廣告業(yè)務(wù)而言,定制特征是非常重要的,比如有的廣告有固定的位置標識、pagerank、ctr特征等等,然后如果參與定制特征的平臺多,定制特征的粒度夠細的話(huà),本地數據庫的使用率會(huì )比較低對數據進(jìn)行分類(lèi)管理,類(lèi)似etl,用一定的算法和策略將所有的存儲到不同數據庫中去如果需要進(jìn)行分析,可以自己對業(yè)務(wù)、流程進(jìn)行重構,比如:消息隊列,過(guò)濾流程,負載均衡等等,將不同的業(yè)務(wù)特征,流程拆分成不同粒度的數據倉庫。 查看全部

  網(wǎng)站將用戶(hù)資料分門(mén)別類(lèi)的存儲在百度中
  c爬蟲(chóng)抓取網(wǎng)頁(yè)數據,可以得到我們想要的各種格式的數據用戶(hù)信息是可以作為數據有價(jià)值的獲取來(lái)源。比如一個(gè)網(wǎng)站將用戶(hù)資料分門(mén)別類(lèi)的存儲在百度中,那么用戶(hù)不僅可以接受百度的url信息,還可以查看百度收錄了哪些對自己有用的用戶(hù)信息。根據產(chǎn)品上線(xiàn)的數據質(zhì)量對用戶(hù)信息的價(jià)值進(jìn)行確定,在這里對用戶(hù)信息的價(jià)值分為初級價(jià)值、中級價(jià)值、高級價(jià)值三類(lèi)(根據產(chǎn)品和相關(guān)業(yè)務(wù)流程的特征進(jìn)行下劃分),初級價(jià)值比如xxx寶馬集團電子商務(wù)平臺用戶(hù)在購物車(chē)不只是購買(mǎi)自己想要的產(chǎn)品,還可以查看新推薦的商品、查看優(yōu)惠券的使用情況中級價(jià)值比如xxx寶馬集團電子商務(wù)平臺用戶(hù)在購物車(chē)不只是購買(mǎi)自己想要的產(chǎn)品,還可以查看優(yōu)惠券的使用情況高級價(jià)值比如某寶同城生活服務(wù)平臺的用戶(hù)在微信上獲取到完整圖片視頻等內容的用戶(hù)信息通過(guò)以上的分類(lèi),一般可以根據產(chǎn)品的定位將用戶(hù)信息劃分出來(lái),放到哪里去獲取都可以。info_data_name。
  根據業(yè)務(wù)特征選擇,設計合理的信息模型和鏈路,及時(shí)對信息進(jìn)行處理對網(wǎng)頁(yè)中的信息進(jìn)行解析,提取信息特征,并儲存起來(lái)需要獲取什么樣的信息信息以數據庫的形式存儲即可,沒(méi)有特定指標來(lái)要求儲存速度,txt或者json,提取關(guān)鍵字,把抽象內容鏈接到一起即可,最重要的是全量的準確性,保證準確性的一點(diǎn)是有足夠快的讀寫(xiě)速度。
  對于廣告業(yè)務(wù)而言,定制特征是非常重要的,比如有的廣告有固定的位置標識、pagerank、ctr特征等等,然后如果參與定制特征的平臺多,定制特征的粒度夠細的話(huà),本地數據庫的使用率會(huì )比較低對數據進(jìn)行分類(lèi)管理,類(lèi)似etl,用一定的算法和策略將所有的存儲到不同數據庫中去如果需要進(jìn)行分析,可以自己對業(yè)務(wù)、流程進(jìn)行重構,比如:消息隊列,過(guò)濾流程,負載均衡等等,將不同的業(yè)務(wù)特征,流程拆分成不同粒度的數據倉庫。

如何構建一個(gè)分布式爬蟲(chóng):實(shí)戰篇

網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 87 次瀏覽 ? 2022-06-05 05:09 ? 來(lái)自相關(guān)話(huà)題

  如何構建一個(gè)分布式爬蟲(chóng):實(shí)戰篇
  
  種子博主具體信息
  這里我們就看到了他的具體信息了。然后,我們看該頁(yè)面的 url 構造
  我直接 copy 的地址欄的 url。這樣做有啥不好的呢?對于老鳥(niǎo)來(lái)說(shuō),一下就看出來(lái)了,這樣做的話(huà),可能會(huì )導致信息不全,因為可能有些信息是動(dòng)態(tài)加載的。所以,我們需要通過(guò)抓包來(lái)判斷到底微博會(huì )通過(guò)該 url 返回所有信息,還是需要請求一些 ajax 鏈接才會(huì )返回一些關(guān)鍵信息。這里我就重復一下我的觀(guān)點(diǎn):抓包很重要,抓包很重要,抓包很重要!重要的事情說(shuō)三遍。關(guān)于抓包,我在模擬登陸微博和模擬登陸百度云都詳細講過(guò)了,這里我就不講了。
  我們抓完包,發(fā)現并沒(méi)有 ajax 請求。那么可以肯定請求前面的 url,會(huì )返回所有信息。我們通過(guò)點(diǎn)擊鼠標右鍵,查看網(wǎng)頁(yè)源代碼,然后ctrl a、ctrl c將所有的頁(yè)面源碼保存到本地,這里我命名為personinfo.html。我們用瀏覽器打開(kāi)該文件,發(fā)現我們需要的所有信息都在這段源碼中,這個(gè)工作和抓包判斷數據是否全面有些重復,但是在我看來(lái)是必不可少的,因為我們解析頁(yè)面數據的時(shí)候還可以用到這個(gè) html 文件,如果我們每次都通過(guò)網(wǎng)絡(luò )請求去解析內容的話(huà),那么可能賬號沒(méi)一會(huì )兒就會(huì )被封了(因為頻繁訪(fǎng)問(wèn)微博信息),所以我們需要把要解析的文件保存到本地。
  從上面分析中我們可以得知
  這個(gè) url 就是獲取用戶(hù)數據的 url。那么我們在只知道用戶(hù) id 的時(shí)候怎么構造它呢?我們可以多拿幾個(gè)用戶(hù) id 來(lái)做測試,看構造是否有規律,比如我這里以用戶(hù)名為網(wǎng)易云音樂(lè )的用戶(hù)做分析,發(fā)現它的用戶(hù)信息頁(yè)面構造如下
  這個(gè)就和上面那個(gè)不同了。但是我們仔細觀(guān)察,可以發(fā)現上面那個(gè)是個(gè)人用戶(hù),下面是企業(yè)微博用戶(hù)。我們嘗試一下把它們 url 格式都統一為第一種或者第二種的格式
  這樣會(huì )出現 404,那么統一成上面那種呢?
  這樣子的話(huà),它會(huì )被重定向到用戶(hù)主頁(yè),而不是用戶(hù)詳細資料頁(yè)。所以也就不對了。那么該以什么依據判斷何時(shí)用第一種 url 格式,何時(shí)用第二種 url 格式呢?我們多翻幾個(gè)用戶(hù),會(huì )發(fā)現除了100505之外,還有100305、100206等前綴,那么我猜想這個(gè)應該可以區分不同用戶(hù)。這個(gè)前綴在哪里可以得到呢?我們打開(kāi)我們剛保存的頁(yè)面源碼,搜索100505,可以發(fā)現
  
  domain
  微博應該是根據這個(gè)來(lái)區分不同用戶(hù)類(lèi)型的。這里大家可以自己也可以試試,看不同用戶(hù)的domain是否不同。為了數據能全面,我也是做了大量測試,發(fā)現個(gè)人用戶(hù)的 domain 是1005051,作家是100305,其他基本都是認證的企業(yè)號。前兩個(gè)個(gè)人信息的 url 構造就是
  后者的是
  弄清楚了個(gè)人信息 url 的構造方式,但是還有一個(gè)問(wèn)題。我們已知只有 uid 啊,沒(méi)有 domain 啊。如果是企業(yè)號,我們通過(guò)domain=100505會(huì )被重定向到主頁(yè),如果是作家等(domain=100305 或者 100306),也會(huì )被重定向主頁(yè)。我們在主頁(yè)把 domain 提取出來(lái),再請求一次,不就能拿到用戶(hù)詳細信息了嗎?
  關(guān)于如何構造獲取用戶(hù)信息的 url 的相關(guān)分析就到這里了。因為我們是在登錄的情況下進(jìn)行數據抓取的,可能在抓取的時(shí)候,某個(gè)賬號突然就被封了,或者由于網(wǎng)絡(luò )原因,某次請求失敗了,該如何處理?對于前者,我們需要判斷每次請求返回的內容是否符合預期,也就是看 response url 是否正常,看 response content 是否是 404 或者讓你驗證手機號等,對于后者,我們可以做一個(gè)簡(jiǎn)單的重試策略,大概代碼如下
  <p>@timeout_decorator
  def get_page(url, user_verify=True, need_login=True):
   ? ?"""
   ? ?:param url: 待抓取 url
   ? ?:param user_verify: 是否為可能出現驗證碼的頁(yè)面(ajax 連接不會(huì )出現驗證碼,如果是請求微博或者用戶(hù)信息可能出現驗證碼),否為抓取轉發(fā)的 ajax 連接
   ? ?:param need_login: 抓取頁(yè)面是否需要登錄,這樣做可以減小一些賬號的壓力
   ? ?:return: 返回請求的數據,如果出現 404 或者 403,或者是別的異常,都返回空字符串
   ? ?"""
   ? ?crawler.info('本次抓取的 url 為{url}'.format(url=url))
   ? ?count = 0<p> ? ?while count 查看全部

  如何構建一個(gè)分布式爬蟲(chóng):實(shí)戰篇
  
  種子博主具體信息
  這里我們就看到了他的具體信息了。然后,我們看該頁(yè)面的 url 構造
  我直接 copy 的地址欄的 url。這樣做有啥不好的呢?對于老鳥(niǎo)來(lái)說(shuō),一下就看出來(lái)了,這樣做的話(huà),可能會(huì )導致信息不全,因為可能有些信息是動(dòng)態(tài)加載的。所以,我們需要通過(guò)抓包來(lái)判斷到底微博會(huì )通過(guò)該 url 返回所有信息,還是需要請求一些 ajax 鏈接才會(huì )返回一些關(guān)鍵信息。這里我就重復一下我的觀(guān)點(diǎn):抓包很重要,抓包很重要,抓包很重要!重要的事情說(shuō)三遍。關(guān)于抓包,我在模擬登陸微博和模擬登陸百度云都詳細講過(guò)了,這里我就不講了。
  我們抓完包,發(fā)現并沒(méi)有 ajax 請求。那么可以肯定請求前面的 url,會(huì )返回所有信息。我們通過(guò)點(diǎn)擊鼠標右鍵,查看網(wǎng)頁(yè)源代碼,然后ctrl a、ctrl c將所有的頁(yè)面源碼保存到本地,這里我命名為personinfo.html。我們用瀏覽器打開(kāi)該文件,發(fā)現我們需要的所有信息都在這段源碼中,這個(gè)工作和抓包判斷數據是否全面有些重復,但是在我看來(lái)是必不可少的,因為我們解析頁(yè)面數據的時(shí)候還可以用到這個(gè) html 文件,如果我們每次都通過(guò)網(wǎng)絡(luò )請求去解析內容的話(huà),那么可能賬號沒(méi)一會(huì )兒就會(huì )被封了(因為頻繁訪(fǎng)問(wèn)微博信息),所以我們需要把要解析的文件保存到本地。
  從上面分析中我們可以得知
  這個(gè) url 就是獲取用戶(hù)數據的 url。那么我們在只知道用戶(hù) id 的時(shí)候怎么構造它呢?我們可以多拿幾個(gè)用戶(hù) id 來(lái)做測試,看構造是否有規律,比如我這里以用戶(hù)名為網(wǎng)易云音樂(lè )的用戶(hù)做分析,發(fā)現它的用戶(hù)信息頁(yè)面構造如下
  這個(gè)就和上面那個(gè)不同了。但是我們仔細觀(guān)察,可以發(fā)現上面那個(gè)是個(gè)人用戶(hù),下面是企業(yè)微博用戶(hù)。我們嘗試一下把它們 url 格式都統一為第一種或者第二種的格式
  這樣會(huì )出現 404,那么統一成上面那種呢?
  這樣子的話(huà),它會(huì )被重定向到用戶(hù)主頁(yè),而不是用戶(hù)詳細資料頁(yè)。所以也就不對了。那么該以什么依據判斷何時(shí)用第一種 url 格式,何時(shí)用第二種 url 格式呢?我們多翻幾個(gè)用戶(hù),會(huì )發(fā)現除了100505之外,還有100305、100206等前綴,那么我猜想這個(gè)應該可以區分不同用戶(hù)。這個(gè)前綴在哪里可以得到呢?我們打開(kāi)我們剛保存的頁(yè)面源碼,搜索100505,可以發(fā)現
  
  domain
  微博應該是根據這個(gè)來(lái)區分不同用戶(hù)類(lèi)型的。這里大家可以自己也可以試試,看不同用戶(hù)的domain是否不同。為了數據能全面,我也是做了大量測試,發(fā)現個(gè)人用戶(hù)的 domain 是1005051,作家是100305,其他基本都是認證的企業(yè)號。前兩個(gè)個(gè)人信息的 url 構造就是
  后者的是
  弄清楚了個(gè)人信息 url 的構造方式,但是還有一個(gè)問(wèn)題。我們已知只有 uid 啊,沒(méi)有 domain 啊。如果是企業(yè)號,我們通過(guò)domain=100505會(huì )被重定向到主頁(yè),如果是作家等(domain=100305 或者 100306),也會(huì )被重定向主頁(yè)。我們在主頁(yè)把 domain 提取出來(lái),再請求一次,不就能拿到用戶(hù)詳細信息了嗎?
  關(guān)于如何構造獲取用戶(hù)信息的 url 的相關(guān)分析就到這里了。因為我們是在登錄的情況下進(jìn)行數據抓取的,可能在抓取的時(shí)候,某個(gè)賬號突然就被封了,或者由于網(wǎng)絡(luò )原因,某次請求失敗了,該如何處理?對于前者,我們需要判斷每次請求返回的內容是否符合預期,也就是看 response url 是否正常,看 response content 是否是 404 或者讓你驗證手機號等,對于后者,我們可以做一個(gè)簡(jiǎn)單的重試策略,大概代碼如下
  <p>@timeout_decorator
  def get_page(url, user_verify=True, need_login=True):
   ? ?"""
   ? ?:param url: 待抓取 url
   ? ?:param user_verify: 是否為可能出現驗證碼的頁(yè)面(ajax 連接不會(huì )出現驗證碼,如果是請求微博或者用戶(hù)信息可能出現驗證碼),否為抓取轉發(fā)的 ajax 連接
   ? ?:param need_login: 抓取頁(yè)面是否需要登錄,這樣做可以減小一些賬號的壓力
   ? ?:return: 返回請求的數據,如果出現 404 或者 403,或者是別的異常,都返回空字符串
   ? ?"""
   ? ?crawler.info('本次抓取的 url 為{url}'.format(url=url))
   ? ?count = 0<p> ? ?while count

微博各種數據抓取思路與難點(diǎn)總結——小白爬蟲(chóng)進(jìn)階(1)

網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 312 次瀏覽 ? 2022-06-04 11:43 ? 來(lái)自相關(guān)話(huà)題

  微博各種數據抓取思路與難點(diǎn)總結——小白爬蟲(chóng)進(jìn)階(1)
  最近后臺留言異常的多,還有不少催更,看來(lái)各位小伙伴都是寒假稍歇后就立刻又投身于禿頭事業(yè)了,讓大家久等了,2022一起繼續加油。
  在之前的小白爬蟲(chóng)實(shí)戰(1)里,我們以馬云的微博為例初步演示了如何爬取一個(gè)微博用戶(hù)的所有微博文本(回顧戳這→),最近有很多同學(xué)后臺問(wèn)起詳細的思路,也有小伙伴對如何進(jìn)一步抓取微博轉發(fā)、評論、點(diǎn)贊數據甚至配圖的抓取方法提出了疑問(wèn)。
  針對以上問(wèn)題,本篇對微博數據的抓取做一個(gè)專(zhuān)門(mén)的梳理與總結,本文分為以下三部分:
  1、抓取URL的構造
  2、微博文本、轉發(fā)、評論、點(diǎn)贊數據的抓取與保存
  3、微博圖片的抓取與保存
  經(jīng)過(guò)這三部分的梳理,相信各位能對有關(guān)微博的抓取有更進(jìn)一步的了解,無(wú)論是抓取話(huà)題還是抓取熱搜,萬(wàn)變不離其宗,只需要按需求在本文基礎上進(jìn)行些改動(dòng)即可。
  注意:本篇是基于爬蟲(chóng)實(shí)戰(1)等前面相關(guān)內容之上的總結,一些基礎的內容便不再贅述,有需要的小伙伴可以回顧之前的相關(guān)內容:
  下面我們開(kāi)始這三部分——
  1
  抓取URL的構造
  在爬蟲(chóng)實(shí)戰(1)中,我們用檢查中的XHR過(guò)濾器找到了獲取數據所需的鏈接地址,這個(gè)鏈接地址有一大坨,第一頁(yè)鏈接與之后鏈接的差距就在于第一頁(yè)的鏈接尾部沒(méi)有since_id參數,這次我們進(jìn)一步對這一大坨鏈接進(jìn)行分解分析。
  %3D1%26q%3D%E9%A9%AC%E4%BA%91&type=uid&value=2145291155&containerid=91155&since_id=44903
  上面即是馬云微博數據的第二頁(yè)鏈接,若是把鏈接末尾的since_id刪去即為第一頁(yè)鏈接。在這么一大坨鏈接里,最終是靠著(zhù)末尾since_id的變化實(shí)現獲取下一頁(yè)數據的,在爬蟲(chóng)實(shí)戰(1)中,我們是直接將這一大坨復制粘貼到代碼中,而為since_id專(zhuān)門(mén)設了一個(gè)變量,這次我們再進(jìn)一步將這個(gè)鏈接拆分看看。
  實(shí)際上,這么一大坨連接中,只有
  為基礎連接,后面的一長(cháng)串都是各種各樣的參數組合,比如uid、t、luicode等等,而這一長(cháng)串由百分號、數字和字母構成的部分我們可以通過(guò)解碼得到它的實(shí)際文本
  %3D1%26q%3D%E9%A9%AC%E4%BA%91
  我們可以在中對上面這行奇奇怪怪的內容進(jìn)行URL解碼:
  
  解碼之后:
  
  通過(guò)解碼可知,%3D1%26q%3D%E9%A9%AC%E4%BA%91的實(shí)際文本含義為“=1&q=馬云”,據此可得這一大串鏈接的真實(shí)表達為:
  =1&q=馬云&type=uid&value=2145291155&containerid=91155&since_id=44903
  也就是一個(gè)基礎鏈接加上各種必要參數的組合。在Python中我們可以通過(guò)調用urlencode()方法將構造的參數字典與基礎連接組合生成完整鏈接,據此我們首先構造一個(gè)生成完整請求鏈接的函數:
  from urllib.parse import urlencode
  def generate_url(since_id='0'):
  """
  構造完整鏈接 """
  base_url = ''
  params = {
  'uid': '2145291155',
  't': '0',
  'luicode': '10000011',
  'lfid': '100103type=1',
  'q': '馬云',
  'type': 'uid',
  'value': '2145291155',
  'containerid': '91155',
  'since_id': since_id
  }
  url = base_url + urlencode(params)
  return url
  generate_url
  因為只有since_id是變化的,而第一頁(yè)鏈接又不含since_id,所以這里設一個(gè)since_id默認值為0的變量。
  到此,抓取所需的URL便構造完成了。
  2
  微博文本、轉發(fā)、評論、點(diǎn)贊數據的抓取與保存
  在爬蟲(chóng)實(shí)戰(1)中說(shuō)到,若用火狐瀏覽器訪(fǎng)問(wèn)我們所構造的URL,可以得到結構化的json數據,而我們所需要抓取的目標就在這些json數據之中。微博文本在mblog的text下,而轉發(fā)、評論、點(diǎn)贊數據也異曲同工:
  數據位置
  數據含義
  mblog→reposts_count
  點(diǎn)贊數
  mblog→comments_count 查看全部

  微博各種數據抓取思路與難點(diǎn)總結——小白爬蟲(chóng)進(jìn)階(1)
  最近后臺留言異常的多,還有不少催更,看來(lái)各位小伙伴都是寒假稍歇后就立刻又投身于禿頭事業(yè)了,讓大家久等了,2022一起繼續加油。
  在之前的小白爬蟲(chóng)實(shí)戰(1)里,我們以馬云的微博為例初步演示了如何爬取一個(gè)微博用戶(hù)的所有微博文本(回顧戳這→),最近有很多同學(xué)后臺問(wèn)起詳細的思路,也有小伙伴對如何進(jìn)一步抓取微博轉發(fā)、評論、點(diǎn)贊數據甚至配圖的抓取方法提出了疑問(wèn)。
  針對以上問(wèn)題,本篇對微博數據的抓取做一個(gè)專(zhuān)門(mén)的梳理與總結,本文分為以下三部分:
  1、抓取URL的構造
  2、微博文本、轉發(fā)、評論、點(diǎn)贊數據的抓取與保存
  3、微博圖片的抓取與保存
  經(jīng)過(guò)這三部分的梳理,相信各位能對有關(guān)微博的抓取有更進(jìn)一步的了解,無(wú)論是抓取話(huà)題還是抓取熱搜,萬(wàn)變不離其宗,只需要按需求在本文基礎上進(jìn)行些改動(dòng)即可。
  注意:本篇是基于爬蟲(chóng)實(shí)戰(1)等前面相關(guān)內容之上的總結,一些基礎的內容便不再贅述,有需要的小伙伴可以回顧之前的相關(guān)內容:
  下面我們開(kāi)始這三部分——
  1
  抓取URL的構造
  在爬蟲(chóng)實(shí)戰(1)中,我們用檢查中的XHR過(guò)濾器找到了獲取數據所需的鏈接地址,這個(gè)鏈接地址有一大坨,第一頁(yè)鏈接與之后鏈接的差距就在于第一頁(yè)的鏈接尾部沒(méi)有since_id參數,這次我們進(jìn)一步對這一大坨鏈接進(jìn)行分解分析。
  %3D1%26q%3D%E9%A9%AC%E4%BA%91&type=uid&value=2145291155&containerid=91155&since_id=44903
  上面即是馬云微博數據的第二頁(yè)鏈接,若是把鏈接末尾的since_id刪去即為第一頁(yè)鏈接。在這么一大坨鏈接里,最終是靠著(zhù)末尾since_id的變化實(shí)現獲取下一頁(yè)數據的,在爬蟲(chóng)實(shí)戰(1)中,我們是直接將這一大坨復制粘貼到代碼中,而為since_id專(zhuān)門(mén)設了一個(gè)變量,這次我們再進(jìn)一步將這個(gè)鏈接拆分看看。
  實(shí)際上,這么一大坨連接中,只有
  為基礎連接,后面的一長(cháng)串都是各種各樣的參數組合,比如uid、t、luicode等等,而這一長(cháng)串由百分號、數字和字母構成的部分我們可以通過(guò)解碼得到它的實(shí)際文本
  %3D1%26q%3D%E9%A9%AC%E4%BA%91
  我們可以在中對上面這行奇奇怪怪的內容進(jìn)行URL解碼:
  
  解碼之后:
  
  通過(guò)解碼可知,%3D1%26q%3D%E9%A9%AC%E4%BA%91的實(shí)際文本含義為“=1&q=馬云”,據此可得這一大串鏈接的真實(shí)表達為:
  =1&q=馬云&type=uid&value=2145291155&containerid=91155&since_id=44903
  也就是一個(gè)基礎鏈接加上各種必要參數的組合。在Python中我們可以通過(guò)調用urlencode()方法將構造的參數字典與基礎連接組合生成完整鏈接,據此我們首先構造一個(gè)生成完整請求鏈接的函數:
  from urllib.parse import urlencode
  def generate_url(since_id='0'):
  """
  構造完整鏈接 """
  base_url = ''
  params = {
  'uid': '2145291155',
  't': '0',
  'luicode': '10000011',
  'lfid': '100103type=1',
  'q': '馬云',
  'type': 'uid',
  'value': '2145291155',
  'containerid': '91155',
  'since_id': since_id
  }
  url = base_url + urlencode(params)
  return url
  generate_url
  因為只有since_id是變化的,而第一頁(yè)鏈接又不含since_id,所以這里設一個(gè)since_id默認值為0的變量。
  到此,抓取所需的URL便構造完成了。
  2
  微博文本、轉發(fā)、評論、點(diǎn)贊數據的抓取與保存
  在爬蟲(chóng)實(shí)戰(1)中說(shuō)到,若用火狐瀏覽器訪(fǎng)問(wèn)我們所構造的URL,可以得到結構化的json數據,而我們所需要抓取的目標就在這些json數據之中。微博文本在mblog的text下,而轉發(fā)、評論、點(diǎn)贊數據也異曲同工:
  數據位置
  數據含義
  mblog→reposts_count
  點(diǎn)贊數
  mblog→comments_count

Python爬蟲(chóng)入門(mén),8個(gè)常用爬蟲(chóng)技巧盤(pán)點(diǎn)

網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 139 次瀏覽 ? 2022-06-04 06:47 ? 來(lái)自相關(guān)話(huà)題

  Python爬蟲(chóng)入門(mén),8個(gè)常用爬蟲(chóng)技巧盤(pán)點(diǎn)
  
  
  5、頁(yè)面解析
  對于頁(yè)面解析最強大的當然是正則表達式,
  這個(gè)對于不同網(wǎng)站不同的使用者都不一樣,就不用過(guò)多的說(shuō)明。
  
  其次就是解析庫了,常用的有兩個(gè)lxml和BeautifulSoup。
  對于這兩個(gè)庫,我的評價(jià)是,
  都是HTML/XML的處理庫,Beautifulsoup純python實(shí)現,效率低,
  但是功能實(shí)用,比如能用通過(guò)結果搜索獲得某個(gè)HTML節點(diǎn)的源碼;
  lxmlC語(yǔ)言編碼,高效,支持Xpath。
  
  6.驗證碼的處理
  碰到驗證碼咋辦?
  這里分兩種情況處理:
  google那種驗證碼,沒(méi)辦法。
  簡(jiǎn)單的驗證碼:字符個(gè)數有限,只使用了簡(jiǎn)單的平移或旋轉加噪音而沒(méi)有扭曲的,
  這種還是有可能可以處理的,一般思路是旋轉的轉回來(lái),噪音去掉,
  然后劃分單個(gè)字符,劃分好了以后再通過(guò)特征提取的方法(例如PCA)降維并生成特征庫,
  然后把驗證碼和特征庫進(jìn)行比較。
  這個(gè)比較復雜,這里就不展開(kāi)了,
  具體做法請弄本相關(guān)教科書(shū)好好研究一下。
  
  7. gzip/deflate支持
  現在的網(wǎng)頁(yè)普遍支持gzip壓縮,這往往可以解決大量傳輸時(shí)間,
  以VeryCD的主頁(yè)為例,未壓縮版本247K,壓縮了以后45K,為原來(lái)的1/5。
  這就意味著(zhù)抓取速度會(huì )快5倍。
  然而python的urllib/urllib2默認都不支持壓縮
  要返回壓縮格式,必須在request的header里面寫(xiě)明’accept-encoding’,
  然后讀取response后更要檢查header查看是否有’content-encoding’一項來(lái)判斷是否需要解碼,很繁瑣瑣碎。
  如何讓urllib2自動(dòng)支持gzip, defalte呢?
  其實(shí)可以繼承BaseHanlder類(lèi),
  然后build_opener的方式來(lái)處理:
  
  
  8、多線(xiàn)程并發(fā)抓取
  單線(xiàn)程太慢的話(huà),就需要多線(xiàn)程了,
  這里給個(gè)簡(jiǎn)單的線(xiàn)程池模板 這個(gè)程序只是簡(jiǎn)單地打印了1-10,
  但是可以看出是并發(fā)的。
  雖然說(shuō)Python的多線(xiàn)程很雞肋
  但是對于爬蟲(chóng)這種網(wǎng)絡(luò )頻繁型,
  還是能一定程度提高效率的。
  
  
  9. 總結
  閱讀Python編寫(xiě)的代碼感覺(jué)像在閱讀英語(yǔ)一樣,這讓使用者可以專(zhuān)注于解決問(wèn)題而不是去搞明白語(yǔ)言本身。
  Python雖然是基于C語(yǔ)言編寫(xiě),但是摒棄了C中復雜的指針,使其變得簡(jiǎn)明易學(xué)。
  并且作為開(kāi)源軟件,Python允許對代碼進(jìn)行閱讀,拷貝甚至改進(jìn)。
  這些性能成就了Python的高效率,有“人生苦短,我用Python”之說(shuō),是一種十分精彩又強大的語(yǔ)言。
  總而言之,開(kāi)始學(xué)Python一定要注意這4點(diǎn):
  1.代碼規范,這本身就是一個(gè)非常好的習慣,如果開(kāi)始不養好好的代碼規劃,以后會(huì )很痛苦。
  2.多動(dòng)手,少看書(shū),很多人學(xué)Python就一味的看書(shū),這不是學(xué)數學(xué)物理,你看例題可能就會(huì )了,學(xué)習Python主要是學(xué)習編程思想。
  3.勤練習,學(xué)完新的知識點(diǎn),一定要記得如何去應用,不然學(xué)完就會(huì )忘,學(xué)我們這行主要都是實(shí)際操作。
  4.學(xué)習要有效率,如果自己都覺(jué)得效率非常低,那就停不停,找一下原因,去問(wèn)問(wèn)過(guò)來(lái)人這是為什么。
  推薦↓↓↓
  
  長(cháng)
  按
  關(guān)
  注
  【】都在這里!
  涵蓋:程序員大咖、源碼共讀、程序員共讀、數據結構與算法、黑客技術(shù)和網(wǎng)絡(luò )安全、大數據科技、編程前端、Java、Python、Web編程開(kāi)發(fā)、Android、iOS開(kāi)發(fā)、Linux、數據庫研發(fā)、幽默程序員等。 查看全部

  Python爬蟲(chóng)入門(mén),8個(gè)常用爬蟲(chóng)技巧盤(pán)點(diǎn)
  
  
  5、頁(yè)面解析
  對于頁(yè)面解析最強大的當然是正則表達式,
  這個(gè)對于不同網(wǎng)站不同的使用者都不一樣,就不用過(guò)多的說(shuō)明。
  
  其次就是解析庫了,常用的有兩個(gè)lxml和BeautifulSoup。
  對于這兩個(gè)庫,我的評價(jià)是,
  都是HTML/XML的處理庫,Beautifulsoup純python實(shí)現,效率低,
  但是功能實(shí)用,比如能用通過(guò)結果搜索獲得某個(gè)HTML節點(diǎn)的源碼;
  lxmlC語(yǔ)言編碼,高效,支持Xpath。
  
  6.驗證碼的處理
  碰到驗證碼咋辦?
  這里分兩種情況處理:
  google那種驗證碼,沒(méi)辦法。
  簡(jiǎn)單的驗證碼:字符個(gè)數有限,只使用了簡(jiǎn)單的平移或旋轉加噪音而沒(méi)有扭曲的,
  這種還是有可能可以處理的,一般思路是旋轉的轉回來(lái),噪音去掉,
  然后劃分單個(gè)字符,劃分好了以后再通過(guò)特征提取的方法(例如PCA)降維并生成特征庫,
  然后把驗證碼和特征庫進(jìn)行比較。
  這個(gè)比較復雜,這里就不展開(kāi)了,
  具體做法請弄本相關(guān)教科書(shū)好好研究一下。
  
  7. gzip/deflate支持
  現在的網(wǎng)頁(yè)普遍支持gzip壓縮,這往往可以解決大量傳輸時(shí)間,
  以VeryCD的主頁(yè)為例,未壓縮版本247K,壓縮了以后45K,為原來(lái)的1/5。
  這就意味著(zhù)抓取速度會(huì )快5倍。
  然而python的urllib/urllib2默認都不支持壓縮
  要返回壓縮格式,必須在request的header里面寫(xiě)明’accept-encoding’,
  然后讀取response后更要檢查header查看是否有’content-encoding’一項來(lái)判斷是否需要解碼,很繁瑣瑣碎。
  如何讓urllib2自動(dòng)支持gzip, defalte呢?
  其實(shí)可以繼承BaseHanlder類(lèi),
  然后build_opener的方式來(lái)處理:
  
  
  8、多線(xiàn)程并發(fā)抓取
  單線(xiàn)程太慢的話(huà),就需要多線(xiàn)程了,
  這里給個(gè)簡(jiǎn)單的線(xiàn)程池模板 這個(gè)程序只是簡(jiǎn)單地打印了1-10,
  但是可以看出是并發(fā)的。
  雖然說(shuō)Python的多線(xiàn)程很雞肋
  但是對于爬蟲(chóng)這種網(wǎng)絡(luò )頻繁型,
  還是能一定程度提高效率的。
  
  
  9. 總結
  閱讀Python編寫(xiě)的代碼感覺(jué)像在閱讀英語(yǔ)一樣,這讓使用者可以專(zhuān)注于解決問(wèn)題而不是去搞明白語(yǔ)言本身。
  Python雖然是基于C語(yǔ)言編寫(xiě),但是摒棄了C中復雜的指針,使其變得簡(jiǎn)明易學(xué)。
  并且作為開(kāi)源軟件,Python允許對代碼進(jìn)行閱讀,拷貝甚至改進(jìn)。
  這些性能成就了Python的高效率,有“人生苦短,我用Python”之說(shuō),是一種十分精彩又強大的語(yǔ)言。
  總而言之,開(kāi)始學(xué)Python一定要注意這4點(diǎn):
  1.代碼規范,這本身就是一個(gè)非常好的習慣,如果開(kāi)始不養好好的代碼規劃,以后會(huì )很痛苦。
  2.多動(dòng)手,少看書(shū),很多人學(xué)Python就一味的看書(shū),這不是學(xué)數學(xué)物理,你看例題可能就會(huì )了,學(xué)習Python主要是學(xué)習編程思想。
  3.勤練習,學(xué)完新的知識點(diǎn),一定要記得如何去應用,不然學(xué)完就會(huì )忘,學(xué)我們這行主要都是實(shí)際操作。
  4.學(xué)習要有效率,如果自己都覺(jué)得效率非常低,那就停不停,找一下原因,去問(wèn)問(wèn)過(guò)來(lái)人這是為什么。
  推薦↓↓↓
  
  長(cháng)
  按
  關(guān)
  注
  【】都在這里!
  涵蓋:程序員大咖、源碼共讀、程序員共讀、數據結構與算法、黑客技術(shù)和網(wǎng)絡(luò )安全、大數據科技、編程前端、Java、Python、Web編程開(kāi)發(fā)、Android、iOS開(kāi)發(fā)、Linux、數據庫研發(fā)、幽默程序員等。

實(shí)戰演練——愛(ài)嬰醫院中莆田系醫院數據分析(一)

網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 72 次瀏覽 ? 2022-06-04 06:44 ? 來(lái)自相關(guān)話(huà)題

  實(shí)戰演練——愛(ài)嬰醫院中莆田系醫院數據分析(一)
  技術(shù)總編:張 邯
  爬蟲(chóng)俱樂(lè )部將于2020年1月5日至11日在湖北武漢舉行為期一周的Stata編程技術(shù)定制培訓,此次采取初級班和高級班分批次培訓。課程通過(guò)案例教學(xué)模式,旨在幫助大家在短期內掌握Stata軟件編程、金融計量知識和實(shí)證分析方法,使大家熟悉Stata核心的爬蟲(chóng)技術(shù),以及Stata與其他軟件交互的高端技術(shù)。目前正在火熱招生中~詳細培訓大綱及報名方式,請點(diǎn)擊《》或點(diǎn)擊文末閱讀原文呦~
  自2015年黨的十八屆五中全會(huì )開(kāi)放二孩政策實(shí)施以來(lái),越來(lái)越多天真可愛(ài)的孩子在這個(gè)中國特色社會(huì )新時(shí)代呱呱墜地。但是,“7歲男童墜樓身亡”、“幼兒園虐童”等新聞時(shí)時(shí)刻刻提醒我們,要全方位、多角度對這些祖國未來(lái)的建設者進(jìn)行保護。當然,保護他們要從保護他們的出生做起。
  開(kāi)放二孩政策實(shí)施后,國家婦幼健康司響應號召,在2015年11月公布了《國家衛生計生委關(guān)于公布全國愛(ài)嬰醫院名單的公告》,旨在“不斷改善產(chǎn)科兒科服務(wù)質(zhì)量,逐步提高母乳喂養率,降低非醫學(xué)指征剖宮產(chǎn)率,保障調整完善生育政策順利實(shí)施”。(網(wǎng)址:)
  
  當小編打開(kāi)這些名單瀏覽的時(shí)候,這里面有些醫院的名字竟形同“莆田系醫院”,為了識別這其中為數不多的“莆田系醫院”,小編決定使用Python來(lái)一探究竟。
  由于篇幅限制,本篇重點(diǎn)介紹如何獲取所需的.docx文件,下篇重點(diǎn)介紹如何提取.docx文件中的表格信息并與已有的數據庫進(jìn)行匹配。
  本文涉及的技術(shù)要點(diǎn):
 ?、佾@取公告附件②獲取word文件中的表格信息③ 將.doc文件轉換為.docx文件
  一、使用網(wǎng)絡(luò )爬蟲(chóng)技術(shù)抓取愛(ài)嬰醫院名單
  1、創(chuàng )建文件夾并改變缺省路徑
  導入Python的os標準庫,判斷是否存在我們需要的文件夾,如果不存在則創(chuàng )建,將新創(chuàng )建的文件夾作為缺省路徑,程序如下:
  import osif not os.path.exists(r"D:/愛(ài)嬰醫院"): os.mkdir(r"D:/愛(ài)嬰醫院")os.chdir(r"D:/愛(ài)嬰醫院")
  2、導入requests標準庫和re標準庫抓取WORD文件
  requests和re庫的使用在爬蟲(chóng)俱樂(lè )部往期推文《》和《》中已詳細介紹。首先,導入標準庫,構造headers,并抓取網(wǎng)頁(yè)源代碼,程序如下:
  import requestsimport reheaders = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36', 'Host': 'www.nhc.gov.cn', 'Referer': 'http://www.nhc.gov.cn/fys/s7906/201511/e5650712dbcd449e9d2e01129a698b9c.shtml', 'Cookie': 'FSSBBIl1UgzbN7N80S=IIRSdCvBkEfkV.B2JY9RYhaETIf1BuxVpvEkSoPAJNFoG0jDMD0Ful2W19MSwjQT; yfx_c_g_u_id_10006654=_ck19080819145412635280045357765; _gscu_2059686908=65262894vmq4k445; yfx_f_l_v_t_10006654=f_t_1565262894262__r_t_1566175543011__v_t_1566175543011__r_c_2; _gscbrs_2059686908=1; yfx_mr_10006654=%3A%3Amarket_type_free_search%3A%3A%3A%3Abaidu%3A%3A%3A%3A%3A%3A%3A%3Awww.baidu.com%3A%3A%3A%3Apmf_from_free_search; yfx_mr_f_10006654=%3A%3Amarket_type_free_search%3A%3A%3A%3Abaidu%3A%3A%3A%3A%3A%3A%3A%3Awww.baidu.com%3A%3A%3A%3Apmf_from_free_search; yfx_key_10006654=; security_session_verify=27b11d4bf074ab3d320a0abb616f351f; banggoo.nuva.cookie=1|XVn2H|XVnyw; FSSBBIl1UgzbN7N80T=3r.zHapFkhZJ9axZJ1O.c4IFBETpXD7V97EmMfYcNch3_sxH_Btj9.wKGGKtWVFD4JTZMrYQH4I_cyZS.TVLlnmOlnWWQYX1KSl_0JUVaqTV5NSoiWZ2yDjJtV0RKxM3mtcPiY3b6wUjzJcPd4Z3u2ns76vO.lskE3joV_Gsk37Wj7hd7a.qnhOQazlKQrIZW8zGEH.8cPkVTO626ptQpnK35KuJcjrdVKTUEIq7bS81Ba.CKHUaDxNyxwsVMVkUiIGOGGD9sL3MFcik_S05TQa174cT51WxsHLZ_d4FFWBq3LZzaqvAM.ybpZ0vwVcPApVOILVksCY4w7adafW4.rYWCq_.1437bDWfT7f6FtSnb9G' }html = requests.get("http://www.nhc.gov.cn/fys/s790 ... 6quot;)text = html.content.decode('utf-8')#先抓取字節碼再轉換為字符串,避免亂碼。print(text)
  結果如下:
  
  可見(jiàn),我們使用requests庫成功將網(wǎng)頁(yè)源代碼抓取下來(lái)。源代碼中存有WORD文件的URL,我們將其中一個(gè)復制下來(lái)進(jìn)行分析:
  <A target=_blankhref="/ewebeditor/uploadfile/2015/11/20151117160507435.doc">1.北京市愛(ài)嬰醫院名單.doc</A></P>
  其中的URL可以使用正則表達式A[ ]target.*?href="(.*?)"進(jìn)行提取,我們提取出32個(gè)WORD文件的URL并放在一個(gè)列表中,程序如下:
  urls = re.findall('A[ ]target.*?href="(.*?)"', text, re.S)print(urls)c_url = []for url in urls: ur = "http://www.nhc.gov.cn" + url c_url.append(ur)print(c_url)
  結果如下:
  
  最后,使用requests庫,根據列表中的URL下載WORD文件,程序如下:
  for nu,c in enumerate(c_url): co = requests.get(c) #獲取文件 suffix = os.path.splitext(c)[1] #分離文件名與文件后綴(.doc或.docx) filename = str(nu)+suffix #用序號給文件命名,生成新的文件名 with open(filename,'wb') as f:????????f.write(co.content)
  此時(shí),在缺省路徑中就出現了我們需要的WORD文件,結果如下:
  
  二、將.doc文件轉換為.docx文件
  由于Python無(wú)法讀取.doc文件,因此我們先將.doc轉換為.docx。
  導入標準庫并定義轉化函數:
  from win32com import client# win32com.client可以直接調用VBA的庫,對Word、Excel進(jìn)行操作def doc_to_docx(path): if os.path.splitext(path)[1] == ".doc": word = client.Dispatch('Word.Application') #打開(kāi)word。 doc = word.Documents.Open(path) # 打開(kāi)目標路徑下的文件 doc.SaveAs(os.path.splitext(path)[0]+".docx", 16) doc.Close()????????word.Quit()???????#退出
  上述函數需要傳入文件名。接下來(lái)定義一個(gè)函數,用來(lái)將指定文件夾中的所有文件存入歷列表中:
  def find_file(path, ext, file_list=[]): dir = os.listdir(path) for i in dir: i = os.path.join(path, i) #拼接文件路徑, 將多個(gè)路徑組合后返回 if os.path.isdir(i): #用于判斷某一對象是否為目錄 find_file(i, ext, file_list) else: if ext == os.path.splitext(i)[1]: file_list.append(i)????return?file_list
  調用上述函數進(jìn)行轉換并刪掉.doc文件,程序如下:
  dir_path = "D:\愛(ài)嬰醫院" #批量轉換文件夾ext = ".doc"file_list = find_file(dir_path, ext)for file in file_list: doc_to_docx(file)#刪掉.doc文件files = os.listdir()print(files)for c in files: if os.path.splitext(c)[1] == ".doc":????????os.remove(c)
  結果如下:
  
  此時(shí),文件就全部轉換為了.docx文件。
  
  對我們的推文累計打賞超過(guò)1000元,我們即可給您開(kāi)具發(fā)票,發(fā)票類(lèi)別為“咨詢(xún)費”。用心做事,不負您的支持!
  往期推文推薦
  關(guān)于我們
  微信公眾號“Stata and Python數據分析”分享實(shí)用的stata、python等軟件的數據處理知識,歡迎轉載、打賞。我們是由李春濤教授領(lǐng)導下的研究生及本科生組成的大數據處理和分析團隊。
  此外,歡迎大家踴躍投稿,介紹一些關(guān)于stata和python的數據處理和分析技巧。投稿郵箱:投稿要求:
  1)必須原創(chuàng ),禁止抄襲;
  2)必須準確,詳細,有例子,有截圖;
  注意事項:
  1)所有投稿都會(huì )經(jīng)過(guò)本公眾號運營(yíng)團隊成員的審核,審核通過(guò)才可錄用,一經(jīng)錄用,會(huì )在該推文里為作者署名,并有賞金分成。
  2)郵件請注明投稿,郵件名稱(chēng)為“投稿+推文名稱(chēng)”。
  3)應廣大讀者要求,現開(kāi)通有償問(wèn)答服務(wù),如果大家遇到有關(guān)數據處理、分析等問(wèn)題,可以在公眾號中提出,只需支付少量賞金,我們會(huì )在后期的推文里給予解答。
   查看全部

  實(shí)戰演練——愛(ài)嬰醫院中莆田系醫院數據分析(一)
  技術(shù)總編:張 邯
  爬蟲(chóng)俱樂(lè )部將于2020年1月5日至11日在湖北武漢舉行為期一周的Stata編程技術(shù)定制培訓,此次采取初級班和高級班分批次培訓。課程通過(guò)案例教學(xué)模式,旨在幫助大家在短期內掌握Stata軟件編程、金融計量知識和實(shí)證分析方法,使大家熟悉Stata核心的爬蟲(chóng)技術(shù),以及Stata與其他軟件交互的高端技術(shù)。目前正在火熱招生中~詳細培訓大綱及報名方式,請點(diǎn)擊《》或點(diǎn)擊文末閱讀原文呦~
  自2015年黨的十八屆五中全會(huì )開(kāi)放二孩政策實(shí)施以來(lái),越來(lái)越多天真可愛(ài)的孩子在這個(gè)中國特色社會(huì )新時(shí)代呱呱墜地。但是,“7歲男童墜樓身亡”、“幼兒園虐童”等新聞時(shí)時(shí)刻刻提醒我們,要全方位、多角度對這些祖國未來(lái)的建設者進(jìn)行保護。當然,保護他們要從保護他們的出生做起。
  開(kāi)放二孩政策實(shí)施后,國家婦幼健康司響應號召,在2015年11月公布了《國家衛生計生委關(guān)于公布全國愛(ài)嬰醫院名單的公告》,旨在“不斷改善產(chǎn)科兒科服務(wù)質(zhì)量,逐步提高母乳喂養率,降低非醫學(xué)指征剖宮產(chǎn)率,保障調整完善生育政策順利實(shí)施”。(網(wǎng)址:)
  
  當小編打開(kāi)這些名單瀏覽的時(shí)候,這里面有些醫院的名字竟形同“莆田系醫院”,為了識別這其中為數不多的“莆田系醫院”,小編決定使用Python來(lái)一探究竟。
  由于篇幅限制,本篇重點(diǎn)介紹如何獲取所需的.docx文件,下篇重點(diǎn)介紹如何提取.docx文件中的表格信息并與已有的數據庫進(jìn)行匹配。
  本文涉及的技術(shù)要點(diǎn):
 ?、佾@取公告附件②獲取word文件中的表格信息③ 將.doc文件轉換為.docx文件
  一、使用網(wǎng)絡(luò )爬蟲(chóng)技術(shù)抓取愛(ài)嬰醫院名單
  1、創(chuàng )建文件夾并改變缺省路徑
  導入Python的os標準庫,判斷是否存在我們需要的文件夾,如果不存在則創(chuàng )建,將新創(chuàng )建的文件夾作為缺省路徑,程序如下:
  import osif not os.path.exists(r"D:/愛(ài)嬰醫院"): os.mkdir(r"D:/愛(ài)嬰醫院")os.chdir(r"D:/愛(ài)嬰醫院")
  2、導入requests標準庫和re標準庫抓取WORD文件
  requests和re庫的使用在爬蟲(chóng)俱樂(lè )部往期推文《》和《》中已詳細介紹。首先,導入標準庫,構造headers,并抓取網(wǎng)頁(yè)源代碼,程序如下:
  import requestsimport reheaders = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36', 'Host': 'www.nhc.gov.cn', 'Referer': 'http://www.nhc.gov.cn/fys/s7906/201511/e5650712dbcd449e9d2e01129a698b9c.shtml', 'Cookie': 'FSSBBIl1UgzbN7N80S=IIRSdCvBkEfkV.B2JY9RYhaETIf1BuxVpvEkSoPAJNFoG0jDMD0Ful2W19MSwjQT; yfx_c_g_u_id_10006654=_ck19080819145412635280045357765; _gscu_2059686908=65262894vmq4k445; yfx_f_l_v_t_10006654=f_t_1565262894262__r_t_1566175543011__v_t_1566175543011__r_c_2; _gscbrs_2059686908=1; yfx_mr_10006654=%3A%3Amarket_type_free_search%3A%3A%3A%3Abaidu%3A%3A%3A%3A%3A%3A%3A%3Awww.baidu.com%3A%3A%3A%3Apmf_from_free_search; yfx_mr_f_10006654=%3A%3Amarket_type_free_search%3A%3A%3A%3Abaidu%3A%3A%3A%3A%3A%3A%3A%3Awww.baidu.com%3A%3A%3A%3Apmf_from_free_search; yfx_key_10006654=; security_session_verify=27b11d4bf074ab3d320a0abb616f351f; banggoo.nuva.cookie=1|XVn2H|XVnyw; FSSBBIl1UgzbN7N80T=3r.zHapFkhZJ9axZJ1O.c4IFBETpXD7V97EmMfYcNch3_sxH_Btj9.wKGGKtWVFD4JTZMrYQH4I_cyZS.TVLlnmOlnWWQYX1KSl_0JUVaqTV5NSoiWZ2yDjJtV0RKxM3mtcPiY3b6wUjzJcPd4Z3u2ns76vO.lskE3joV_Gsk37Wj7hd7a.qnhOQazlKQrIZW8zGEH.8cPkVTO626ptQpnK35KuJcjrdVKTUEIq7bS81Ba.CKHUaDxNyxwsVMVkUiIGOGGD9sL3MFcik_S05TQa174cT51WxsHLZ_d4FFWBq3LZzaqvAM.ybpZ0vwVcPApVOILVksCY4w7adafW4.rYWCq_.1437bDWfT7f6FtSnb9G' }html = requests.get("http://www.nhc.gov.cn/fys/s790 ... 6quot;)text = html.content.decode('utf-8')#先抓取字節碼再轉換為字符串,避免亂碼。print(text)
  結果如下:
  
  可見(jiàn),我們使用requests庫成功將網(wǎng)頁(yè)源代碼抓取下來(lái)。源代碼中存有WORD文件的URL,我們將其中一個(gè)復制下來(lái)進(jìn)行分析:
  <A target=_blankhref="/ewebeditor/uploadfile/2015/11/20151117160507435.doc">1.北京市愛(ài)嬰醫院名單.doc</A></P>
  其中的URL可以使用正則表達式A[ ]target.*?href="(.*?)"進(jìn)行提取,我們提取出32個(gè)WORD文件的URL并放在一個(gè)列表中,程序如下:
  urls = re.findall('A[ ]target.*?href="(.*?)"', text, re.S)print(urls)c_url = []for url in urls: ur = "http://www.nhc.gov.cn" + url c_url.append(ur)print(c_url)
  結果如下:
  
  最后,使用requests庫,根據列表中的URL下載WORD文件,程序如下:
  for nu,c in enumerate(c_url): co = requests.get(c) #獲取文件 suffix = os.path.splitext(c)[1] #分離文件名與文件后綴(.doc或.docx) filename = str(nu)+suffix #用序號給文件命名,生成新的文件名 with open(filename,'wb') as f:????????f.write(co.content)
  此時(shí),在缺省路徑中就出現了我們需要的WORD文件,結果如下:
  
  二、將.doc文件轉換為.docx文件
  由于Python無(wú)法讀取.doc文件,因此我們先將.doc轉換為.docx。
  導入標準庫并定義轉化函數:
  from win32com import client# win32com.client可以直接調用VBA的庫,對Word、Excel進(jìn)行操作def doc_to_docx(path): if os.path.splitext(path)[1] == ".doc": word = client.Dispatch('Word.Application') #打開(kāi)word。 doc = word.Documents.Open(path) # 打開(kāi)目標路徑下的文件 doc.SaveAs(os.path.splitext(path)[0]+".docx", 16) doc.Close()????????word.Quit()???????#退出
  上述函數需要傳入文件名。接下來(lái)定義一個(gè)函數,用來(lái)將指定文件夾中的所有文件存入歷列表中:
  def find_file(path, ext, file_list=[]): dir = os.listdir(path) for i in dir: i = os.path.join(path, i) #拼接文件路徑, 將多個(gè)路徑組合后返回 if os.path.isdir(i): #用于判斷某一對象是否為目錄 find_file(i, ext, file_list) else: if ext == os.path.splitext(i)[1]: file_list.append(i)????return?file_list
  調用上述函數進(jìn)行轉換并刪掉.doc文件,程序如下:
  dir_path = "D:\愛(ài)嬰醫院" #批量轉換文件夾ext = ".doc"file_list = find_file(dir_path, ext)for file in file_list: doc_to_docx(file)#刪掉.doc文件files = os.listdir()print(files)for c in files: if os.path.splitext(c)[1] == ".doc":????????os.remove(c)
  結果如下:
  
  此時(shí),文件就全部轉換為了.docx文件。
  
  對我們的推文累計打賞超過(guò)1000元,我們即可給您開(kāi)具發(fā)票,發(fā)票類(lèi)別為“咨詢(xún)費”。用心做事,不負您的支持!
  往期推文推薦
  關(guān)于我們
  微信公眾號“Stata and Python數據分析”分享實(shí)用的stata、python等軟件的數據處理知識,歡迎轉載、打賞。我們是由李春濤教授領(lǐng)導下的研究生及本科生組成的大數據處理和分析團隊。
  此外,歡迎大家踴躍投稿,介紹一些關(guān)于stata和python的數據處理和分析技巧。投稿郵箱:投稿要求:
  1)必須原創(chuàng ),禁止抄襲;
  2)必須準確,詳細,有例子,有截圖;
  注意事項:
  1)所有投稿都會(huì )經(jīng)過(guò)本公眾號運營(yíng)團隊成員的審核,審核通過(guò)才可錄用,一經(jīng)錄用,會(huì )在該推文里為作者署名,并有賞金分成。
  2)郵件請注明投稿,郵件名稱(chēng)為“投稿+推文名稱(chēng)”。
  3)應廣大讀者要求,現開(kāi)通有償問(wèn)答服務(wù),如果大家遇到有關(guān)數據處理、分析等問(wèn)題,可以在公眾號中提出,只需支付少量賞金,我們會(huì )在后期的推文里給予解答。
  

小白學(xué) Python 爬蟲(chóng)(42):春節去哪里玩(系列終篇)

網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 192 次瀏覽 ? 2022-05-26 12:39 ? 來(lái)自相關(guān)話(huà)題

  小白學(xué) Python 爬蟲(chóng)(42):春節去哪里玩(系列終篇)
  
  
  
  人生苦短,我用 Python
  前文傳送門(mén):
  引言
  首先恭喜看到這篇文章的同學(xué),本篇內容為 「小白學(xué) Python 爬蟲(chóng)」 系列的最后一篇。
  
  看了下上面的前文傳送門(mén),加上這篇內容,總共有 42 篇,小編還是成就感滿(mǎn)滿(mǎn),小編翻看了下公眾號,第一篇文章是在 2019 年的 11 月 17 日推送的,大致數了數,將近兩個(gè)月的時(shí)間。
  當然,其中一些文章的質(zhì)量并不高,很多都是在比較有限的時(shí)間中趕工趕出來(lái)的,還是感謝各位讀者對小編的不離不棄,寫(xiě)的這么爛還沒(méi)取關(guān)的絕對是真愛(ài)了。
  正好下周就要過(guò)年了,從推送的時(shí)間算的話(huà)還有 10 個(gè)自然日左右的時(shí)間,可能很多同學(xué)可能過(guò)年是要出去玩的,那么去哪里玩就成了一個(gè)問(wèn)題。
  那么,怎么挑選去哪里玩最快的,小編想了想,直接去抓某站的數據吧,抓下來(lái)自己根據自己的情況查詢(xún)下就好了。
  那么今天的目標站是:馬蜂窩。
  這里小編還想說(shuō)一點(diǎn),雖然我們在前面 7、 8 篇文章中都是在講如何使用爬蟲(chóng)框架 Scrapy ,說(shuō)實(shí)話(huà),小編并不覺(jué)得 Scrapy 有多方便,在一些簡(jiǎn)單的應用場(chǎng)景下,使用 Requests 庫可能是最方便的選擇, Scrapy 小編個(gè)人感覺(jué)還是更適合使用在一些中大型的爬蟲(chóng)項目中,簡(jiǎn)單的爬蟲(chóng)腳本使用最簡(jiǎn)單的技術(shù)棧就 ok 了,所以小編在本文中使用的技術(shù)棧還是 Requests + PyQuery 。
  不要問(wèn)為啥,問(wèn)就是喜歡。
  分析
  首先我們訪(fǎng)問(wèn)鏈接,打開(kāi)我們將要抓取的站點(diǎn):。
  
  這里是攻略的列表頁(yè),我們的目標是抓取來(lái)自游記的數據,其余的數據放過(guò),原因是在游記中我們才能獲取到一些具體的我們需要的數據。
  
  數據的來(lái)源搞清楚了,接下來(lái)是翻頁(yè)功能,只有清楚了如何翻頁(yè),我們才能源源不斷的獲取數據,否則就只能抓取第一頁(yè)的數據了。
  當把頁(yè)面翻到最下面的時(shí)候就尷尬了,發(fā)現是自動(dòng)加載更多,這個(gè)當然難不倒帥氣逼人的小編我,掏出大殺器, Chrome 的開(kāi)發(fā)者工具 F12 ,選到 network 標簽頁(yè),再往下滾動(dòng)一下,我們查看下這個(gè)頁(yè)面發(fā)出的請求。
  
  這個(gè)請求很有意思,請求的路徑和我們訪(fǎng)問(wèn)的頁(yè)面路徑一樣,但是請求類(lèi)型變成 POST ,并且增加了請求參數,類(lèi)型還是 Form 表單格式的。
  截止這里,我們已經(jīng)清楚了目標站點(diǎn)的數據路徑以及翻頁(yè)方式,雖然目前我們并不知道最大頁(yè)數是多少,但是我們可以人為的設置一個(gè)最大頁(yè)數,比如 100 或者 200 ,小編相信,這么大的站點(diǎn)上,幾百頁(yè)的游記應該是還有的。
  代碼
  代碼小編就直接貼出來(lái),之前有同學(xué)希望數據是保存在 Excel 中的,本次實(shí)戰的數據就不存數據庫了,直接寫(xiě)入 Excel 。
  import requests<br />from pyquery import PyQuery<br />import xlsxwriter<br /><br />headers = {<br /> 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36',<br /> 'cookie': '__jsluid_s=6fc5b4a3b5235afbfdafff4bbf7e6dbd; PHPSESSID=v9hm8hc3s56ogrn8si12fejdm3; mfw_uuid=5e1db855-ab4a-da12-309c-afb9cf90d3dd; _r=baidu; _rp=a%3A2%3A%7Bs%3A1%3A%22p%22%3Bs%3A18%3A%22www.baidu.com%2Flink%22%3Bs%3A1%3A%22t%22%3Bi%3A1579006045%3B%7D; oad_n=a%3A5%3A%7Bs%3A5%3A%22refer%22%3Bs%3A21%3A%22https%3A%2F%2Fwww.baidu.com%22%3Bs%3A2%3A%22hp%22%3Bs%3A13%3A%22www.baidu.com%22%3Bs%3A3%3A%22oid%22%3Bi%3A1026%3Bs%3A2%3A%22dm%22%3Bs%3A15%3A%22www.mafengwo.cn%22%3Bs%3A2%3A%22ft%22%3Bs%3A19%3A%222020-01-14+20%3A47%3A25%22%3B%7D; __mfwothchid=referrer%7Cwww.baidu.com; __omc_chl=; __mfwc=referrer%7Cwww.baidu.com; Hm_lvt_8288b2ed37e5bc9b4c9f7008798d2de0=1579006048; uva=s%3A264%3A%22a%3A4%3A%7Bs%3A13%3A%22host_pre_time%22%3Bs%3A10%3A%222020-01-14%22%3Bs%3A2%3A%22lt%22%3Bi%3A1579006046%3Bs%3A10%3A%22last_refer%22%3Bs%3A137%3A%22https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DuR5Oj9n_xm4TSj7_1drQ1HRnFTYNM0M2TCljkjVrdIiUE-B2qPgh0MifEkceLE_U%26wd%3D%26eqid%3D93c920a80002dc72000000035e1db85c%22%3Bs%3A5%3A%22rhost%22%3Bs%3A13%3A%22www.baidu.com%22%3B%7D%22%3B; __mfwurd=a%3A3%3A%7Bs%3A6%3A%22f_time%22%3Bi%3A1579006046%3Bs%3A9%3A%22f_rdomain%22%3Bs%3A13%3A%22www.baidu.com%22%3Bs%3A6%3A%22f_host%22%3Bs%3A3%3A%22www%22%3B%7D; __mfwuuid=5e1db855-ab4a-da12-309c-afb9cf90d3dd; UM_distinctid=16fa418373e40f-070db24dfac29d-c383f64-1fa400-16fa418373fe31; __jsluid_h=b3f11fd3c79469af5c49be9ecb7f7b86; __omc_r=; __mfwa=1579006047379.58159.3.1579011903001.1579015057723; __mfwlv=1579015057; __mfwvn=2; CNZZDATA30065558=cnzz_eid%3D448020855-1579003717-https%253A%252F%252Fwww.baidu.com%252F%26ntime%3D1579014923; bottom_ad_status=0; __mfwb=5e663dbc8869.7.direct; __mfwlt=1579019025; Hm_lpvt_8288b2ed37e5bc9b4c9f7008798d2de0=1579019026; __jsl_clearance=1579019146.235|0|fpZQ1rm7BHtgd6GdjVUIX8FJJ9o%3D'<br />}<br /><br /><br />s = requests.Session()<br /><br /><br />value = []<br /><br />defgetList(maxNum):<br /> """<br /> 獲取列表頁(yè)面數據<br /> :param maxNum: 最大抓取頁(yè)數<br /> :return:<br /> """<br /> url = 'http://www.mafengwo.cn/gonglve/'<br /> s.get(url, headers = headers)<br /> for page in range(1, maxNum + 1):<br /> data = {'page': page}<br /> response = s.post(url, data = data, headers = headers)<br /> doc = PyQuery(response.text)<br /> items = doc('.feed-item').items()<br /> for item in items:<br /> if item('.type strong').text() == '游記':<br /> # 如果是游記,則進(jìn)入內頁(yè)數據抓取<br /> inner_url = item('a').attr('href')<br /> getInfo(inner_url)<br /><br /><br />defgetInfo(url):<br /> """<br /> 獲取內頁(yè)數據<br /> :param url: 內頁(yè)鏈接<br /> :return:<br /> """<br /> response = s.get(url, headers = headers)<br /> doc = PyQuery(response.text)<br /> title = doc('title').text()<br /> # 獲取數據采集區<br /> item = doc('.tarvel_dir_list')<br /> if len(item) == 0:<br /> return<br /> time = item('.time').text()<br /> day = item('.day').text()<br /> people = item('.people').text()<br /> cost = item('.cost').text()<br /> # 數據格式化<br /> if time == '':<br /> pass<br /> else:<br /> time = time.split('/')[1] if len(time.split('/')) > 1 else ''<br /><br /> if day == '':<br /> pass<br /> else:<br /> day = day.split('/')[1] if len(day.split('/')) > 1 else ''<br /><br /> if people == '':<br /> pass<br /> else:<br /> people = people.split('/')[1] if len(people.split('/')) > 1 else ''<br /><br /> if cost == '':<br /> pass<br /> else:<br /> cost = cost.split('/')[1] if len(cost.split('/')) > 1 else ''<br /><br /><br /> value.append([title, time, day, people, cost, url])<br /><br /><br />defwrite_excel_xlsx(value):<br /> """<br /> 數據寫(xiě)入Excel<br /> :param value:<br /> :return:<br /> """<br /> index = len(value)<br /><br /> workbook = xlsxwriter.Workbook('mfw.xlsx')<br /> sheet = workbook.add_worksheet()<br /> for i in range(1, index + 1):<br /> row = 'A' + str(i)<br /> sheet.write_row(row, value[i - 1])<br /> workbook.close()<br /> print("xlsx格式表格寫(xiě)入數據成功!")<br /><br /><br />defmain():<br /> getList(5)<br /> write_excel_xlsx(value)<br /><br />if __name__ == '__main__':<br /> main()<br />
  因為馬蜂窩在游記的詳情頁(yè)面上有反爬的限制,小編這里為了簡(jiǎn)單,直接從瀏覽器中將 cookie copy 出來(lái),加在了請求頭上。
  小編這里簡(jiǎn)單的爬取了 5 個(gè)列表頁(yè)的信息,如下:
  
  好像數據量并不是很多的樣子,各位同學(xué)可以嘗試爬取 50 頁(yè)或者 100 頁(yè)的數據,這樣得到的結果會(huì )有比較不錯的參考價(jià)值。
  好了,本篇內容到這里就結束了,小編隨后會(huì )將全部的文章索引整理出來(lái)推在公眾號上,方便大家查閱。
  示例代碼
  本系列的所有代碼小編都會(huì )放在代碼管理倉庫 Github 和 Gitee 上,方便大家取用。
  示例代碼-Github:
  示例代碼-Gitee:
  
   查看全部

  小白學(xué) Python 爬蟲(chóng)(42):春節去哪里玩(系列終篇)
  
  
  
  人生苦短,我用 Python
  前文傳送門(mén):
  引言
  首先恭喜看到這篇文章的同學(xué),本篇內容為 「小白學(xué) Python 爬蟲(chóng)」 系列的最后一篇。
  
  看了下上面的前文傳送門(mén),加上這篇內容,總共有 42 篇,小編還是成就感滿(mǎn)滿(mǎn),小編翻看了下公眾號,第一篇文章是在 2019 年的 11 月 17 日推送的,大致數了數,將近兩個(gè)月的時(shí)間。
  當然,其中一些文章的質(zhì)量并不高,很多都是在比較有限的時(shí)間中趕工趕出來(lái)的,還是感謝各位讀者對小編的不離不棄,寫(xiě)的這么爛還沒(méi)取關(guān)的絕對是真愛(ài)了。
  正好下周就要過(guò)年了,從推送的時(shí)間算的話(huà)還有 10 個(gè)自然日左右的時(shí)間,可能很多同學(xué)可能過(guò)年是要出去玩的,那么去哪里玩就成了一個(gè)問(wèn)題。
  那么,怎么挑選去哪里玩最快的,小編想了想,直接去抓某站的數據吧,抓下來(lái)自己根據自己的情況查詢(xún)下就好了。
  那么今天的目標站是:馬蜂窩。
  這里小編還想說(shuō)一點(diǎn),雖然我們在前面 7、 8 篇文章中都是在講如何使用爬蟲(chóng)框架 Scrapy ,說(shuō)實(shí)話(huà),小編并不覺(jué)得 Scrapy 有多方便,在一些簡(jiǎn)單的應用場(chǎng)景下,使用 Requests 庫可能是最方便的選擇, Scrapy 小編個(gè)人感覺(jué)還是更適合使用在一些中大型的爬蟲(chóng)項目中,簡(jiǎn)單的爬蟲(chóng)腳本使用最簡(jiǎn)單的技術(shù)棧就 ok 了,所以小編在本文中使用的技術(shù)棧還是 Requests + PyQuery 。
  不要問(wèn)為啥,問(wèn)就是喜歡。
  分析
  首先我們訪(fǎng)問(wèn)鏈接,打開(kāi)我們將要抓取的站點(diǎn):。
  
  這里是攻略的列表頁(yè),我們的目標是抓取來(lái)自游記的數據,其余的數據放過(guò),原因是在游記中我們才能獲取到一些具體的我們需要的數據。
  
  數據的來(lái)源搞清楚了,接下來(lái)是翻頁(yè)功能,只有清楚了如何翻頁(yè),我們才能源源不斷的獲取數據,否則就只能抓取第一頁(yè)的數據了。
  當把頁(yè)面翻到最下面的時(shí)候就尷尬了,發(fā)現是自動(dòng)加載更多,這個(gè)當然難不倒帥氣逼人的小編我,掏出大殺器, Chrome 的開(kāi)發(fā)者工具 F12 ,選到 network 標簽頁(yè),再往下滾動(dòng)一下,我們查看下這個(gè)頁(yè)面發(fā)出的請求。
  
  這個(gè)請求很有意思,請求的路徑和我們訪(fǎng)問(wèn)的頁(yè)面路徑一樣,但是請求類(lèi)型變成 POST ,并且增加了請求參數,類(lèi)型還是 Form 表單格式的。
  截止這里,我們已經(jīng)清楚了目標站點(diǎn)的數據路徑以及翻頁(yè)方式,雖然目前我們并不知道最大頁(yè)數是多少,但是我們可以人為的設置一個(gè)最大頁(yè)數,比如 100 或者 200 ,小編相信,這么大的站點(diǎn)上,幾百頁(yè)的游記應該是還有的。
  代碼
  代碼小編就直接貼出來(lái),之前有同學(xué)希望數據是保存在 Excel 中的,本次實(shí)戰的數據就不存數據庫了,直接寫(xiě)入 Excel 。
  import requests<br />from pyquery import PyQuery<br />import xlsxwriter<br /><br />headers = {<br /> 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36',<br /> 'cookie': '__jsluid_s=6fc5b4a3b5235afbfdafff4bbf7e6dbd; PHPSESSID=v9hm8hc3s56ogrn8si12fejdm3; mfw_uuid=5e1db855-ab4a-da12-309c-afb9cf90d3dd; _r=baidu; _rp=a%3A2%3A%7Bs%3A1%3A%22p%22%3Bs%3A18%3A%22www.baidu.com%2Flink%22%3Bs%3A1%3A%22t%22%3Bi%3A1579006045%3B%7D; oad_n=a%3A5%3A%7Bs%3A5%3A%22refer%22%3Bs%3A21%3A%22https%3A%2F%2Fwww.baidu.com%22%3Bs%3A2%3A%22hp%22%3Bs%3A13%3A%22www.baidu.com%22%3Bs%3A3%3A%22oid%22%3Bi%3A1026%3Bs%3A2%3A%22dm%22%3Bs%3A15%3A%22www.mafengwo.cn%22%3Bs%3A2%3A%22ft%22%3Bs%3A19%3A%222020-01-14+20%3A47%3A25%22%3B%7D; __mfwothchid=referrer%7Cwww.baidu.com; __omc_chl=; __mfwc=referrer%7Cwww.baidu.com; Hm_lvt_8288b2ed37e5bc9b4c9f7008798d2de0=1579006048; uva=s%3A264%3A%22a%3A4%3A%7Bs%3A13%3A%22host_pre_time%22%3Bs%3A10%3A%222020-01-14%22%3Bs%3A2%3A%22lt%22%3Bi%3A1579006046%3Bs%3A10%3A%22last_refer%22%3Bs%3A137%3A%22https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DuR5Oj9n_xm4TSj7_1drQ1HRnFTYNM0M2TCljkjVrdIiUE-B2qPgh0MifEkceLE_U%26wd%3D%26eqid%3D93c920a80002dc72000000035e1db85c%22%3Bs%3A5%3A%22rhost%22%3Bs%3A13%3A%22www.baidu.com%22%3B%7D%22%3B; __mfwurd=a%3A3%3A%7Bs%3A6%3A%22f_time%22%3Bi%3A1579006046%3Bs%3A9%3A%22f_rdomain%22%3Bs%3A13%3A%22www.baidu.com%22%3Bs%3A6%3A%22f_host%22%3Bs%3A3%3A%22www%22%3B%7D; __mfwuuid=5e1db855-ab4a-da12-309c-afb9cf90d3dd; UM_distinctid=16fa418373e40f-070db24dfac29d-c383f64-1fa400-16fa418373fe31; __jsluid_h=b3f11fd3c79469af5c49be9ecb7f7b86; __omc_r=; __mfwa=1579006047379.58159.3.1579011903001.1579015057723; __mfwlv=1579015057; __mfwvn=2; CNZZDATA30065558=cnzz_eid%3D448020855-1579003717-https%253A%252F%252Fwww.baidu.com%252F%26ntime%3D1579014923; bottom_ad_status=0; __mfwb=5e663dbc8869.7.direct; __mfwlt=1579019025; Hm_lpvt_8288b2ed37e5bc9b4c9f7008798d2de0=1579019026; __jsl_clearance=1579019146.235|0|fpZQ1rm7BHtgd6GdjVUIX8FJJ9o%3D'<br />}<br /><br /><br />s = requests.Session()<br /><br /><br />value = []<br /><br />defgetList(maxNum):<br /> """<br /> 獲取列表頁(yè)面數據<br /> :param maxNum: 最大抓取頁(yè)數<br /> :return:<br /> """<br /> url = 'http://www.mafengwo.cn/gonglve/'<br /> s.get(url, headers = headers)<br /> for page in range(1, maxNum + 1):<br /> data = {'page': page}<br /> response = s.post(url, data = data, headers = headers)<br /> doc = PyQuery(response.text)<br /> items = doc('.feed-item').items()<br /> for item in items:<br /> if item('.type strong').text() == '游記':<br /> # 如果是游記,則進(jìn)入內頁(yè)數據抓取<br /> inner_url = item('a').attr('href')<br /> getInfo(inner_url)<br /><br /><br />defgetInfo(url):<br /> """<br /> 獲取內頁(yè)數據<br /> :param url: 內頁(yè)鏈接<br /> :return:<br /> """<br /> response = s.get(url, headers = headers)<br /> doc = PyQuery(response.text)<br /> title = doc('title').text()<br /> # 獲取數據采集區<br /> item = doc('.tarvel_dir_list')<br /> if len(item) == 0:<br /> return<br /> time = item('.time').text()<br /> day = item('.day').text()<br /> people = item('.people').text()<br /> cost = item('.cost').text()<br /> # 數據格式化<br /> if time == '':<br /> pass<br /> else:<br /> time = time.split('/')[1] if len(time.split('/')) > 1 else ''<br /><br /> if day == '':<br /> pass<br /> else:<br /> day = day.split('/')[1] if len(day.split('/')) > 1 else ''<br /><br /> if people == '':<br /> pass<br /> else:<br /> people = people.split('/')[1] if len(people.split('/')) > 1 else ''<br /><br /> if cost == '':<br /> pass<br /> else:<br /> cost = cost.split('/')[1] if len(cost.split('/')) > 1 else ''<br /><br /><br /> value.append([title, time, day, people, cost, url])<br /><br /><br />defwrite_excel_xlsx(value):<br /> """<br /> 數據寫(xiě)入Excel<br /> :param value:<br /> :return:<br /> """<br /> index = len(value)<br /><br /> workbook = xlsxwriter.Workbook('mfw.xlsx')<br /> sheet = workbook.add_worksheet()<br /> for i in range(1, index + 1):<br /> row = 'A' + str(i)<br /> sheet.write_row(row, value[i - 1])<br /> workbook.close()<br /> print("xlsx格式表格寫(xiě)入數據成功!")<br /><br /><br />defmain():<br /> getList(5)<br /> write_excel_xlsx(value)<br /><br />if __name__ == '__main__':<br /> main()<br />
  因為馬蜂窩在游記的詳情頁(yè)面上有反爬的限制,小編這里為了簡(jiǎn)單,直接從瀏覽器中將 cookie copy 出來(lái),加在了請求頭上。
  小編這里簡(jiǎn)單的爬取了 5 個(gè)列表頁(yè)的信息,如下:
  
  好像數據量并不是很多的樣子,各位同學(xué)可以嘗試爬取 50 頁(yè)或者 100 頁(yè)的數據,這樣得到的結果會(huì )有比較不錯的參考價(jià)值。
  好了,本篇內容到這里就結束了,小編隨后會(huì )將全部的文章索引整理出來(lái)推在公眾號上,方便大家查閱。
  示例代碼
  本系列的所有代碼小編都會(huì )放在代碼管理倉庫 Github 和 Gitee 上,方便大家取用。
  示例代碼-Github:
  示例代碼-Gitee:
  
  

一文搞懂爬蟲(chóng)Scrapy框架詳解

網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 60 次瀏覽 ? 2022-05-21 05:55 ? 來(lái)自相關(guān)話(huà)題

  一文搞懂爬蟲(chóng)Scrapy框架詳解
  
  “Python爬蟲(chóng)Scrapy框架實(shí)踐?!?
  大數據已經(jīng)滲透到當今每一個(gè)行業(yè)和業(yè)務(wù)職能領(lǐng)域,成為重要的生產(chǎn)因素?!比藗儗τ诤A繑祿耐诰蚝瓦\用越來(lái)越密切,預示著(zhù)爬蟲(chóng)工作者已經(jīng)成為互聯(lián)網(wǎng)數據公司的關(guān)鍵性職位,他們不但要精通數據抓取和分析,還要掌握搜索引擎和相關(guān)檢索的算法,對內存、性能、分布式算法都要有一定的了解,并針對工作進(jìn)程編排合理的布局。依據數據來(lái)預測某一種事物未來(lái)的發(fā)展趨勢,以及對應的風(fēng)險,提早解決未來(lái)即將遇到的風(fēng)險,防范于未然。
  一 Scrapy框架簡(jiǎn)介
  Scrapy,Python開(kāi)發(fā)的一個(gè)快速,高層次的屏幕抓取和web抓取框架,用于抓取web站點(diǎn)并從頁(yè)面中提取結構化的數據。Scrapy用途廣泛,可以用于數據挖掘、監測和自動(dòng)化測試。
  了解scrapy爬蟲(chóng)原理:Scrapy 使用了 Twisted異步網(wǎng)絡(luò )庫來(lái)處理網(wǎng)絡(luò )通訊。整體架構如下:
  
  總結-scrapy大概流程如下:
  Scrapy Engine:Scrapy引擎。負責控制數據流在系統中所有組件中流動(dòng),并在相應動(dòng)作發(fā)生時(shí)觸發(fā)事件。
  Scheduler:調度器。從Scrapy Engine接受請求(requests)并排序列入隊列,并在引擎再次請求時(shí)返回。用它來(lái)決定下一個(gè)抓取的網(wǎng)址是什么,同時(shí)去除重復的網(wǎng)址。
  Downloader:下載器。抓取網(wǎng)頁(yè)并將網(wǎng)頁(yè)內容返還給Spiders。建立在twisted異步模型。
  Spiders:爬蟲(chóng)。用戶(hù)自定義的類(lèi),主要用來(lái)解析網(wǎng)頁(yè),提取Items,發(fā)送url跟進(jìn)等新請求等。
  Item Pipelines:管道。主要用來(lái)處理Spider解析出來(lái)的Items,進(jìn)行按規則過(guò)濾,驗證,持久化存儲(如數據庫存儲)等
  Downloader Middlewares:下載中間件。位于Scrapy Engine和Downloader之間,主要是處理Scrapy引擎與下載器之間的請求及響應。
  Spider Middlewares:爬蟲(chóng)中間件。位于Scrapy Engine和Spiders之間,主要工作是處理Spiders的響應輸入和請求輸出。
  Scheduler Middlewares:調度中間件。位于Scrapy Engine和Scheduler之間。主要工作是處理從Scrapy Engine發(fā)送到Scheduler的請求和響應。
  二 Scrapy框架詳解Scrapy由Python語(yǔ)言編寫(xiě),是一個(gè)快速、高層次的屏幕抓取和Web抓取框架。1. 數據流向Scrapy數據流是由執行流程的核心引擎來(lái)控制的,流程如圖所示。
  
  框架組件數據流
  1.ScrapyEngine打開(kāi)一個(gè)網(wǎng)站,找到處理該網(wǎng)站的Spider,并向該Spider請求第一個(gè)(批)要爬取的url(s);
  2.ScrapyEngine向調度器請求第一個(gè)要爬取的url,并加入到Schedule作為請求以備調度;
  3.ScrapyEngine向調度器請求下一個(gè)要爬取的url;
  4.Schedule返回下一個(gè)要爬取的url給ScrapyEngine,ScrapyEngine通過(guò)DownloaderMiddlewares將url轉發(fā)給Downloader;
  5.頁(yè)面下載完畢,Downloader生成一個(gè)頁(yè)面的Response,通過(guò)DownloaderMiddlewares發(fā)送給ScrapyEngine;
  6.ScrapyEngine從Downloader中接收到Response,通過(guò)SpiderMiddlewares發(fā)送給Spider處理;
  7.Spider處理Response并返回提取到的Item以及新的Request給ScrapyEngine;
  8.ScrapyEngine將Spider返回的Item交給ItemPipeline,將Spider返回的Request交給Schedule進(jìn)行從第二步開(kāi)始的重復操作,直到調度器中沒(méi)有待處理的Request,ScrapyEngine關(guān)閉。
  2Scrapy 的運作流程
  制作 Scrapy 爬蟲(chóng) 一共需要 4 步:
  1 新建項目 (scrapy startproject xxx):新建一個(gè)新的爬蟲(chóng)項目
  2 明確目標 (編寫(xiě) items.py):明確你想要抓取的目標,想要爬什么信息
  3 制作爬蟲(chóng) (spiders/xxspider.py):制作爬蟲(chóng)開(kāi)始爬取網(wǎng)頁(yè)
  4 存儲內容 (pipelines.py):設計管道存儲爬取內容
  具體流程
  1、scrapy安裝
  pip install scrapy<br /><br />Successfully installed Automat-20.2.0 PyDispatcher-2.0.5 Twisted-21.2.0 attrs-21.2.0 constantly-15.1.0 cssselect-1.1.0 h2-3.2.0 hpack-3.0.0 hyperframe-5.2.0 hyperlink-21.0.0 incremental-21.3.0 itemadapter-0.2.0 itemloaders-1.0.4 parsel-1.6.0 priority-1.3.0 protego-0.1.16 pyOpenSSL-20.0.1 pyasn1-0.4.8 pyasn1-modules-0.2.8 queuelib-1.6.1 scrapy-2.5.0 service-identity-21.1.0 twisted-iocpsupport-1.0.1 w3lib-1.22.0 zope.interface-5.4.0
  檢查是否安裝成功:
  scrapy?versionScrapy 2.5.0
  scrapy常用命令使用:
  
  Usage: scrapy [options] [args]<br />Available commands: bench Run quick benchmark test check Check spider contracts commands crawl Run a spider edit Edit spider fetch Fetch a URL using the Scrapy downloader genspider Generate new spider using pre-defined templates list List available spiders parse Parse URL (using its spider) and print the results runspider Run a self-contained spider (without creating a project) settings Get settings values shell Interactive scraping console startproject Create new project version Print Scrapy version view Open URL in browser, as seen by Scrapy<br />Use "scrapy -h" to see more info about a command
  2、創(chuàng )建項目
  //創(chuàng )建一個(gè)測試項目scrapy startproject scrapyproject<br />New Scrapy project 'scrapyproject', using template directory 'c:\users\username\appdata\local\programs\python\python36\lib\site-packages\scrapy\templates\project', created in: C:\Users\username\PycharmProjects\scrapyproject<br />You can start your first spider with: cd scrapyproject scrapy genspider example example.com
  3、第一個(gè)爬蟲(chóng)項目
  注釋?zhuān)?
  scrapy genspider -l 查看當前可以使用的爬蟲(chóng)模板
  scrapy genspider -t 創(chuàng )建爬蟲(chóng)文件
  1.scrapy?startproject?scrapyproject2.在工程目錄下創(chuàng )建爬蟲(chóng)baidu 格式:scrapy genspider [-t template] <br />支持模板template:basic(默認)、crawl、csvfeed、xmlfeed這里name是爬蟲(chóng)的名字;domain是設置allowed_domains以及start_urls,這兩個(gè)屬性可以在爬蟲(chóng)類(lèi)中修改<br /><br />cd scrapyprojectscrapy?genspider?baidu?baidu.com?(baidu?為爬蟲(chóng)的名稱(chēng),baidu.com為要爬取的網(wǎng)站的域名)<br />輸出:Created spider 'baidu' using template 'basic' in module: scrapyproject.spiders.baidu<br />3.使用pycharm 打開(kāi)第一步創(chuàng )建的項目
  目錄及文件結構:
  
  文件說(shuō)明:
  scrapy.cfg 項目的配置信息,主要為Scrapy命令行工具提供一個(gè)基礎的配置信息。(真正爬蟲(chóng)相關(guān)的配置信息在settings.py文件中)
  items.py 設置數據存儲模板,用于結構化數據,如:Django的Model
  pipelines 數據處理行為,如:一般結構化的數據持久化
  settings.py 配置文件,如:遞歸的層數、并發(fā)數,延遲下載等
  spiders 爬蟲(chóng)目錄,如:創(chuàng )建文件,編寫(xiě)爬蟲(chóng)規則
  注意:一般創(chuàng )建爬蟲(chóng)文件時(shí),以網(wǎng)站域名命名。
  4. cd 項目目錄,重寫(xiě)parse函數,然后啟動(dòng)爬蟲(chóng),命令:
  
  注意ROBOTSTXT_OBEY = False baidu的robots.txt里面禁止了scrapy
  scrapy?crawl?baidu
  生成爬取結果
  
  打開(kāi)是界面:
  
  05Scrapy?;ňW(wǎng)爬取實(shí)踐
  以?;ňW(wǎng)為例進(jìn)行爬取,?;ňW(wǎng):
  創(chuàng )建xiaohuar spider:
  scrapy genspider xiaohuar xiaohuar.comCreated spider 'xiaohuar' using template 'basic' in module: scrapyproject.spiders.xiaohuar
  準備: 查看全部

  一文搞懂爬蟲(chóng)Scrapy框架詳解
  
  “Python爬蟲(chóng)Scrapy框架實(shí)踐?!?
  大數據已經(jīng)滲透到當今每一個(gè)行業(yè)和業(yè)務(wù)職能領(lǐng)域,成為重要的生產(chǎn)因素?!比藗儗τ诤A繑祿耐诰蚝瓦\用越來(lái)越密切,預示著(zhù)爬蟲(chóng)工作者已經(jīng)成為互聯(lián)網(wǎng)數據公司的關(guān)鍵性職位,他們不但要精通數據抓取和分析,還要掌握搜索引擎和相關(guān)檢索的算法,對內存、性能、分布式算法都要有一定的了解,并針對工作進(jìn)程編排合理的布局。依據數據來(lái)預測某一種事物未來(lái)的發(fā)展趨勢,以及對應的風(fēng)險,提早解決未來(lái)即將遇到的風(fēng)險,防范于未然。
  一 Scrapy框架簡(jiǎn)介
  Scrapy,Python開(kāi)發(fā)的一個(gè)快速,高層次的屏幕抓取和web抓取框架,用于抓取web站點(diǎn)并從頁(yè)面中提取結構化的數據。Scrapy用途廣泛,可以用于數據挖掘、監測和自動(dòng)化測試。
  了解scrapy爬蟲(chóng)原理:Scrapy 使用了 Twisted異步網(wǎng)絡(luò )庫來(lái)處理網(wǎng)絡(luò )通訊。整體架構如下:
  
  總結-scrapy大概流程如下:
  Scrapy Engine:Scrapy引擎。負責控制數據流在系統中所有組件中流動(dòng),并在相應動(dòng)作發(fā)生時(shí)觸發(fā)事件。
  Scheduler:調度器。從Scrapy Engine接受請求(requests)并排序列入隊列,并在引擎再次請求時(shí)返回。用它來(lái)決定下一個(gè)抓取的網(wǎng)址是什么,同時(shí)去除重復的網(wǎng)址。
  Downloader:下載器。抓取網(wǎng)頁(yè)并將網(wǎng)頁(yè)內容返還給Spiders。建立在twisted異步模型。
  Spiders:爬蟲(chóng)。用戶(hù)自定義的類(lèi),主要用來(lái)解析網(wǎng)頁(yè),提取Items,發(fā)送url跟進(jìn)等新請求等。
  Item Pipelines:管道。主要用來(lái)處理Spider解析出來(lái)的Items,進(jìn)行按規則過(guò)濾,驗證,持久化存儲(如數據庫存儲)等
  Downloader Middlewares:下載中間件。位于Scrapy Engine和Downloader之間,主要是處理Scrapy引擎與下載器之間的請求及響應。
  Spider Middlewares:爬蟲(chóng)中間件。位于Scrapy Engine和Spiders之間,主要工作是處理Spiders的響應輸入和請求輸出。
  Scheduler Middlewares:調度中間件。位于Scrapy Engine和Scheduler之間。主要工作是處理從Scrapy Engine發(fā)送到Scheduler的請求和響應。
  二 Scrapy框架詳解Scrapy由Python語(yǔ)言編寫(xiě),是一個(gè)快速、高層次的屏幕抓取和Web抓取框架。1. 數據流向Scrapy數據流是由執行流程的核心引擎來(lái)控制的,流程如圖所示。
  
  框架組件數據流
  1.ScrapyEngine打開(kāi)一個(gè)網(wǎng)站,找到處理該網(wǎng)站的Spider,并向該Spider請求第一個(gè)(批)要爬取的url(s);
  2.ScrapyEngine向調度器請求第一個(gè)要爬取的url,并加入到Schedule作為請求以備調度;
  3.ScrapyEngine向調度器請求下一個(gè)要爬取的url;
  4.Schedule返回下一個(gè)要爬取的url給ScrapyEngine,ScrapyEngine通過(guò)DownloaderMiddlewares將url轉發(fā)給Downloader;
  5.頁(yè)面下載完畢,Downloader生成一個(gè)頁(yè)面的Response,通過(guò)DownloaderMiddlewares發(fā)送給ScrapyEngine;
  6.ScrapyEngine從Downloader中接收到Response,通過(guò)SpiderMiddlewares發(fā)送給Spider處理;
  7.Spider處理Response并返回提取到的Item以及新的Request給ScrapyEngine;
  8.ScrapyEngine將Spider返回的Item交給ItemPipeline,將Spider返回的Request交給Schedule進(jìn)行從第二步開(kāi)始的重復操作,直到調度器中沒(méi)有待處理的Request,ScrapyEngine關(guān)閉。
  2Scrapy 的運作流程
  制作 Scrapy 爬蟲(chóng) 一共需要 4 步:
  1 新建項目 (scrapy startproject xxx):新建一個(gè)新的爬蟲(chóng)項目
  2 明確目標 (編寫(xiě) items.py):明確你想要抓取的目標,想要爬什么信息
  3 制作爬蟲(chóng) (spiders/xxspider.py):制作爬蟲(chóng)開(kāi)始爬取網(wǎng)頁(yè)
  4 存儲內容 (pipelines.py):設計管道存儲爬取內容
  具體流程
  1、scrapy安裝
  pip install scrapy<br /><br />Successfully installed Automat-20.2.0 PyDispatcher-2.0.5 Twisted-21.2.0 attrs-21.2.0 constantly-15.1.0 cssselect-1.1.0 h2-3.2.0 hpack-3.0.0 hyperframe-5.2.0 hyperlink-21.0.0 incremental-21.3.0 itemadapter-0.2.0 itemloaders-1.0.4 parsel-1.6.0 priority-1.3.0 protego-0.1.16 pyOpenSSL-20.0.1 pyasn1-0.4.8 pyasn1-modules-0.2.8 queuelib-1.6.1 scrapy-2.5.0 service-identity-21.1.0 twisted-iocpsupport-1.0.1 w3lib-1.22.0 zope.interface-5.4.0
  檢查是否安裝成功:
  scrapy?versionScrapy 2.5.0
  scrapy常用命令使用:
  
  Usage: scrapy [options] [args]<br />Available commands: bench Run quick benchmark test check Check spider contracts commands crawl Run a spider edit Edit spider fetch Fetch a URL using the Scrapy downloader genspider Generate new spider using pre-defined templates list List available spiders parse Parse URL (using its spider) and print the results runspider Run a self-contained spider (without creating a project) settings Get settings values shell Interactive scraping console startproject Create new project version Print Scrapy version view Open URL in browser, as seen by Scrapy<br />Use "scrapy -h" to see more info about a command
  2、創(chuàng )建項目
  //創(chuàng )建一個(gè)測試項目scrapy startproject scrapyproject<br />New Scrapy project 'scrapyproject', using template directory 'c:\users\username\appdata\local\programs\python\python36\lib\site-packages\scrapy\templates\project', created in: C:\Users\username\PycharmProjects\scrapyproject<br />You can start your first spider with: cd scrapyproject scrapy genspider example example.com
  3、第一個(gè)爬蟲(chóng)項目
  注釋?zhuān)?
  scrapy genspider -l 查看當前可以使用的爬蟲(chóng)模板
  scrapy genspider -t 創(chuàng )建爬蟲(chóng)文件
  1.scrapy?startproject?scrapyproject2.在工程目錄下創(chuàng )建爬蟲(chóng)baidu 格式:scrapy genspider [-t template] <br />支持模板template:basic(默認)、crawl、csvfeed、xmlfeed這里name是爬蟲(chóng)的名字;domain是設置allowed_domains以及start_urls,這兩個(gè)屬性可以在爬蟲(chóng)類(lèi)中修改<br /><br />cd scrapyprojectscrapy?genspider?baidu?baidu.com?(baidu?為爬蟲(chóng)的名稱(chēng),baidu.com為要爬取的網(wǎng)站的域名)<br />輸出:Created spider 'baidu' using template 'basic' in module: scrapyproject.spiders.baidu<br />3.使用pycharm 打開(kāi)第一步創(chuàng )建的項目
  目錄及文件結構:
  
  文件說(shuō)明:
  scrapy.cfg 項目的配置信息,主要為Scrapy命令行工具提供一個(gè)基礎的配置信息。(真正爬蟲(chóng)相關(guān)的配置信息在settings.py文件中)
  items.py 設置數據存儲模板,用于結構化數據,如:Django的Model
  pipelines 數據處理行為,如:一般結構化的數據持久化
  settings.py 配置文件,如:遞歸的層數、并發(fā)數,延遲下載等
  spiders 爬蟲(chóng)目錄,如:創(chuàng )建文件,編寫(xiě)爬蟲(chóng)規則
  注意:一般創(chuàng )建爬蟲(chóng)文件時(shí),以網(wǎng)站域名命名。
  4. cd 項目目錄,重寫(xiě)parse函數,然后啟動(dòng)爬蟲(chóng),命令:
  
  注意ROBOTSTXT_OBEY = False baidu的robots.txt里面禁止了scrapy
  scrapy?crawl?baidu
  生成爬取結果
  
  打開(kāi)是界面:
  
  05Scrapy?;ňW(wǎng)爬取實(shí)踐
  以?;ňW(wǎng)為例進(jìn)行爬取,?;ňW(wǎng):
  創(chuàng )建xiaohuar spider:
  scrapy genspider xiaohuar xiaohuar.comCreated spider 'xiaohuar' using template 'basic' in module: scrapyproject.spiders.xiaohuar
  準備:

Python爬蟲(chóng)—破解JS加密的Cookie

網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 288 次瀏覽 ? 2022-05-21 02:21 ? 來(lái)自相關(guān)話(huà)題

  Python爬蟲(chóng)—破解JS加密的Cookie
  專(zhuān) 欄
  
  ?Jerry,Python中文社區專(zhuān)欄作者。
  blog:
  github:
  ?前言 在GitHub上維護了一個(gè)代理池的項目,代理來(lái)源是抓取一些免費的代理發(fā)布網(wǎng)站。上午有個(gè)小哥告訴我說(shuō)有個(gè)代理抓取接口不能用了,返回狀態(tài)521。抱著(zhù)幫人解決問(wèn)題的心態(tài)去跑了一遍代碼。發(fā)現果真是這樣。
  通過(guò)Fiddler抓包比較,基本可以確定是JavaScript生成加密Cookie導致原來(lái)的請求返回521。
  發(fā)現問(wèn)題
  打開(kāi)Fiddler軟件,用瀏覽器打開(kāi)目標站點(diǎn)() ??梢园l(fā)現瀏覽器對這個(gè)頁(yè)面加載了兩次,第一次返回521,第二次才正常返回數據。很多沒(méi)有寫(xiě)過(guò)網(wǎng)站或是爬蟲(chóng)經(jīng)驗不足的童鞋,可能就會(huì )覺(jué)得奇怪為什么會(huì )這樣?為什么瀏覽器可能正常返回數據而代碼卻不行?
  
  仔細觀(guān)察兩次返回的結果可以發(fā)現:
  
  
  1、第二次請求比第一次請求的Cookie內容多了個(gè)這個(gè)_ydclearance=0c316df6ea04c5281b421aa8-5570-47ae-9768-2510d9fe971
  2、第一次返回的內容一些復雜看不懂的JS代碼,第二次返回的就是正確的內容
  其實(shí)這是網(wǎng)站反爬蟲(chóng)的常用手段。大致過(guò)程是這樣的:首次請求數據時(shí),服務(wù)端返回動(dòng)態(tài)的混淆加密過(guò)的JS,而這段JS的作用是給Cookie添加新的內容用于服務(wù)端驗證,此時(shí)返回的狀態(tài)碼是521。瀏覽器帶上新的Cookie再次請求,服務(wù)端驗證Cookie通過(guò)返回數據(這也是為嘛代碼不能返回數據的原因)。
  解決問(wèn)題
  其實(shí)我第一次遇到這樣的問(wèn)題是,一開(kāi)始想的就是既然你是用JS生成的Cookie, 那么我也可以將JS函數翻譯成Python運行。但是最后還是發(fā)現我太傻太天真,因為現在的JS都流行混淆加密,原始的JS這樣的:
  <p>function lq(VA) {
   ? ?var qo, mo = "", no = "", oo = [0x8c, 0xcd, 0x4c, 0xf9, 0xd7, 0x4d, 0x25, 0xba, 0x3c, 0x16, 0x96, 0x44, 0x8d, 0x0b, 0x90, 0x1e, 0xa3, 0x39, 0xc9, 0x86, 0x23, 0x61, 0x2f, 0xc8, 0x30, 0xdd, 0x57, 0xec, 0x92, 0x84, 0xc4, 0x6a, 0xeb, 0x99, 0x37, 0xeb, 0x25, 0x0e, 0xbb, 0xb0, 0x95, 0x76, 0x45, 0xde, 0x80, 0x59, 0xf6, 0x9c, 0x58, 0x39, 0x12, 0xc7, 0x9c, 0x8d, 0x18, 0xe0, 0xc5, 0x77, 0x50, 0x39, 0x01, 0xed, 0x93, 0x39, 0x02, 0x7e, 0x72, 0x4f, 0x24, 0x01, 0xe9, 0x66, 0x75, 0x4e, 0x2b, 0xd8, 0x6e, 0xe2, 0xfa, 0xc7, 0xa4, 0x85, 0x4e, 0xc2, 0xa5, 0x96, 0x6b, 0x58, 0x39, 0xd2, 0x7f, 0x44, 0xe5, 0x7b, 0x48, 0x2d, 0xf6, 0xdf, 0xbc, 0x31, 0x1e, 0xf6, 0xbf, 0x84, 0x6d, 0x5e, 0x33, 0x0c, 0x97, 0x5c, 0x39, 0x26, 0xf2, 0x9b, 0x77, 0x0d, 0xd6, 0xc0, 0x46, 0x38, 0x5f, 0xf4, 0xe2, 0x9f, 0xf1, 0x7b, 0xe8, 0xbe, 0x37, 0xdf, 0xd0, 0xbd, 0xb9, 0x36, 0x2c, 0xd1, 0xc3, 0x40, 0xe7, 0xcc, 0xa9, 0x52, 0x3b, 0x20, 0x40, 0x09, 0xe1, 0xd2, 0xa3, 0x80, 0x25, 0x0a, 0xb2, 0xd8, 0xce, 0x21, 0x69, 0x3e, 0xe6, 0x80, 0xfd, 0x73, 0xab, 0x51, 0xde, 0x60, 0x15, 0x95, 0x07, 0x94, 0x6a, 0x18, 0x9d, 0x37, 0x31, 0xde, 0x64, 0xdd, 0x63, 0xe3, 0x57, 0x05, 0x82, 0xff, 0xcc, 0x75, 0x79, 0x63, 0x09, 0xe2, 0x6c, 0x21, 0x5c, 0xe0, 0x7d, 0x4a, 0xf2, 0xd8, 0x9c, 0x22, 0xa3, 0x3d, 0xba, 0xa0, 0xaf, 0x30, 0xc1, 0x47, 0xf4, 0xca, 0xee, 0x64, 0xf9, 0x7b, 0x55, 0xd5, 0xd2, 0x4c, 0xc9, 0x7f, 0x25, 0xfe, 0x48, 0xcd, 0x4b, 0xcc, 0x81, 0x1b, 0x05, 0x82, 0x38, 0x0e, 0x83, 0x19, 0xe3, 0x65, 0x3f, 0xbf, 0x16, 0x88, 0x93, 0xdd, 0x3b];<p> ? ?qo = "qo=241; do{oo[qo]=(-oo[qo])&0xff; oo[qo]=(((oo[qo]>>3)|((oo[qo] 查看全部

  Python爬蟲(chóng)—破解JS加密的Cookie
  專(zhuān) 欄
  
  ?Jerry,Python中文社區專(zhuān)欄作者。
  blog:
  github:
  ?前言 在GitHub上維護了一個(gè)代理池的項目,代理來(lái)源是抓取一些免費的代理發(fā)布網(wǎng)站。上午有個(gè)小哥告訴我說(shuō)有個(gè)代理抓取接口不能用了,返回狀態(tài)521。抱著(zhù)幫人解決問(wèn)題的心態(tài)去跑了一遍代碼。發(fā)現果真是這樣。
  通過(guò)Fiddler抓包比較,基本可以確定是JavaScript生成加密Cookie導致原來(lái)的請求返回521。
  發(fā)現問(wèn)題
  打開(kāi)Fiddler軟件,用瀏覽器打開(kāi)目標站點(diǎn)() ??梢园l(fā)現瀏覽器對這個(gè)頁(yè)面加載了兩次,第一次返回521,第二次才正常返回數據。很多沒(méi)有寫(xiě)過(guò)網(wǎng)站或是爬蟲(chóng)經(jīng)驗不足的童鞋,可能就會(huì )覺(jué)得奇怪為什么會(huì )這樣?為什么瀏覽器可能正常返回數據而代碼卻不行?
  
  仔細觀(guān)察兩次返回的結果可以發(fā)現:
  
  
  1、第二次請求比第一次請求的Cookie內容多了個(gè)這個(gè)_ydclearance=0c316df6ea04c5281b421aa8-5570-47ae-9768-2510d9fe971
  2、第一次返回的內容一些復雜看不懂的JS代碼,第二次返回的就是正確的內容
  其實(shí)這是網(wǎng)站反爬蟲(chóng)的常用手段。大致過(guò)程是這樣的:首次請求數據時(shí),服務(wù)端返回動(dòng)態(tài)的混淆加密過(guò)的JS,而這段JS的作用是給Cookie添加新的內容用于服務(wù)端驗證,此時(shí)返回的狀態(tài)碼是521。瀏覽器帶上新的Cookie再次請求,服務(wù)端驗證Cookie通過(guò)返回數據(這也是為嘛代碼不能返回數據的原因)。
  解決問(wèn)題
  其實(shí)我第一次遇到這樣的問(wèn)題是,一開(kāi)始想的就是既然你是用JS生成的Cookie, 那么我也可以將JS函數翻譯成Python運行。但是最后還是發(fā)現我太傻太天真,因為現在的JS都流行混淆加密,原始的JS這樣的:
  <p>function lq(VA) {
   ? ?var qo, mo = "", no = "", oo = [0x8c, 0xcd, 0x4c, 0xf9, 0xd7, 0x4d, 0x25, 0xba, 0x3c, 0x16, 0x96, 0x44, 0x8d, 0x0b, 0x90, 0x1e, 0xa3, 0x39, 0xc9, 0x86, 0x23, 0x61, 0x2f, 0xc8, 0x30, 0xdd, 0x57, 0xec, 0x92, 0x84, 0xc4, 0x6a, 0xeb, 0x99, 0x37, 0xeb, 0x25, 0x0e, 0xbb, 0xb0, 0x95, 0x76, 0x45, 0xde, 0x80, 0x59, 0xf6, 0x9c, 0x58, 0x39, 0x12, 0xc7, 0x9c, 0x8d, 0x18, 0xe0, 0xc5, 0x77, 0x50, 0x39, 0x01, 0xed, 0x93, 0x39, 0x02, 0x7e, 0x72, 0x4f, 0x24, 0x01, 0xe9, 0x66, 0x75, 0x4e, 0x2b, 0xd8, 0x6e, 0xe2, 0xfa, 0xc7, 0xa4, 0x85, 0x4e, 0xc2, 0xa5, 0x96, 0x6b, 0x58, 0x39, 0xd2, 0x7f, 0x44, 0xe5, 0x7b, 0x48, 0x2d, 0xf6, 0xdf, 0xbc, 0x31, 0x1e, 0xf6, 0xbf, 0x84, 0x6d, 0x5e, 0x33, 0x0c, 0x97, 0x5c, 0x39, 0x26, 0xf2, 0x9b, 0x77, 0x0d, 0xd6, 0xc0, 0x46, 0x38, 0x5f, 0xf4, 0xe2, 0x9f, 0xf1, 0x7b, 0xe8, 0xbe, 0x37, 0xdf, 0xd0, 0xbd, 0xb9, 0x36, 0x2c, 0xd1, 0xc3, 0x40, 0xe7, 0xcc, 0xa9, 0x52, 0x3b, 0x20, 0x40, 0x09, 0xe1, 0xd2, 0xa3, 0x80, 0x25, 0x0a, 0xb2, 0xd8, 0xce, 0x21, 0x69, 0x3e, 0xe6, 0x80, 0xfd, 0x73, 0xab, 0x51, 0xde, 0x60, 0x15, 0x95, 0x07, 0x94, 0x6a, 0x18, 0x9d, 0x37, 0x31, 0xde, 0x64, 0xdd, 0x63, 0xe3, 0x57, 0x05, 0x82, 0xff, 0xcc, 0x75, 0x79, 0x63, 0x09, 0xe2, 0x6c, 0x21, 0x5c, 0xe0, 0x7d, 0x4a, 0xf2, 0xd8, 0x9c, 0x22, 0xa3, 0x3d, 0xba, 0xa0, 0xaf, 0x30, 0xc1, 0x47, 0xf4, 0xca, 0xee, 0x64, 0xf9, 0x7b, 0x55, 0xd5, 0xd2, 0x4c, 0xc9, 0x7f, 0x25, 0xfe, 0x48, 0xcd, 0x4b, 0xcc, 0x81, 0x1b, 0x05, 0x82, 0x38, 0x0e, 0x83, 0x19, 0xe3, 0x65, 0x3f, 0xbf, 0x16, 0x88, 0x93, 0xdd, 0x3b];<p> ? ?qo = "qo=241; do{oo[qo]=(-oo[qo])&0xff; oo[qo]=(((oo[qo]>>3)|((oo[qo]

一只知乎爬蟲(chóng)

網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 202 次瀏覽 ? 2022-05-15 05:53 ? 來(lái)自相關(guān)話(huà)題

  一只知乎爬蟲(chóng)
  本文經(jīng)作者授權發(fā)布。
  文 | 程柳鋒@Tencent
  爬蟲(chóng)的基本流程
  
  網(wǎng)絡(luò )爬蟲(chóng)的基本工作流程如下:
  爬蟲(chóng)的抓取策略
  在爬蟲(chóng)系統中,待抓取 URL 隊列是很重要的一部分。待抓取 URL 隊列中的 URL 以什么樣的順序排列也是一個(gè)很重要的問(wèn)題,因為這涉及到先抓取那個(gè)頁(yè)面,后抓取哪個(gè)頁(yè)面。而決定這些 URL 排列順序的方法,叫做抓取策略。下面重點(diǎn)介紹幾種常見(jiàn)的抓取策略:
  
  了解了爬蟲(chóng)的工作流程和爬取策略后,就可以動(dòng)手實(shí)現一個(gè)爬蟲(chóng)了!那么在 python 里怎么實(shí)現呢?
  技術(shù)?;緦?shí)現
  下面是一個(gè)偽代碼
  <p>import Queue
  initial_page = "https://www.zhihu.com/people/gaoming623"
  url_queue = Queue.Queue()
  seen = set()
  seen.insert(initial_page)
  url_queue.put(initial_page)
  while(True): #一直進(jìn)行
   ? ?if url_queue.size()>0:
   ? ? ? ?current_url = url_queue.get() ? ? ? ? ? ? ?#拿出隊例中第一個(gè)的 url
   ? ? ? ?store(current_url) ? ? ? ? ? ? ? ? ? ? ? ? #把這個(gè) url 代表的網(wǎng)頁(yè)存儲好
   ? ? ? ?for next_url in extract_urls(current_url): #提取把這個(gè) url 里鏈向的 url
   ? ? ? ? ? ?if next_url not in seen: ? ? ?
   ? ? ? ? ? ? ? ?seen.put(next_url)
   ? ? ? ? ? ? ? ?url_queue.put(next_url)
   ? ?else:
   ? ? ? ?break</p>
  如果你直接加工一下上面的代碼直接運行的話(huà),你需要很長(cháng)的時(shí)間才能爬下整個(gè)知乎用戶(hù)的信息,畢竟知乎有 6000 萬(wàn)月活躍用戶(hù)。更別說(shuō) Google 這樣的搜索引擎需要爬下全網(wǎng)的內容了。那么問(wèn)題出現在哪里?
  布隆過(guò)濾器
  需要爬的網(wǎng)頁(yè)實(shí)在太多太多了,而上面的代碼太慢太慢了。設想全網(wǎng)有 N 個(gè)網(wǎng)站,那么分析一下判重的復雜度就是 N*log(N),因為所有網(wǎng)頁(yè)要遍歷一次,而每次判重用 set 的話(huà)需要 log(N) 的復雜度。OK,我知道 python 的 set 實(shí)現是 hash——不過(guò)這樣還是太慢了,至少內存使用效率不高。
  通常的判重做法是怎樣呢?Bloom Filter. 簡(jiǎn)單講它仍然是一種 hash 的方法,但是它的特點(diǎn)是,它可以使用固定的內存(不隨 url 的數量而增長(cháng))以 O(1) 的效率判定 url 是否已經(jīng)在 set 中??上煜聸](méi)有白吃的午餐,它的唯一問(wèn)題在于,如果這個(gè) url 不在 set 中,BF 可以 100%確定這個(gè) url 沒(méi)有看過(guò)。但是如果這個(gè) url 在 set 中,它會(huì )告訴你:這個(gè) url 應該已經(jīng)出現過(guò),不過(guò)我有 2%的不確定性。注意這里的不確定性在你分配的內存足夠大的時(shí)候,可以變得很小很少。
  <p># bloom_filter.py
  BIT_SIZE = 5000000
  class BloomFilter:
   ? ?def __init__(self):
   ? ? ? ?# Initialize bloom filter, set size and all bits to 0
   ? ? ? ?bit_array = bitarray(BIT_SIZE)
   ? ? ? ?bit_array.setall(0)
   ? ? ? ?self.bit_array = bit_array
   ? ?def add(self, url):
   ? ? ? ?# Add a url, and set points in bitarray to 1 (Points count is equal to hash funcs count.)
   ? ? ? ?# Here use 7 hash functions.
   ? ? ? ?point_list = self.get_postions(url)
   ? ? ? ?for b in point_list:
   ? ? ? ? ? ?self.bit_array[b] = 1
   ? ?def contains(self, url):
   ? ? ? ?# Check if a url is in a collection
   ? ? ? ?point_list = self.get_postions(url)
   ? ? ? ?result = True
   ? ? ? ?for b in point_list:
   ? ? ? ? ? ?result = result and self.bit_array[b]
   ? ? ? ?return result
   ? ?def get_postions(self, url):
   ? ? ? ?# Get points positions in bit vector.
   ? ? ? ?point1 = mmh3.hash(url, 41) % BIT_SIZE
   ? ? ? ?point2 = mmh3.hash(url, 42) % BIT_SIZE
   ? ? ? ?point3 = mmh3.hash(url, 43) % BIT_SIZE
   ? ? ? ?point4 = mmh3.hash(url, 44) % BIT_SIZE
   ? ? ? ?point5 = mmh3.hash(url, 45) % BIT_SIZE
   ? ? ? ?point6 = mmh3.hash(url, 46) % BIT_SIZE
   ? ? ? ?point7 = mmh3.hash(url, 47) % BIT_SIZE
   ? ? ? ?return [point1, point2, point3, point4, point5, point6, point7]</p>
  BF 詳細的原理參考我之前寫(xiě)的文章:布隆過(guò)濾器(Bloom Filter) 的原理和實(shí)現
  建表
  用戶(hù)有價(jià)值的信息包括用戶(hù)名、簡(jiǎn)介、行業(yè)、院校、專(zhuān)業(yè)及在平臺上活動(dòng)的數據比如回答數、文章數、提問(wèn)數、粉絲數等等。
  用戶(hù)信息存儲的表結構如下:
  <p>CREATE DATABASE `zhihu_user` /*!40100 DEFAULT CHARACTER SET utf8 */;
  -- User base information table
  CREATE TABLE `t_user` (
   ?`uid` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
   ?`username` varchar(50) NOT NULL COMMENT '用戶(hù)名', ? ? ? ? ? ? ? ? ? ? ?
   ?`brief_info` varchar(400) ?COMMENT '個(gè)人簡(jiǎn)介',
   ?`industry` varchar(50) COMMENT '所處行業(yè)', ? ? ? ? ? ?
   ?`education` varchar(50) COMMENT '畢業(yè)院校', ? ? ? ? ? ?
   ?`major` varchar(50) COMMENT '主修專(zhuān)業(yè)',
   ?`answer_count` int(10) unsigned DEFAULT 0 COMMENT '回答數',
   ?`article_count` int(10) unsigned DEFAULT 0 COMMENT '文章數',
   ?`ask_question_count` int(10) unsigned DEFAULT 0 COMMENT '提問(wèn)數',
   ?`collection_count` int(10) unsigned DEFAULT 0 COMMENT '收藏數',
   ?`follower_count` int(10) unsigned DEFAULT 0 COMMENT '被關(guān)注數',
   ?`followed_count` int(10) unsigned DEFAULT 0 COMMENT '關(guān)注數',
   ?`follow_live_count` int(10) unsigned DEFAULT 0 COMMENT '關(guān)注直播數',
   ?`follow_topic_count` int(10) unsigned DEFAULT 0 COMMENT '關(guān)注話(huà)題數',
   ?`follow_column_count` int(10) unsigned DEFAULT 0 COMMENT '關(guān)注專(zhuān)欄數',
   ?`follow_question_count` int(10) unsigned DEFAULT 0 COMMENT '關(guān)注問(wèn)題數',
   ?`follow_collection_count` int(10) unsigned DEFAULT 0 COMMENT '關(guān)注收藏夾數',
   ?`gmt_create` datetime NOT NULL COMMENT '創(chuàng )建時(shí)間', ?
   ?`gmt_modify` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '最后一次編輯', ? ? ? ? ? ?
   ?PRIMARY KEY (`uid`)
  ) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='用戶(hù)基本信息表';</p>
  網(wǎng)頁(yè)下載后通過(guò) XPath 進(jìn)行解析,提取用戶(hù)各個(gè)維度的數據,最后保存到數據庫中。
  反爬蟲(chóng)策略應對-Headers
  一般網(wǎng)站會(huì )從幾個(gè)維度來(lái)反爬蟲(chóng):用戶(hù)請求的 Headers,用戶(hù)行為,網(wǎng)站和數據加載的方式。從用戶(hù)請求的 Headers 反爬蟲(chóng)是最常見(jiàn)的策略,很多網(wǎng)站都會(huì )對 Headers 的 User-Agent 進(jìn)行檢測,還有一部分網(wǎng)站會(huì )對 Referer 進(jìn)行檢測(一些資源網(wǎng)站的防盜鏈就是檢測 Referer)。
  如果遇到了這類(lèi)反爬蟲(chóng)機制,可以直接在爬蟲(chóng)中添加 Headers,將瀏覽器的 User-Agent 復制到爬蟲(chóng)的 Headers 中;或者將 Referer 值修改為目標網(wǎng)站域名。對于檢測 Headers 的反爬蟲(chóng),在爬蟲(chóng)中修改或者添加 Headers 就能很好的繞過(guò)。
  <p>cookies = {
   ? ?"d_c0": "AECA7v-aPwqPTiIbemmIQ8abhJy7bdD2VgE=|1468847182",
   ? ?"login": "NzM5ZDc2M2JkYzYwNDZlOGJlYWQ1YmI4OTg5NDhmMTY=|1480901173|9c296f424b32f241d1471203244eaf30729420f0",
   ? ?"n_c": "1",
   ? ?"q_c1": "395b12e529e541cbb400e9718395e346|1479808003000|1468847182000",
   ? ?"l_cap_id": "NzI0MTQwZGY2NjQyNDQ1NThmYTY0MjJhYmU2NmExMGY=|1480901160|2e7a7faee3b3e8d0afb550e8e7b38d86c15a31bc",
   ? ?"d_c0": "AECA7v-aPwqPTiIbemmIQ8abhJy7bdD2VgE=|1468847182",
   ? ?"cap_id": "N2U1NmQwODQ1NjFiNGI2Yzg2YTE2NzJkOTU5N2E0NjI=|1480901160|fd59e2ed79faacc2be1010687d27dd559ec1552a"
  }
  headers = {
   ? ?"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.98 Safari/537.3",
   ? ?"Referer": "https://www.zhihu.com/"
  }
  r = requests.get(url, cookies = cookies, headers = headers)</p>
  反爬蟲(chóng)策略應對-代理 IP 池
  還有一部分網(wǎng)站是通過(guò)檢測用戶(hù)行為,例如同一 IP 短時(shí)間內多次訪(fǎng)問(wèn)同一頁(yè)面,或者同一賬戶(hù)短時(shí)間內多次進(jìn)行相同操作。
  大多數網(wǎng)站都是前一種情況,對于這種情況,使用 IP 代理就可以解決。這樣的代理 ip 爬蟲(chóng)經(jīng)常會(huì )用到,最好自己準備一個(gè)。有了大量代理 ip 后可以每請求幾次更換一個(gè) ip,這在 requests 或者 urllib2 中很容易做到,這樣就能很容易的繞過(guò)第一種反爬蟲(chóng)。目前知乎已經(jīng)對爬蟲(chóng)做了限制,如果是單個(gè) IP 的話(huà),一段時(shí)間系統便會(huì )提示異常流量,無(wú)法繼續爬取了。因此代理 IP 池非常關(guān)鍵。網(wǎng)上有個(gè)免費的代理 IP API:
  <p>import requests
  import random
  class Proxy:
   ? ?def __init__(self):
   ? ? ? ?self.cache_ip_list = []
   ? ?# Get random ip from free proxy api url.
   ? ?def get_random_ip(self):
   ? ? ? ?if not len(self.cache_ip_list):
   ? ? ? ? ? ?api_url = 'http://api.xicidaili.com/free2016.txt'
   ? ? ? ? ? ?try:
   ? ? ? ? ? ? ? ?r = requests.get(api_url)
   ? ? ? ? ? ? ? ?ip_list = r.text.split('rn')
   ? ? ? ? ? ? ? ?self.cache_ip_list = ip_list
   ? ? ? ? ? ?except Exception as e:
   ? ? ? ? ? ? ? ?# Return null list when caught exception.
   ? ? ? ? ? ? ? ?# In this case, crawler will not use proxy ip.
   ? ? ? ? ? ? ? ?print e
   ? ? ? ? ? ? ? ?return {}
   ? ? ? ?proxy_ip = random.choice(self.cache_ip_list)
   ? ? ? ?proxies = {'http': 'http://' ? proxy_ip}
   ? ? ? ?return proxies</p>
  后續
  爬蟲(chóng)源代碼:zhihu-crawler下載之后通過(guò) pip 安裝相關(guān)三方包后,運行$ python crawler.py 即可(喜歡的幫忙點(diǎn)個(gè) star 哈,同時(shí)也方便看到后續功能的更新)
  運行截圖:
   查看全部

  一只知乎爬蟲(chóng)
  本文經(jīng)作者授權發(fā)布。
  文 | 程柳鋒@Tencent
  爬蟲(chóng)的基本流程
  
  網(wǎng)絡(luò )爬蟲(chóng)的基本工作流程如下:
  爬蟲(chóng)的抓取策略
  在爬蟲(chóng)系統中,待抓取 URL 隊列是很重要的一部分。待抓取 URL 隊列中的 URL 以什么樣的順序排列也是一個(gè)很重要的問(wèn)題,因為這涉及到先抓取那個(gè)頁(yè)面,后抓取哪個(gè)頁(yè)面。而決定這些 URL 排列順序的方法,叫做抓取策略。下面重點(diǎn)介紹幾種常見(jiàn)的抓取策略:
  
  了解了爬蟲(chóng)的工作流程和爬取策略后,就可以動(dòng)手實(shí)現一個(gè)爬蟲(chóng)了!那么在 python 里怎么實(shí)現呢?
  技術(shù)?;緦?shí)現
  下面是一個(gè)偽代碼
  <p>import Queue
  initial_page = "https://www.zhihu.com/people/gaoming623"
  url_queue = Queue.Queue()
  seen = set()
  seen.insert(initial_page)
  url_queue.put(initial_page)
  while(True): #一直進(jìn)行
   ? ?if url_queue.size()>0:
   ? ? ? ?current_url = url_queue.get() ? ? ? ? ? ? ?#拿出隊例中第一個(gè)的 url
   ? ? ? ?store(current_url) ? ? ? ? ? ? ? ? ? ? ? ? #把這個(gè) url 代表的網(wǎng)頁(yè)存儲好
   ? ? ? ?for next_url in extract_urls(current_url): #提取把這個(gè) url 里鏈向的 url
   ? ? ? ? ? ?if next_url not in seen: ? ? ?
   ? ? ? ? ? ? ? ?seen.put(next_url)
   ? ? ? ? ? ? ? ?url_queue.put(next_url)
   ? ?else:
   ? ? ? ?break</p>
  如果你直接加工一下上面的代碼直接運行的話(huà),你需要很長(cháng)的時(shí)間才能爬下整個(gè)知乎用戶(hù)的信息,畢竟知乎有 6000 萬(wàn)月活躍用戶(hù)。更別說(shuō) Google 這樣的搜索引擎需要爬下全網(wǎng)的內容了。那么問(wèn)題出現在哪里?
  布隆過(guò)濾器
  需要爬的網(wǎng)頁(yè)實(shí)在太多太多了,而上面的代碼太慢太慢了。設想全網(wǎng)有 N 個(gè)網(wǎng)站,那么分析一下判重的復雜度就是 N*log(N),因為所有網(wǎng)頁(yè)要遍歷一次,而每次判重用 set 的話(huà)需要 log(N) 的復雜度。OK,我知道 python 的 set 實(shí)現是 hash——不過(guò)這樣還是太慢了,至少內存使用效率不高。
  通常的判重做法是怎樣呢?Bloom Filter. 簡(jiǎn)單講它仍然是一種 hash 的方法,但是它的特點(diǎn)是,它可以使用固定的內存(不隨 url 的數量而增長(cháng))以 O(1) 的效率判定 url 是否已經(jīng)在 set 中??上煜聸](méi)有白吃的午餐,它的唯一問(wèn)題在于,如果這個(gè) url 不在 set 中,BF 可以 100%確定這個(gè) url 沒(méi)有看過(guò)。但是如果這個(gè) url 在 set 中,它會(huì )告訴你:這個(gè) url 應該已經(jīng)出現過(guò),不過(guò)我有 2%的不確定性。注意這里的不確定性在你分配的內存足夠大的時(shí)候,可以變得很小很少。
  <p># bloom_filter.py
  BIT_SIZE = 5000000
  class BloomFilter:
   ? ?def __init__(self):
   ? ? ? ?# Initialize bloom filter, set size and all bits to 0
   ? ? ? ?bit_array = bitarray(BIT_SIZE)
   ? ? ? ?bit_array.setall(0)
   ? ? ? ?self.bit_array = bit_array
   ? ?def add(self, url):
   ? ? ? ?# Add a url, and set points in bitarray to 1 (Points count is equal to hash funcs count.)
   ? ? ? ?# Here use 7 hash functions.
   ? ? ? ?point_list = self.get_postions(url)
   ? ? ? ?for b in point_list:
   ? ? ? ? ? ?self.bit_array[b] = 1
   ? ?def contains(self, url):
   ? ? ? ?# Check if a url is in a collection
   ? ? ? ?point_list = self.get_postions(url)
   ? ? ? ?result = True
   ? ? ? ?for b in point_list:
   ? ? ? ? ? ?result = result and self.bit_array[b]
   ? ? ? ?return result
   ? ?def get_postions(self, url):
   ? ? ? ?# Get points positions in bit vector.
   ? ? ? ?point1 = mmh3.hash(url, 41) % BIT_SIZE
   ? ? ? ?point2 = mmh3.hash(url, 42) % BIT_SIZE
   ? ? ? ?point3 = mmh3.hash(url, 43) % BIT_SIZE
   ? ? ? ?point4 = mmh3.hash(url, 44) % BIT_SIZE
   ? ? ? ?point5 = mmh3.hash(url, 45) % BIT_SIZE
   ? ? ? ?point6 = mmh3.hash(url, 46) % BIT_SIZE
   ? ? ? ?point7 = mmh3.hash(url, 47) % BIT_SIZE
   ? ? ? ?return [point1, point2, point3, point4, point5, point6, point7]</p>
  BF 詳細的原理參考我之前寫(xiě)的文章:布隆過(guò)濾器(Bloom Filter) 的原理和實(shí)現
  建表
  用戶(hù)有價(jià)值的信息包括用戶(hù)名、簡(jiǎn)介、行業(yè)、院校、專(zhuān)業(yè)及在平臺上活動(dòng)的數據比如回答數、文章數、提問(wèn)數、粉絲數等等。
  用戶(hù)信息存儲的表結構如下:
  <p>CREATE DATABASE `zhihu_user` /*!40100 DEFAULT CHARACTER SET utf8 */;
  -- User base information table
  CREATE TABLE `t_user` (
   ?`uid` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
   ?`username` varchar(50) NOT NULL COMMENT '用戶(hù)名', ? ? ? ? ? ? ? ? ? ? ?
   ?`brief_info` varchar(400) ?COMMENT '個(gè)人簡(jiǎn)介',
   ?`industry` varchar(50) COMMENT '所處行業(yè)', ? ? ? ? ? ?
   ?`education` varchar(50) COMMENT '畢業(yè)院校', ? ? ? ? ? ?
   ?`major` varchar(50) COMMENT '主修專(zhuān)業(yè)',
   ?`answer_count` int(10) unsigned DEFAULT 0 COMMENT '回答數',
   ?`article_count` int(10) unsigned DEFAULT 0 COMMENT '文章數',
   ?`ask_question_count` int(10) unsigned DEFAULT 0 COMMENT '提問(wèn)數',
   ?`collection_count` int(10) unsigned DEFAULT 0 COMMENT '收藏數',
   ?`follower_count` int(10) unsigned DEFAULT 0 COMMENT '被關(guān)注數',
   ?`followed_count` int(10) unsigned DEFAULT 0 COMMENT '關(guān)注數',
   ?`follow_live_count` int(10) unsigned DEFAULT 0 COMMENT '關(guān)注直播數',
   ?`follow_topic_count` int(10) unsigned DEFAULT 0 COMMENT '關(guān)注話(huà)題數',
   ?`follow_column_count` int(10) unsigned DEFAULT 0 COMMENT '關(guān)注專(zhuān)欄數',
   ?`follow_question_count` int(10) unsigned DEFAULT 0 COMMENT '關(guān)注問(wèn)題數',
   ?`follow_collection_count` int(10) unsigned DEFAULT 0 COMMENT '關(guān)注收藏夾數',
   ?`gmt_create` datetime NOT NULL COMMENT '創(chuàng )建時(shí)間', ?
   ?`gmt_modify` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '最后一次編輯', ? ? ? ? ? ?
   ?PRIMARY KEY (`uid`)
  ) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='用戶(hù)基本信息表';</p>
  網(wǎng)頁(yè)下載后通過(guò) XPath 進(jìn)行解析,提取用戶(hù)各個(gè)維度的數據,最后保存到數據庫中。
  反爬蟲(chóng)策略應對-Headers
  一般網(wǎng)站會(huì )從幾個(gè)維度來(lái)反爬蟲(chóng):用戶(hù)請求的 Headers,用戶(hù)行為,網(wǎng)站和數據加載的方式。從用戶(hù)請求的 Headers 反爬蟲(chóng)是最常見(jiàn)的策略,很多網(wǎng)站都會(huì )對 Headers 的 User-Agent 進(jìn)行檢測,還有一部分網(wǎng)站會(huì )對 Referer 進(jìn)行檢測(一些資源網(wǎng)站的防盜鏈就是檢測 Referer)。
  如果遇到了這類(lèi)反爬蟲(chóng)機制,可以直接在爬蟲(chóng)中添加 Headers,將瀏覽器的 User-Agent 復制到爬蟲(chóng)的 Headers 中;或者將 Referer 值修改為目標網(wǎng)站域名。對于檢測 Headers 的反爬蟲(chóng),在爬蟲(chóng)中修改或者添加 Headers 就能很好的繞過(guò)。
  <p>cookies = {
   ? ?"d_c0": "AECA7v-aPwqPTiIbemmIQ8abhJy7bdD2VgE=|1468847182",
   ? ?"login": "NzM5ZDc2M2JkYzYwNDZlOGJlYWQ1YmI4OTg5NDhmMTY=|1480901173|9c296f424b32f241d1471203244eaf30729420f0",
   ? ?"n_c": "1",
   ? ?"q_c1": "395b12e529e541cbb400e9718395e346|1479808003000|1468847182000",
   ? ?"l_cap_id": "NzI0MTQwZGY2NjQyNDQ1NThmYTY0MjJhYmU2NmExMGY=|1480901160|2e7a7faee3b3e8d0afb550e8e7b38d86c15a31bc",
   ? ?"d_c0": "AECA7v-aPwqPTiIbemmIQ8abhJy7bdD2VgE=|1468847182",
   ? ?"cap_id": "N2U1NmQwODQ1NjFiNGI2Yzg2YTE2NzJkOTU5N2E0NjI=|1480901160|fd59e2ed79faacc2be1010687d27dd559ec1552a"
  }
  headers = {
   ? ?"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.98 Safari/537.3",
   ? ?"Referer": "https://www.zhihu.com/"
  }
  r = requests.get(url, cookies = cookies, headers = headers)</p>
  反爬蟲(chóng)策略應對-代理 IP 池
  還有一部分網(wǎng)站是通過(guò)檢測用戶(hù)行為,例如同一 IP 短時(shí)間內多次訪(fǎng)問(wèn)同一頁(yè)面,或者同一賬戶(hù)短時(shí)間內多次進(jìn)行相同操作。
  大多數網(wǎng)站都是前一種情況,對于這種情況,使用 IP 代理就可以解決。這樣的代理 ip 爬蟲(chóng)經(jīng)常會(huì )用到,最好自己準備一個(gè)。有了大量代理 ip 后可以每請求幾次更換一個(gè) ip,這在 requests 或者 urllib2 中很容易做到,這樣就能很容易的繞過(guò)第一種反爬蟲(chóng)。目前知乎已經(jīng)對爬蟲(chóng)做了限制,如果是單個(gè) IP 的話(huà),一段時(shí)間系統便會(huì )提示異常流量,無(wú)法繼續爬取了。因此代理 IP 池非常關(guān)鍵。網(wǎng)上有個(gè)免費的代理 IP API:
  <p>import requests
  import random
  class Proxy:
   ? ?def __init__(self):
   ? ? ? ?self.cache_ip_list = []
   ? ?# Get random ip from free proxy api url.
   ? ?def get_random_ip(self):
   ? ? ? ?if not len(self.cache_ip_list):
   ? ? ? ? ? ?api_url = 'http://api.xicidaili.com/free2016.txt'
   ? ? ? ? ? ?try:
   ? ? ? ? ? ? ? ?r = requests.get(api_url)
   ? ? ? ? ? ? ? ?ip_list = r.text.split('rn')
   ? ? ? ? ? ? ? ?self.cache_ip_list = ip_list
   ? ? ? ? ? ?except Exception as e:
   ? ? ? ? ? ? ? ?# Return null list when caught exception.
   ? ? ? ? ? ? ? ?# In this case, crawler will not use proxy ip.
   ? ? ? ? ? ? ? ?print e
   ? ? ? ? ? ? ? ?return {}
   ? ? ? ?proxy_ip = random.choice(self.cache_ip_list)
   ? ? ? ?proxies = {'http': 'http://' ? proxy_ip}
   ? ? ? ?return proxies</p>
  后續
  爬蟲(chóng)源代碼:zhihu-crawler下載之后通過(guò) pip 安裝相關(guān)三方包后,運行$ python crawler.py 即可(喜歡的幫忙點(diǎn)個(gè) star 哈,同時(shí)也方便看到后續功能的更新)
  運行截圖:
  

c爬蟲(chóng)抓取網(wǎng)頁(yè)數據正常情況下發(fā)生的場(chǎng)景是什么?

網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 103 次瀏覽 ? 2022-09-06 16:02 ? 來(lái)自相關(guān)話(huà)題

  c爬蟲(chóng)抓取網(wǎng)頁(yè)數據正常情況下發(fā)生的場(chǎng)景是什么?
  c爬蟲(chóng)抓取網(wǎng)頁(yè)數據正常情況下發(fā)生的場(chǎng)景是:用戶(hù)發(fā)起一次請求,從瀏覽器的user-agent(瀏覽器上面一個(gè)host或者cookie)里面獲取對應的body,然后交給爬蟲(chóng)解析交給c段發(fā)起連接請求,兩邊繼續一對一的發(fā)起請求,但是一般情況下連接建立得不是太多,所以一般來(lái)說(shuō)單方面只能發(fā)起一次連接請求。但是,機器比較多的情況下,系統可能就要發(fā)起一次連接請求了,比如加入了多種進(jìn)程,那么這個(gè)連接請求可能連接多個(gè)進(jìn)程,甚至數十個(gè)進(jìn)程,在本文中,我們以一個(gè)前端每秒發(fā)起三次連接請求為例,將爬蟲(chóng)和后端連接請求相連接原理一次連接請求解析圖解1:從user-agent我們知道用戶(hù)瀏覽器里面的user-agent,瀏覽器在接收到了連接請求之后,首先會(huì )首先去查看請求里面的參數,看這些參數指定的資源是不是自己想要的,一般的發(fā)送的時(shí)候都會(huì )帶著(zhù)對應的headers,比如cookie之類(lèi)的。
  
  那么連接請求用到了哪些參數?user-agent:你要發(fā)送的user-agent-agent-名:你想發(fā)送的user-agent-agent-數:你想發(fā)送的user-agent-agent-cookie:你發(fā)送的user-agent-agent-數值那么requestheaders就是我們最常用的兩個(gè)參數,頭部的部分跟request沒(méi)什么區別,這里重點(diǎn)看一下服務(wù)端參數第一個(gè)參數是cookie,前面請求里面也提到了,這個(gè)cookie在別的連接請求里面可能會(huì )用到;其次還有一個(gè)cookiebanner,也就是獲取cookie的通道,一般來(lái)說(shuō)可以用httpcookie連接推送http請求推送完cookie之后,后面這些數據就不再重復發(fā)送了。
  
  第二個(gè)是服務(wù)端可以獲取到的參數還有:cookie的host和max-age設置你的端口及子域名之類(lèi)的對第一個(gè)參數進(jìn)行檢查,如果是一個(gè)比較熟悉自己程序請求的人,他會(huì )知道使用自己家的服務(wù)器,或者是自己家的機器,或者是自己家機器的內部連接,實(shí)際上你還可以在后臺找到一些端口。對第二個(gè)參數,我們一般也是根據自己的業(yè)務(wù)來(lái)選擇對應的參數,如果要抓的數據量大,我們的連接請求數可能就會(huì )很多,或者對user-agent提供了頭部的cookie可以直接在相應設置連接請求,如果需要抓多個(gè)不同資源,在不太熟悉的情況下,最好就抓取一個(gè),進(jìn)行連接請求,這樣可以減輕連接請求的負擔,而使得連接效率更高。
  2:給請求加上代理如果要發(fā)送多個(gè)user-agent請求,那么一個(gè)個(gè)的發(fā)送這種連接請求會(huì )很慢的,那么可以加一個(gè)代理服務(wù)器進(jìn)行發(fā)送,代理服務(wù)器可以是公網(wǎng)的,也可以是爬蟲(chóng)自己的機器,速度比在本地發(fā)送要快,而且,代理服務(wù)器里面數據也是你自己配置的,這樣可以防止惡意爬蟲(chóng)連接請求到你的程序。那么。 查看全部

  c爬蟲(chóng)抓取網(wǎng)頁(yè)數據正常情況下發(fā)生的場(chǎng)景是什么?
  c爬蟲(chóng)抓取網(wǎng)頁(yè)數據正常情況下發(fā)生的場(chǎng)景是:用戶(hù)發(fā)起一次請求,從瀏覽器的user-agent(瀏覽器上面一個(gè)host或者cookie)里面獲取對應的body,然后交給爬蟲(chóng)解析交給c段發(fā)起連接請求,兩邊繼續一對一的發(fā)起請求,但是一般情況下連接建立得不是太多,所以一般來(lái)說(shuō)單方面只能發(fā)起一次連接請求。但是,機器比較多的情況下,系統可能就要發(fā)起一次連接請求了,比如加入了多種進(jìn)程,那么這個(gè)連接請求可能連接多個(gè)進(jìn)程,甚至數十個(gè)進(jìn)程,在本文中,我們以一個(gè)前端每秒發(fā)起三次連接請求為例,將爬蟲(chóng)和后端連接請求相連接原理一次連接請求解析圖解1:從user-agent我們知道用戶(hù)瀏覽器里面的user-agent,瀏覽器在接收到了連接請求之后,首先會(huì )首先去查看請求里面的參數,看這些參數指定的資源是不是自己想要的,一般的發(fā)送的時(shí)候都會(huì )帶著(zhù)對應的headers,比如cookie之類(lèi)的。
  
  那么連接請求用到了哪些參數?user-agent:你要發(fā)送的user-agent-agent-名:你想發(fā)送的user-agent-agent-數:你想發(fā)送的user-agent-agent-cookie:你發(fā)送的user-agent-agent-數值那么requestheaders就是我們最常用的兩個(gè)參數,頭部的部分跟request沒(méi)什么區別,這里重點(diǎn)看一下服務(wù)端參數第一個(gè)參數是cookie,前面請求里面也提到了,這個(gè)cookie在別的連接請求里面可能會(huì )用到;其次還有一個(gè)cookiebanner,也就是獲取cookie的通道,一般來(lái)說(shuō)可以用httpcookie連接推送http請求推送完cookie之后,后面這些數據就不再重復發(fā)送了。
  
  第二個(gè)是服務(wù)端可以獲取到的參數還有:cookie的host和max-age設置你的端口及子域名之類(lèi)的對第一個(gè)參數進(jìn)行檢查,如果是一個(gè)比較熟悉自己程序請求的人,他會(huì )知道使用自己家的服務(wù)器,或者是自己家的機器,或者是自己家機器的內部連接,實(shí)際上你還可以在后臺找到一些端口。對第二個(gè)參數,我們一般也是根據自己的業(yè)務(wù)來(lái)選擇對應的參數,如果要抓的數據量大,我們的連接請求數可能就會(huì )很多,或者對user-agent提供了頭部的cookie可以直接在相應設置連接請求,如果需要抓多個(gè)不同資源,在不太熟悉的情況下,最好就抓取一個(gè),進(jìn)行連接請求,這樣可以減輕連接請求的負擔,而使得連接效率更高。
  2:給請求加上代理如果要發(fā)送多個(gè)user-agent請求,那么一個(gè)個(gè)的發(fā)送這種連接請求會(huì )很慢的,那么可以加一個(gè)代理服務(wù)器進(jìn)行發(fā)送,代理服務(wù)器可以是公網(wǎng)的,也可以是爬蟲(chóng)自己的機器,速度比在本地發(fā)送要快,而且,代理服務(wù)器里面數據也是你自己配置的,這樣可以防止惡意爬蟲(chóng)連接請求到你的程序。那么。

c爬蟲(chóng)抓取網(wǎng)頁(yè)數據,使用session使得爬蟲(chóng)程序間隔時(shí)間不需要很長(cháng)

網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 85 次瀏覽 ? 2022-08-28 03:09 ? 來(lái)自相關(guān)話(huà)題

  c爬蟲(chóng)抓取網(wǎng)頁(yè)數據,使用session使得爬蟲(chóng)程序間隔時(shí)間不需要很長(cháng)
  
  c爬蟲(chóng)抓取網(wǎng)頁(yè)數據,使用session使得爬蟲(chóng)程序間隔時(shí)間不需要很長(cháng),節省了很多計算量。url解析,用urllib3本身并不需要session,而采用scrapy框架scrapy框架要實(shí)現不同url間的切換時(shí)候需要session,并且每個(gè)spider的不同url解析采用不同的spiderspider所以三者實(shí)現邏輯差異不大以下代碼是在scrapy框架下實(shí)現的,spider如下:pythonurllib3installscrapyimportscrapyimportseleniumimportrequestsimporttimedefgetpage(url):selenium.webdriver.chrome().executable['chromedriver.exe']2:#文件目錄和文件名有要求,一般>2try:drivermanager(x)exceptexceptionase:print('{0}'.format(e))returnnoneurl=getpage('')drivermanager(x)#使用chrome瀏覽器命令fromin(url)fromax(url)#定位瀏覽器輸入url時(shí)候的錯誤drivermanager(x。 查看全部

  c爬蟲(chóng)抓取網(wǎng)頁(yè)數據,使用session使得爬蟲(chóng)程序間隔時(shí)間不需要很長(cháng)
  
  c爬蟲(chóng)抓取網(wǎng)頁(yè)數據,使用session使得爬蟲(chóng)程序間隔時(shí)間不需要很長(cháng),節省了很多計算量。url解析,用urllib3本身并不需要session,而采用scrapy框架scrapy框架要實(shí)現不同url間的切換時(shí)候需要session,并且每個(gè)spider的不同url解析采用不同的spiderspider所以三者實(shí)現邏輯差異不大以下代碼是在scrapy框架下實(shí)現的,spider如下:pythonurllib3installscrapyimportscrapyimportseleniumimportrequestsimporttimedefgetpage(url):selenium.webdriver.chrome().executable['chromedriver.exe']2:#文件目錄和文件名有要求,一般>2try:drivermanager(x)exceptexceptionase:print('{0}'.format(e))returnnoneurl=getpage('')drivermanager(x)#使用chrome瀏覽器命令fromin(url)fromax(url)#定位瀏覽器輸入url時(shí)候的錯誤drivermanager(x。

網(wǎng)絡(luò )爬蟲(chóng)入門(mén)之python

網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 89 次瀏覽 ? 2022-08-09 02:18 ? 來(lái)自相關(guān)話(huà)題

  網(wǎng)絡(luò )爬蟲(chóng)入門(mén)之python
  網(wǎng)絡(luò )爬蟲(chóng)定義:
 ?。▉?lái)自于百度百科):網(wǎng)絡(luò )爬蟲(chóng)(又稱(chēng)為網(wǎng)頁(yè)蜘蛛,網(wǎng)絡(luò )機器人,在FOAF社區中間,更經(jīng)常的稱(chēng)為網(wǎng)頁(yè)追逐者),是一種按照一定的規則,自動(dòng)地抓取萬(wàn)維網(wǎng)信息的程序或者腳本。另外一些不常使用的名字還有螞蟻、自動(dòng)索引、模擬程序或者蠕蟲(chóng)。
  為什么要學(xué):
  在數據爆發(fā)式增長(cháng)時(shí)代,如果這些數據得以分析利用,可以幫助企業(yè)更好的做出決策。網(wǎng)絡(luò )爬蟲(chóng)技術(shù),也是大數據分析的第一個(gè)環(huán)節。
  Robots協(xié)議(爬蟲(chóng)協(xié)議)
  全稱(chēng)是網(wǎng)絡(luò )爬蟲(chóng)排除標準,通過(guò)該協(xié)議告訴搜索引擎哪些頁(yè)面可以抓取,哪些不能抓取。是國際互聯(lián)網(wǎng)通行的道德規范,雖然沒(méi)有寫(xiě)入法律,但每一個(gè)爬蟲(chóng)都應該遵守這項協(xié)議。
  python
 ?。▉?lái)自于百度百科):Python由荷蘭數學(xué)和計算機科學(xué)研究學(xué)會(huì )的吉多·范羅蘇姆于1990年代初設計,作為一門(mén)叫做ABC語(yǔ)言的替代品。Python提供了高效的高級數據結構,還能簡(jiǎn)單有效地面向對象編程。Python語(yǔ)法和動(dòng)態(tài)類(lèi)型,以及解釋型語(yǔ)言的本質(zhì),使它成為多數平臺上寫(xiě)腳本和快速開(kāi)發(fā)應用的編程語(yǔ)言, 隨著(zhù)版本的不斷更新和語(yǔ)言新功能的添加,逐漸被用于獨立的、大型項目的開(kāi)發(fā)。
  Python解釋器易于擴展,可以使用C語(yǔ)言或C++(或者其他可以通過(guò)C調用的語(yǔ)言)擴展新的功能和數據類(lèi)型。Python也可用于可定制化軟件中的擴展程序語(yǔ)言。Python豐富的標準庫,提供了適用于各個(gè)主要系統平臺的源碼或機器碼。
  2021年10月,語(yǔ)言流行指數的編譯器Tiobe將Python加冕為最受歡迎的編程語(yǔ)言,20年來(lái)首次將其置于Java、C和JavaScript之上。
  
  版本很多,本次使用python3
  python爬蟲(chóng)流程
  重要知識點(diǎn):
  獲取網(wǎng)頁(yè):requests、urllib、selenium
  解析網(wǎng)頁(yè):re正則表達式、BeautifulSoup、lxml
  存儲數據:存入txt、csv、存入mysql、redis、mongodb等
  框架:scrapy
  python 安裝
  使用Anaconda科學(xué)計算環(huán)境下載python
  安裝步驟 自行搜索百度,有很多,其實(shí)就是下一步下一步。使用pip安裝第三方庫或者使用Anaconda安裝第三方庫。
  
  編輯器:Pycharm
  如果你使用Python安裝包下載的python,推薦使用pycharm編輯器。下載免費版即可,官網(wǎng)好像被墻了。
  python之初嘗試
  python之爬蟲(chóng)初嘗試 查看全部

  網(wǎng)絡(luò )爬蟲(chóng)入門(mén)之python
  網(wǎng)絡(luò )爬蟲(chóng)定義:
 ?。▉?lái)自于百度百科):網(wǎng)絡(luò )爬蟲(chóng)(又稱(chēng)為網(wǎng)頁(yè)蜘蛛,網(wǎng)絡(luò )機器人,在FOAF社區中間,更經(jīng)常的稱(chēng)為網(wǎng)頁(yè)追逐者),是一種按照一定的規則,自動(dòng)地抓取萬(wàn)維網(wǎng)信息的程序或者腳本。另外一些不常使用的名字還有螞蟻、自動(dòng)索引、模擬程序或者蠕蟲(chóng)。
  為什么要學(xué):
  在數據爆發(fā)式增長(cháng)時(shí)代,如果這些數據得以分析利用,可以幫助企業(yè)更好的做出決策。網(wǎng)絡(luò )爬蟲(chóng)技術(shù),也是大數據分析的第一個(gè)環(huán)節。
  Robots協(xié)議(爬蟲(chóng)協(xié)議)
  全稱(chēng)是網(wǎng)絡(luò )爬蟲(chóng)排除標準,通過(guò)該協(xié)議告訴搜索引擎哪些頁(yè)面可以抓取,哪些不能抓取。是國際互聯(lián)網(wǎng)通行的道德規范,雖然沒(méi)有寫(xiě)入法律,但每一個(gè)爬蟲(chóng)都應該遵守這項協(xié)議。
  python
 ?。▉?lái)自于百度百科):Python由荷蘭數學(xué)和計算機科學(xué)研究學(xué)會(huì )的吉多·范羅蘇姆于1990年代初設計,作為一門(mén)叫做ABC語(yǔ)言的替代品。Python提供了高效的高級數據結構,還能簡(jiǎn)單有效地面向對象編程。Python語(yǔ)法和動(dòng)態(tài)類(lèi)型,以及解釋型語(yǔ)言的本質(zhì),使它成為多數平臺上寫(xiě)腳本和快速開(kāi)發(fā)應用的編程語(yǔ)言, 隨著(zhù)版本的不斷更新和語(yǔ)言新功能的添加,逐漸被用于獨立的、大型項目的開(kāi)發(fā)。
  Python解釋器易于擴展,可以使用C語(yǔ)言或C++(或者其他可以通過(guò)C調用的語(yǔ)言)擴展新的功能和數據類(lèi)型。Python也可用于可定制化軟件中的擴展程序語(yǔ)言。Python豐富的標準庫,提供了適用于各個(gè)主要系統平臺的源碼或機器碼。
  2021年10月,語(yǔ)言流行指數的編譯器Tiobe將Python加冕為最受歡迎的編程語(yǔ)言,20年來(lái)首次將其置于Java、C和JavaScript之上。
  
  版本很多,本次使用python3
  python爬蟲(chóng)流程
  重要知識點(diǎn):
  獲取網(wǎng)頁(yè):requests、urllib、selenium
  解析網(wǎng)頁(yè):re正則表達式、BeautifulSoup、lxml
  存儲數據:存入txt、csv、存入mysql、redis、mongodb等
  框架:scrapy
  python 安裝
  使用Anaconda科學(xué)計算環(huán)境下載python
  安裝步驟 自行搜索百度,有很多,其實(shí)就是下一步下一步。使用pip安裝第三方庫或者使用Anaconda安裝第三方庫。
  
  編輯器:Pycharm
  如果你使用Python安裝包下載的python,推薦使用pycharm編輯器。下載免費版即可,官網(wǎng)好像被墻了。
  python之初嘗試
  python之爬蟲(chóng)初嘗試

c爬蟲(chóng)抓取網(wǎng)頁(yè)數據,比如百度全部關(guān)鍵詞爬蟲(chóng)。

網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 116 次瀏覽 ? 2022-08-05 14:05 ? 來(lái)自相關(guān)話(huà)題

  c爬蟲(chóng)抓取網(wǎng)頁(yè)數據,比如百度全部關(guān)鍵詞爬蟲(chóng)。
  c爬蟲(chóng)抓取網(wǎng)頁(yè)數據,比如百度全部關(guān)鍵詞爬蟲(chóng)。update2:20190913又看了一下,問(wèn)題中是純元數據。本身元數據沒(méi)有地域歸屬。這樣設置,useragent提供的信息僅限于ip和mac地址,而你能爬取的并不是這些信息。你需要axios+request來(lái)注冊scrapy,才能爬取以外的信息。以下為20190710補充:github上有提供examples:examples|scrapy學(xué)習。
  
  nlp方面,有一些國內論壇可以去學(xué)習。比如,通過(guò)python的poc文本識別正則表達式(抓取百度網(wǎng)頁(yè)上的文本信息,并翻譯英文,但非微信的文章信息)。
  如果你是零基礎的話(huà),推薦去csdn看看一個(gè)和你問(wèn)題有相似需求的人在使用什么框架和數據庫。web的話(huà),爬蟲(chóng)爬取評論數據用前端selenium。找相關(guān)的網(wǎng)站翻譯一下。如果可以看懂的話(huà)可以試著(zhù)寫(xiě)一個(gè)爬蟲(chóng)這樣。我目前是這么干的,具體不太懂。感覺(jué)時(shí)間比較緊,
  
  回答你的問(wèn)題首先要說(shuō)明的是,市面上比較多,國內的,國外的,mongodb等等很多,我只知道其中的一款,如果你想學(xué)習爬蟲(chóng)的話(huà),建議去學(xué)習一下,因為爬蟲(chóng)要對各種兼容性進(jìn)行分析,可能你需要寫(xiě)幾個(gè)框架,從最開(kāi)始的caffe到其他的,從此要自己寫(xiě)框架,初學(xué)的話(huà),這些框架你可以選擇一個(gè),其實(shí)安卓,ios都可以搭建自己的網(wǎng)站,反正不都是web嗎,所以你也可以去學(xué)習一下。
  并不是不會(huì ),是因為沒(méi)經(jīng)歷過(guò),作為初學(xué)者,建議還是先學(xué)一些框架,比如requests+xpath+beautifulsoup4(因為本人java基礎不是很好,所以選擇了前三個(gè),做練習可以選擇其他的)lxmlpyquery等等或者直接學(xué)一下flaskpyramid都可以。自己先去學(xué)一下其他的,然后了解一下api,通過(guò)各種api寫(xiě)一個(gè)網(wǎng)站,網(wǎng)站出來(lái)以后在選擇一個(gè)框架,這樣一來(lái),一切都會(huì )水到渠成。 查看全部

  c爬蟲(chóng)抓取網(wǎng)頁(yè)數據,比如百度全部關(guān)鍵詞爬蟲(chóng)。
  c爬蟲(chóng)抓取網(wǎng)頁(yè)數據,比如百度全部關(guān)鍵詞爬蟲(chóng)。update2:20190913又看了一下,問(wèn)題中是純元數據。本身元數據沒(méi)有地域歸屬。這樣設置,useragent提供的信息僅限于ip和mac地址,而你能爬取的并不是這些信息。你需要axios+request來(lái)注冊scrapy,才能爬取以外的信息。以下為20190710補充:github上有提供examples:examples|scrapy學(xué)習。
  
  nlp方面,有一些國內論壇可以去學(xué)習。比如,通過(guò)python的poc文本識別正則表達式(抓取百度網(wǎng)頁(yè)上的文本信息,并翻譯英文,但非微信的文章信息)。
  如果你是零基礎的話(huà),推薦去csdn看看一個(gè)和你問(wèn)題有相似需求的人在使用什么框架和數據庫。web的話(huà),爬蟲(chóng)爬取評論數據用前端selenium。找相關(guān)的網(wǎng)站翻譯一下。如果可以看懂的話(huà)可以試著(zhù)寫(xiě)一個(gè)爬蟲(chóng)這樣。我目前是這么干的,具體不太懂。感覺(jué)時(shí)間比較緊,
  
  回答你的問(wèn)題首先要說(shuō)明的是,市面上比較多,國內的,國外的,mongodb等等很多,我只知道其中的一款,如果你想學(xué)習爬蟲(chóng)的話(huà),建議去學(xué)習一下,因為爬蟲(chóng)要對各種兼容性進(jìn)行分析,可能你需要寫(xiě)幾個(gè)框架,從最開(kāi)始的caffe到其他的,從此要自己寫(xiě)框架,初學(xué)的話(huà),這些框架你可以選擇一個(gè),其實(shí)安卓,ios都可以搭建自己的網(wǎng)站,反正不都是web嗎,所以你也可以去學(xué)習一下。
  并不是不會(huì ),是因為沒(méi)經(jīng)歷過(guò),作為初學(xué)者,建議還是先學(xué)一些框架,比如requests+xpath+beautifulsoup4(因為本人java基礎不是很好,所以選擇了前三個(gè),做練習可以選擇其他的)lxmlpyquery等等或者直接學(xué)一下flaskpyramid都可以。自己先去學(xué)一下其他的,然后了解一下api,通過(guò)各種api寫(xiě)一個(gè)網(wǎng)站,網(wǎng)站出來(lái)以后在選擇一個(gè)框架,這樣一來(lái),一切都會(huì )水到渠成。

c爬蟲(chóng)抓取網(wǎng)頁(yè)數據更新的步驟是什么?怎么做

網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 294 次瀏覽 ? 2022-06-29 07:02 ? 來(lái)自相關(guān)話(huà)題

  c爬蟲(chóng)抓取網(wǎng)頁(yè)數據更新的步驟是什么?怎么做
  c爬蟲(chóng)抓取網(wǎng)頁(yè)數據更新的步驟:1.首先是獲取目標網(wǎng)頁(yè)的數據的方法,即獲取這個(gè)網(wǎng)頁(yè)所需要的數據。2.再是打包成數據包,下載到本地。然后對下載下來(lái)的數據做分析計算。有了本地的數據包,才能通過(guò)腳本更新網(wǎng)頁(yè)。3.網(wǎng)頁(yè)的更新即是用人工手動(dòng)的方式取得網(wǎng)頁(yè)最新的數據。這個(gè)過(guò)程需要使用抓包工具。4.http請求的代碼以https格式寫(xiě)在代碼最后。5.有人會(huì )問(wèn),這個(gè)代碼在哪里?運行代碼的時(shí)候,會(huì )用到瀏覽器開(kāi)發(fā)者工具。
  做爬蟲(chóng)的時(shí)候經(jīng)常會(huì )用到一些爬蟲(chóng)工具,
  
  可以使用多線(xiàn)程抓取,
  我個(gè)人認為,
  有個(gè)叫說(shuō)手機app的那哥們,整天干這個(gè)。
  
  曾經(jīng)做過(guò)一段android全開(kāi)源爬蟲(chóng),可以爬lbs相關(guān),更新比較及時(shí),速度可以達到1000+,現在想想那是多年前的事了。
  如果只爬公開(kāi)數據(包括大數據),可以通過(guò)反爬蟲(chóng)機制。在androidapi409范圍之內,比如:大商家之間的投票、大的賽事、大型論壇。在recaptcha加密機制之內,拿到中間地址。然后:翻墻找數據。(外國網(wǎng)站監控比較牛逼)在上一條的基礎上,自己編寫(xiě)getheader或者cookie對爬蟲(chóng),這個(gè)可以crawl,不過(guò)有點(diǎn)坑。
  在自己程序中使用第三方爬蟲(chóng),會(huì )和代理廣告相關(guān),自己肯定清楚相關(guān)的東西?;蛘遖gentdetector來(lái)監控哪個(gè)瀏覽器加速。有實(shí)力做爬蟲(chóng)網(wǎng)站比如一些專(zhuān)門(mén)做分析數據爬蟲(chóng)之類(lèi)的東西,就是收費的東西,多爬一些數據吧。 查看全部

  c爬蟲(chóng)抓取網(wǎng)頁(yè)數據更新的步驟是什么?怎么做
  c爬蟲(chóng)抓取網(wǎng)頁(yè)數據更新的步驟:1.首先是獲取目標網(wǎng)頁(yè)的數據的方法,即獲取這個(gè)網(wǎng)頁(yè)所需要的數據。2.再是打包成數據包,下載到本地。然后對下載下來(lái)的數據做分析計算。有了本地的數據包,才能通過(guò)腳本更新網(wǎng)頁(yè)。3.網(wǎng)頁(yè)的更新即是用人工手動(dòng)的方式取得網(wǎng)頁(yè)最新的數據。這個(gè)過(guò)程需要使用抓包工具。4.http請求的代碼以https格式寫(xiě)在代碼最后。5.有人會(huì )問(wèn),這個(gè)代碼在哪里?運行代碼的時(shí)候,會(huì )用到瀏覽器開(kāi)發(fā)者工具。
  做爬蟲(chóng)的時(shí)候經(jīng)常會(huì )用到一些爬蟲(chóng)工具,
  
  可以使用多線(xiàn)程抓取,
  我個(gè)人認為,
  有個(gè)叫說(shuō)手機app的那哥們,整天干這個(gè)。
  
  曾經(jīng)做過(guò)一段android全開(kāi)源爬蟲(chóng),可以爬lbs相關(guān),更新比較及時(shí),速度可以達到1000+,現在想想那是多年前的事了。
  如果只爬公開(kāi)數據(包括大數據),可以通過(guò)反爬蟲(chóng)機制。在androidapi409范圍之內,比如:大商家之間的投票、大的賽事、大型論壇。在recaptcha加密機制之內,拿到中間地址。然后:翻墻找數據。(外國網(wǎng)站監控比較牛逼)在上一條的基礎上,自己編寫(xiě)getheader或者cookie對爬蟲(chóng),這個(gè)可以crawl,不過(guò)有點(diǎn)坑。
  在自己程序中使用第三方爬蟲(chóng),會(huì )和代理廣告相關(guān),自己肯定清楚相關(guān)的東西?;蛘遖gentdetector來(lái)監控哪個(gè)瀏覽器加速。有實(shí)力做爬蟲(chóng)網(wǎng)站比如一些專(zhuān)門(mén)做分析數據爬蟲(chóng)之類(lèi)的東西,就是收費的東西,多爬一些數據吧。

數據分析|爬蟲(chóng)抓取東方財富網(wǎng)股吧帖子

網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 86 次瀏覽 ? 2022-06-24 23:39 ? 來(lái)自相關(guān)話(huà)題

  數據分析|爬蟲(chóng)抓取東方財富網(wǎng)股吧帖子
  1前言
  量化交易策略的研究主要涵蓋了微觀(guān)和宏觀(guān)這兩個(gè)方面,微觀(guān)方面更多地是從市場(chǎng)價(jià)格和成交持倉這些基礎信息為研究對象,通過(guò)算法計算出技術(shù)指標,再從技術(shù)指標的變化上構建交易模型。宏觀(guān)方面則是基于更多的市場(chǎng)資訊開(kāi)發(fā)交易模型,比如從CPI、PPI、貨幣發(fā)行量這些宏觀(guān)經(jīng)濟指標為研究對象構建交易模型;或者是利用數據挖掘技術(shù)從新聞事件中挖掘出可能造成市場(chǎng)異常波動(dòng)的事件,從而獲得交易的時(shí)機。
  我們知道知名股票論壇有點(diǎn)金投資家園、股天下、東方財富網(wǎng)股吧、和訊股吧、創(chuàng )幻論壇、MACD股市等等,筆者用的比較多的是東方財富網(wǎng)股吧。在課程《構建基于股票的量化交易系統》中我們以爬取東方財富網(wǎng)行業(yè)板塊當日的行情數據為案例,介紹了網(wǎng)絡(luò )爬蟲(chóng)的原理和方法,本節我們再介紹下如何爬取東方財富網(wǎng)股吧帖子的內容。
  2
  解析股吧帖子URL
  首先通過(guò)瀏覽器訪(fǎng)問(wèn)偉星新材的股吧,查看該網(wǎng)頁(yè)的URL為:
  ,002372.html,網(wǎng)頁(yè)內容如下圖所示:
  當我們點(diǎn)擊第2頁(yè)、第3頁(yè)后,查看下當前的URL分別為:
  http://guba.eastmoney.com/list,002372_2.htmlhttp://guba.eastmoney.com/list,002372_3.html
  因此得到了個(gè)股股吧URL的規律為:
  , 002372_%d.html形式表示,
  其中的規律比較直白,%d為論壇第幾頁(yè),不過(guò)這個(gè)形式是按評論時(shí)間排列的網(wǎng)址,如果按發(fā)帖時(shí)間的排列網(wǎng)址是:
  ,002372,f_%d.html。
  股吧的帖子由兩部分組成,一部分為“財經(jīng)評論”或“東方財富網(wǎng)”發(fā)布的公告或官方消息,另一部分為散戶(hù)發(fā)布的討論帖子,如下圖所示:
  
  前者的帖子URL為:
  ,cjpl,902659513.html,
  后者的帖子URL為:
  ,002372,902629178.html
  兩者的URL都可在當前該股股吧HTML文件內容中搜尋到,如下所示:
  
  因此“財經(jīng)評論”、“東方財富網(wǎng)”或者散戶(hù)發(fā)布的帖子,主要的特征為/news,在實(shí)現上我們可以先爬取到股吧HTML內容,然后通過(guò)正則表達式來(lái)篩選得到帖子的URL。
  關(guān)于讀取網(wǎng)頁(yè)HTML內容的關(guān)鍵代碼我們已經(jīng)在課程《爬蟲(chóng)方式獲取行業(yè)板塊數據》一節中具體介紹過(guò)。需要注意的是Python2的urllib、urllib2和urlparse,已經(jīng)在Python3中全部被整合到了urllib中,其中Python2的urllib和urllib2中的內容整合為urllib.request模塊,urlparse整合為urllib.parse模塊。
  獲取到HTML代碼部分內容如下:
  正則表達式篩選帖子URL,采用了pile和re.findall,實(shí)現代碼如下:
  其中正則表達式的\S+表示匹配多次非空白字符,然后使用findall函數找到匹配的所有字符串,并把它們作為一個(gè)列表返回。
  然后是使用urljoin方法把整個(gè)url拼接好用于爬取單個(gè)帖子的標題內容,關(guān)鍵代碼如下所示:
  
  3創(chuàng )建爬蟲(chóng)URL隊列
  接下來(lái)我們把所有需要爬取的股吧頁(yè)以及每頁(yè)中的帖子的URL以隊列的方式進(jìn)行管理。Python中存儲序列的類(lèi)型有list、tuple、dict和set,它們之間的區別和特點(diǎn)簡(jiǎn)單的說(shuō):tuple不能修改其中的元素;set是無(wú)序集合,會(huì )自動(dòng)去除重復元素;list是有序的集合;dict是一組key和value的組合。此次我們選擇list作為隊列的存儲類(lèi)型。
  創(chuàng )建target_url_manager類(lèi),該類(lèi)包含以下幾個(gè)方法:
  創(chuàng )建隊列形式如下所示:
  完整代碼可見(jiàn)課程《加推篇!爬蟲(chóng)抓取東方財富網(wǎng)股吧帖子》。
  4
  解析股吧帖子內容
  單個(gè)帖子爬取的內容包括三部分,帖子發(fā)表時(shí)間、作者及帖子標題,如下所示:
  
  我們可以通過(guò)正則表達式進(jìn)行提取,其中在組合正則表達式時(shí),需要考慮到HTML代碼中是否有重復的匹配關(guān)鍵字。作者和帖子標題正則代碼如下,mainbody、zwcontentmain這些關(guān)鍵字在文本中僅出現一次,匹配程度較高。由于網(wǎng)站HTML代碼的改動(dòng),表達式需要經(jīng)常調整。
  關(guān)鍵代碼如下所示:
  com_cont = re.compile(r'.*?zwconttbn.*?(.*?).*?social clearfix',re.DOTALL)
  發(fā)布時(shí)間正則代碼如下,分兩步逐漸明晰的去提取時(shí)間,由于search是掃描字符串找到這個(gè)RE 匹配的位置,因此增加group()返回匹配字符串。
  pub_elems?=?re.search('.*?',html_cont2).group()#發(fā)表于 2020-02-11 09:54:48 東方財富Android版<br />pub_time?=?re.search('\d\d\d\d-\d\d-\d\d',pub_elems).group()#2020-02-06
  <br />
  另外,論壇帖子與當前的股價(jià)走勢有時(shí)間聯(lián)系,太早的帖子對現在無(wú)參考作用,因此需要刪選近期的帖子。我們可以對時(shí)間進(jìn)行判斷,只有一個(gè)月之內發(fā)布的帖子才進(jìn)行爬取并存儲。獲取今天的日期使用datetime.now().date(),然后與爬取的帖子時(shí)間日期比較,timedelta可在日期上做天days時(shí)間計算,但需要將時(shí)間轉換為時(shí)間形式。
  實(shí)現部分關(guān)鍵代碼如下所示:
  
  完成了單個(gè)帖子的內容爬取之后,我們采用迭代方法把全部帖子爬取一遍。我們通過(guò)兩層迭代方法,第一層為頁(yè)數,第二層為一頁(yè)的股吧帖子數,將每個(gè)帖子的URL存儲在列表中,通過(guò)迭代的方式一個(gè)個(gè)爬取帖子的內容。<br />
  實(shí)現部分關(guān)鍵代碼如下:
  
  當我們爬取時(shí)發(fā)現某個(gè)帖子不存在,出現爬取信息異常時(shí),可使用try...except...進(jìn)行異常處理。
  最終爬取到的帖子內容如下圖所示:
  完整代碼可見(jiàn)課程《加推篇!爬蟲(chóng)抓取東方財富網(wǎng)股吧帖子》。
  5
  帖子內容存儲為txt
  我們可以將爬取信息寫(xiě)到txt文件中,打開(kāi)方式的代碼實(shí)現如下所示,a+為在文本尾部追加寫(xiě)入,而不是覆蓋寫(xiě)入,codecs.open這個(gè)方法可以指定編碼打開(kāi)文件,而使用Python內置的open打開(kāi)文件只能寫(xiě)入str類(lèi)型。
  f=codecs.open(name,'a+','utf-8')
  此處我們創(chuàng )建一個(gè)output_txt類(lèi),該類(lèi)中我們會(huì )分別實(shí)現打開(kāi)文件、寫(xiě)文件和關(guān)閉文件這幾個(gè)方法。代碼如下所示:
  
  接下來(lái)就可以一邊爬取帖子內容,一邊把內容寫(xiě)入到txt文件中。實(shí)現關(guān)鍵代碼如下所示:
  
  寫(xiě)入txt文件的效果如下所示:
  
  我們也可以把爬取信息寫(xiě)到GUI工具中,我們知道在wxPython中文本框為wx.TextCtrl類(lèi),該類(lèi)可以顯示和編輯文本,這樣一來(lái)就可以把帖子信息寫(xiě)到GUI工具中。顯示效果如下所示:
  
  6
  總結
  本小節我們通過(guò)爬蟲(chóng)方式得到股吧帖子中的各種內容,那么這些內容對于我們來(lái)說(shuō)有什么意義嗎?我們發(fā)現總有些人一直在唱空,制造恐慌的情緒,不過(guò)我們可以通過(guò)分類(lèi)分析下這些空頭評論和股價(jià)的漲跌有沒(méi)有什么關(guān)聯(lián),是不是有寫(xiě)ID是專(zhuān)門(mén)來(lái)唱空的呢?感興趣的朋友們可以試試!比如用詞云這種方式,如下所示:
  
   查看全部

  數據分析|爬蟲(chóng)抓取東方財富網(wǎng)股吧帖子
  1前言
  量化交易策略的研究主要涵蓋了微觀(guān)和宏觀(guān)這兩個(gè)方面,微觀(guān)方面更多地是從市場(chǎng)價(jià)格和成交持倉這些基礎信息為研究對象,通過(guò)算法計算出技術(shù)指標,再從技術(shù)指標的變化上構建交易模型。宏觀(guān)方面則是基于更多的市場(chǎng)資訊開(kāi)發(fā)交易模型,比如從CPI、PPI、貨幣發(fā)行量這些宏觀(guān)經(jīng)濟指標為研究對象構建交易模型;或者是利用數據挖掘技術(shù)從新聞事件中挖掘出可能造成市場(chǎng)異常波動(dòng)的事件,從而獲得交易的時(shí)機。
  我們知道知名股票論壇有點(diǎn)金投資家園、股天下、東方財富網(wǎng)股吧、和訊股吧、創(chuàng )幻論壇、MACD股市等等,筆者用的比較多的是東方財富網(wǎng)股吧。在課程《構建基于股票的量化交易系統》中我們以爬取東方財富網(wǎng)行業(yè)板塊當日的行情數據為案例,介紹了網(wǎng)絡(luò )爬蟲(chóng)的原理和方法,本節我們再介紹下如何爬取東方財富網(wǎng)股吧帖子的內容。
  2
  解析股吧帖子URL
  首先通過(guò)瀏覽器訪(fǎng)問(wèn)偉星新材的股吧,查看該網(wǎng)頁(yè)的URL為:
  ,002372.html,網(wǎng)頁(yè)內容如下圖所示:
  當我們點(diǎn)擊第2頁(yè)、第3頁(yè)后,查看下當前的URL分別為:
  http://guba.eastmoney.com/list,002372_2.htmlhttp://guba.eastmoney.com/list,002372_3.html
  因此得到了個(gè)股股吧URL的規律為:
  , 002372_%d.html形式表示,
  其中的規律比較直白,%d為論壇第幾頁(yè),不過(guò)這個(gè)形式是按評論時(shí)間排列的網(wǎng)址,如果按發(fā)帖時(shí)間的排列網(wǎng)址是:
  ,002372,f_%d.html。
  股吧的帖子由兩部分組成,一部分為“財經(jīng)評論”或“東方財富網(wǎng)”發(fā)布的公告或官方消息,另一部分為散戶(hù)發(fā)布的討論帖子,如下圖所示:
  
  前者的帖子URL為:
  ,cjpl,902659513.html,
  后者的帖子URL為:
  ,002372,902629178.html
  兩者的URL都可在當前該股股吧HTML文件內容中搜尋到,如下所示:
  
  因此“財經(jīng)評論”、“東方財富網(wǎng)”或者散戶(hù)發(fā)布的帖子,主要的特征為/news,在實(shí)現上我們可以先爬取到股吧HTML內容,然后通過(guò)正則表達式來(lái)篩選得到帖子的URL。
  關(guān)于讀取網(wǎng)頁(yè)HTML內容的關(guān)鍵代碼我們已經(jīng)在課程《爬蟲(chóng)方式獲取行業(yè)板塊數據》一節中具體介紹過(guò)。需要注意的是Python2的urllib、urllib2和urlparse,已經(jīng)在Python3中全部被整合到了urllib中,其中Python2的urllib和urllib2中的內容整合為urllib.request模塊,urlparse整合為urllib.parse模塊。
  獲取到HTML代碼部分內容如下:
  正則表達式篩選帖子URL,采用了pile和re.findall,實(shí)現代碼如下:
  其中正則表達式的\S+表示匹配多次非空白字符,然后使用findall函數找到匹配的所有字符串,并把它們作為一個(gè)列表返回。
  然后是使用urljoin方法把整個(gè)url拼接好用于爬取單個(gè)帖子的標題內容,關(guān)鍵代碼如下所示:
  
  3創(chuàng )建爬蟲(chóng)URL隊列
  接下來(lái)我們把所有需要爬取的股吧頁(yè)以及每頁(yè)中的帖子的URL以隊列的方式進(jìn)行管理。Python中存儲序列的類(lèi)型有list、tuple、dict和set,它們之間的區別和特點(diǎn)簡(jiǎn)單的說(shuō):tuple不能修改其中的元素;set是無(wú)序集合,會(huì )自動(dòng)去除重復元素;list是有序的集合;dict是一組key和value的組合。此次我們選擇list作為隊列的存儲類(lèi)型。
  創(chuàng )建target_url_manager類(lèi),該類(lèi)包含以下幾個(gè)方法:
  創(chuàng )建隊列形式如下所示:
  完整代碼可見(jiàn)課程《加推篇!爬蟲(chóng)抓取東方財富網(wǎng)股吧帖子》。
  4
  解析股吧帖子內容
  單個(gè)帖子爬取的內容包括三部分,帖子發(fā)表時(shí)間、作者及帖子標題,如下所示:
  
  我們可以通過(guò)正則表達式進(jìn)行提取,其中在組合正則表達式時(shí),需要考慮到HTML代碼中是否有重復的匹配關(guān)鍵字。作者和帖子標題正則代碼如下,mainbody、zwcontentmain這些關(guān)鍵字在文本中僅出現一次,匹配程度較高。由于網(wǎng)站HTML代碼的改動(dòng),表達式需要經(jīng)常調整。
  關(guān)鍵代碼如下所示:
  com_cont = re.compile(r'.*?zwconttbn.*?(.*?).*?social clearfix',re.DOTALL)
  發(fā)布時(shí)間正則代碼如下,分兩步逐漸明晰的去提取時(shí)間,由于search是掃描字符串找到這個(gè)RE 匹配的位置,因此增加group()返回匹配字符串。
  pub_elems?=?re.search('.*?',html_cont2).group()#發(fā)表于 2020-02-11 09:54:48 東方財富Android版<br />pub_time?=?re.search('\d\d\d\d-\d\d-\d\d',pub_elems).group()#2020-02-06
  <br />
  另外,論壇帖子與當前的股價(jià)走勢有時(shí)間聯(lián)系,太早的帖子對現在無(wú)參考作用,因此需要刪選近期的帖子。我們可以對時(shí)間進(jìn)行判斷,只有一個(gè)月之內發(fā)布的帖子才進(jìn)行爬取并存儲。獲取今天的日期使用datetime.now().date(),然后與爬取的帖子時(shí)間日期比較,timedelta可在日期上做天days時(shí)間計算,但需要將時(shí)間轉換為時(shí)間形式。
  實(shí)現部分關(guān)鍵代碼如下所示:
  
  完成了單個(gè)帖子的內容爬取之后,我們采用迭代方法把全部帖子爬取一遍。我們通過(guò)兩層迭代方法,第一層為頁(yè)數,第二層為一頁(yè)的股吧帖子數,將每個(gè)帖子的URL存儲在列表中,通過(guò)迭代的方式一個(gè)個(gè)爬取帖子的內容。<br />
  實(shí)現部分關(guān)鍵代碼如下:
  
  當我們爬取時(shí)發(fā)現某個(gè)帖子不存在,出現爬取信息異常時(shí),可使用try...except...進(jìn)行異常處理。
  最終爬取到的帖子內容如下圖所示:
  完整代碼可見(jiàn)課程《加推篇!爬蟲(chóng)抓取東方財富網(wǎng)股吧帖子》。
  5
  帖子內容存儲為txt
  我們可以將爬取信息寫(xiě)到txt文件中,打開(kāi)方式的代碼實(shí)現如下所示,a+為在文本尾部追加寫(xiě)入,而不是覆蓋寫(xiě)入,codecs.open這個(gè)方法可以指定編碼打開(kāi)文件,而使用Python內置的open打開(kāi)文件只能寫(xiě)入str類(lèi)型。
  f=codecs.open(name,'a+','utf-8')
  此處我們創(chuàng )建一個(gè)output_txt類(lèi),該類(lèi)中我們會(huì )分別實(shí)現打開(kāi)文件、寫(xiě)文件和關(guān)閉文件這幾個(gè)方法。代碼如下所示:
  
  接下來(lái)就可以一邊爬取帖子內容,一邊把內容寫(xiě)入到txt文件中。實(shí)現關(guān)鍵代碼如下所示:
  
  寫(xiě)入txt文件的效果如下所示:
  
  我們也可以把爬取信息寫(xiě)到GUI工具中,我們知道在wxPython中文本框為wx.TextCtrl類(lèi),該類(lèi)可以顯示和編輯文本,這樣一來(lái)就可以把帖子信息寫(xiě)到GUI工具中。顯示效果如下所示:
  
  6
  總結
  本小節我們通過(guò)爬蟲(chóng)方式得到股吧帖子中的各種內容,那么這些內容對于我們來(lái)說(shuō)有什么意義嗎?我們發(fā)現總有些人一直在唱空,制造恐慌的情緒,不過(guò)我們可以通過(guò)分類(lèi)分析下這些空頭評論和股價(jià)的漲跌有沒(méi)有什么關(guān)聯(lián),是不是有寫(xiě)ID是專(zhuān)門(mén)來(lái)唱空的呢?感興趣的朋友們可以試試!比如用詞云這種方式,如下所示:
  
  

數據抓取學(xué)習3|web scraper爬蟲(chóng)使用方法—進(jìn)階篇

網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 788 次瀏覽 ? 2022-06-20 04:44 ? 來(lái)自相關(guān)話(huà)題

  數據抓取學(xué)習3|web scraper爬蟲(chóng)使用方法—進(jìn)階篇
  上一篇文章講了web scraper的基礎操作,今天跟大家分享web scraper爬蟲(chóng)的一些進(jìn)階使用方法,學(xué)會(huì )了它,大概80%的網(wǎng)站元素都可以抓取了。
  它的步驟都是:
  創(chuàng )建一個(gè)站點(diǎn)Create sitemap—新增選擇器Add new selector—點(diǎn)擊Scrape抓取,不同的是選擇器中Type的選擇。
  在進(jìn)階篇中,主要講的就是這幾個(gè)Type的使用。
  
  目錄
  頁(yè)內提取多個(gè)字段Type=Element
  選擇樹(shù)Selector graph
  選擇快捷鍵Enable key
  不規則分頁(yè)Type=Element scroll down/Element click
  二三級頁(yè)面元素采集Type=Type=Link
  抓取表單Type=Table
  Delay的設置
  1.頁(yè)內提取多個(gè)字段(Type=Element)
  
  如上圖,如果想要同時(shí)抓取這個(gè)回答中的標題、點(diǎn)贊人數、回答的正文,就要用到Element這個(gè)選擇器,它表示的是元素集,各個(gè)元素組成的一個(gè)元素集。比如上圖中的回答中的標題、點(diǎn)贊人數、回答的正文、評論數就在一個(gè)元素集里。
  具體的操作步驟如下:
  新建一個(gè)站點(diǎn)地圖Create sitemap—新建選擇器Add new selector—新建子選擇器—抓取
  
  點(diǎn)擊Select選取元素,這個(gè)是元素集,所以選擇時(shí)要把整個(gè)元素集都框選中。具體步驟如下圖,在基礎篇中講過(guò),在選擇時(shí)如果是type(1),說(shuō)明這個(gè)頁(yè)面的元素沒(méi)有選完,這里再選擇下一個(gè)元素集就可以了。
  
  在新建選擇器時(shí)選擇Element這個(gè)選擇器,勾選Multiple。
  建好之后,點(diǎn)擊這個(gè)選擇器,進(jìn)入到選擇子器頁(yè)面,然后再新建子選擇器,選擇需要抓取的頁(yè)面元素。比如:標題、正文、點(diǎn)贊數、評論數。
  
  
  子元素:標題、正文、點(diǎn)贊數、評論數這些都是文本,Type選擇Text就可以了。
  2.選擇樹(shù)Selector graph
  在Sitemap的下拉菜單中有一個(gè)Selector graph的選擇,通過(guò)它可以查看選擇器之間的邏輯關(guān)系。
  
  這個(gè)例子中元素集與元素之間的關(guān)系。
  
  3.選擇快捷鍵(Enable key)
  用鼠標選擇頁(yè)面元素,有時(shí)候會(huì )出現選擇錯誤或者是一點(diǎn)擊就跳到的另外一個(gè)頁(yè)面,這時(shí)候可以利用Enable key這個(gè)快捷操作去選取元素。
  勾選Enable key ,把鼠標懸停在你要選擇的元素上,待采集字段變綠后點(diǎn)擊鍵盤(pán)S鍵選擇。
  4.不規則分頁(yè)Type=Element scroll down/Element click
  像下圖中這種,需要鼠標向下滾動(dòng)和點(diǎn)擊“加載更多”,網(wǎng)頁(yè)才會(huì )加載出新的內容。
  這類(lèi)網(wǎng)站的元素,可以分別利用選擇器Type中的Element scroll down和Element click來(lái)進(jìn)行抓取。
  
  下面這個(gè)實(shí)例:收集IT桔子中金融類(lèi)公司的公司名,公司簡(jiǎn)介。
  這里需要鼠標點(diǎn)擊“加載更多”才會(huì )出現新的內容。
  新建一個(gè)站點(diǎn)地圖后,新增選擇器,在Type中選擇Element click,點(diǎn)擊Selector中的Select,選擇元素集。
  在Click selector點(diǎn)擊Select,選擇“加載更多”。
  Click type 中選擇Click more,因為這條類(lèi)目?jì)热莺芏?,需要點(diǎn)擊多次的“加載更多”,如果需要點(diǎn)擊一次的話(huà),選擇Click once就可以。
  Click element uniquenss選擇unique CSS Selector。
  勾選Multiple,注意在子選擇器中就不用勾選。
  這里加載可能會(huì )出現一點(diǎn)延時(shí),所以可以加一個(gè)1000ms的延時(shí)。
  
  然后再分別建立公司標題和公司簡(jiǎn)介的子選擇器,進(jìn)行抓取即可。
  
  5.二三級頁(yè)面元素采集Type=Link
  還是知乎的例子,如果還想要收集這個(gè)問(wèn)題的關(guān)注人數和瀏覽量,但這兩個(gè)數據在另外一個(gè)頁(yè)面,這里就需要用到選擇器中Type=Link的選項,它表示的是指向這個(gè)文本背后的鏈接。
  
  具體的操作步驟如下:
  在元素集的子選擇器中新建一個(gè)link的子選擇器。
  
  Type選擇Link,選中標題,這里會(huì )看到出現標題的鏈接。
  在link的下面再新建兩個(gè)選擇器,分別抓取關(guān)注和瀏覽量的數據。
  
  看下這個(gè)抓取的邏輯樹(shù),理解就更清晰了:
  
  6.抓取表單Type=Table
  利用Type=Table
  以抓取優(yōu)采云票余票信息為例子。
  網(wǎng)址鏈接:
  在選擇器中選擇Type=Table,Selector選擇整個(gè)表格。
  Header row selector,選擇表頭,這例子中選擇數據第一行為表頭,再修改表頭的名字,如果選擇第一行為表頭的話(huà),只能抓取出發(fā)地、目的地、余票數量三個(gè)元素,詳細的每日余票量抓取不了。
  修改表頭的標注
  Data rows selector中選擇所以抓取的數據項。
  7.Delay的設置
  在操作過(guò)程中,但選擇器多了之后,大家會(huì )看到很多Delay的設置,下面說(shuō)說(shuō)需要設置Delay的情況。
  點(diǎn)擊Scrape后,這里的Delay,它針對的是全局,所有鏈接發(fā)生變化的情況。
  
  點(diǎn)擊分頁(yè)、加載更多、滾動(dòng)下拉這類(lèi)頁(yè)面需要時(shí)間加載是,就設置delay,推薦2000ms。
  元素集中的子選擇器可以不設置delay。
  小結
  講解了web scraper的進(jìn)階操作后,是不是發(fā)現又有很多網(wǎng)站數據可以抓取了。
  進(jìn)階篇中主要的知識點(diǎn)有:
  1.根據抓取元素的不同情況,選擇不同的Type
  
  2.選擇樹(shù)Selector graph
  選擇器之間的邏輯關(guān)系。
  3.選擇快捷鍵Enable key
  4.Delay的設置
  頁(yè)面需要時(shí)間加載的情況設置Delay,元素集中的子選擇器可以不設 置。
  5.子選擇器中的Multiple不用勾選
  6.常見(jiàn)的問(wèn)題
  操作過(guò)程中會(huì )需要兩個(gè)常見(jiàn)問(wèn)題:
  思考題
  
  在知乎例子的這個(gè)抓取結果中,回答正文中,沒(méi)有把回答的全文抓取完。在網(wǎng)站上“閱讀全文”這四個(gè)字需要用鼠標點(diǎn)開(kāi),爬蟲(chóng)才能把全部回答抓取完,怎么設置這個(gè)選擇器呢?
  大家可以先思考,嘗試自己操作一下。
  公眾號回復“答案”,就可獲取具體的操作步驟。
  注:我學(xué)習課程為三節課的《人人都能學(xué)會(huì )的數據爬蟲(chóng)課》,此次僅為純粹的學(xué)習分享。
  搬運工的苦勞
  蘋(píng)果專(zhuān)用贊賞二維碼 查看全部

  數據抓取學(xué)習3|web scraper爬蟲(chóng)使用方法—進(jìn)階篇
  上一篇文章講了web scraper的基礎操作,今天跟大家分享web scraper爬蟲(chóng)的一些進(jìn)階使用方法,學(xué)會(huì )了它,大概80%的網(wǎng)站元素都可以抓取了。
  它的步驟都是:
  創(chuàng )建一個(gè)站點(diǎn)Create sitemap—新增選擇器Add new selector—點(diǎn)擊Scrape抓取,不同的是選擇器中Type的選擇。
  在進(jìn)階篇中,主要講的就是這幾個(gè)Type的使用。
  
  目錄
  頁(yè)內提取多個(gè)字段Type=Element
  選擇樹(shù)Selector graph
  選擇快捷鍵Enable key
  不規則分頁(yè)Type=Element scroll down/Element click
  二三級頁(yè)面元素采集Type=Type=Link
  抓取表單Type=Table
  Delay的設置
  1.頁(yè)內提取多個(gè)字段(Type=Element)
  
  如上圖,如果想要同時(shí)抓取這個(gè)回答中的標題、點(diǎn)贊人數、回答的正文,就要用到Element這個(gè)選擇器,它表示的是元素集,各個(gè)元素組成的一個(gè)元素集。比如上圖中的回答中的標題、點(diǎn)贊人數、回答的正文、評論數就在一個(gè)元素集里。
  具體的操作步驟如下:
  新建一個(gè)站點(diǎn)地圖Create sitemap—新建選擇器Add new selector—新建子選擇器—抓取
  
  點(diǎn)擊Select選取元素,這個(gè)是元素集,所以選擇時(shí)要把整個(gè)元素集都框選中。具體步驟如下圖,在基礎篇中講過(guò),在選擇時(shí)如果是type(1),說(shuō)明這個(gè)頁(yè)面的元素沒(méi)有選完,這里再選擇下一個(gè)元素集就可以了。
  
  在新建選擇器時(shí)選擇Element這個(gè)選擇器,勾選Multiple。
  建好之后,點(diǎn)擊這個(gè)選擇器,進(jìn)入到選擇子器頁(yè)面,然后再新建子選擇器,選擇需要抓取的頁(yè)面元素。比如:標題、正文、點(diǎn)贊數、評論數。
  
  
  子元素:標題、正文、點(diǎn)贊數、評論數這些都是文本,Type選擇Text就可以了。
  2.選擇樹(shù)Selector graph
  在Sitemap的下拉菜單中有一個(gè)Selector graph的選擇,通過(guò)它可以查看選擇器之間的邏輯關(guān)系。
  
  這個(gè)例子中元素集與元素之間的關(guān)系。
  
  3.選擇快捷鍵(Enable key)
  用鼠標選擇頁(yè)面元素,有時(shí)候會(huì )出現選擇錯誤或者是一點(diǎn)擊就跳到的另外一個(gè)頁(yè)面,這時(shí)候可以利用Enable key這個(gè)快捷操作去選取元素。
  勾選Enable key ,把鼠標懸停在你要選擇的元素上,待采集字段變綠后點(diǎn)擊鍵盤(pán)S鍵選擇。
  4.不規則分頁(yè)Type=Element scroll down/Element click
  像下圖中這種,需要鼠標向下滾動(dòng)和點(diǎn)擊“加載更多”,網(wǎng)頁(yè)才會(huì )加載出新的內容。
  這類(lèi)網(wǎng)站的元素,可以分別利用選擇器Type中的Element scroll down和Element click來(lái)進(jìn)行抓取。
  
  下面這個(gè)實(shí)例:收集IT桔子中金融類(lèi)公司的公司名,公司簡(jiǎn)介。
  這里需要鼠標點(diǎn)擊“加載更多”才會(huì )出現新的內容。
  新建一個(gè)站點(diǎn)地圖后,新增選擇器,在Type中選擇Element click,點(diǎn)擊Selector中的Select,選擇元素集。
  在Click selector點(diǎn)擊Select,選擇“加載更多”。
  Click type 中選擇Click more,因為這條類(lèi)目?jì)热莺芏?,需要點(diǎn)擊多次的“加載更多”,如果需要點(diǎn)擊一次的話(huà),選擇Click once就可以。
  Click element uniquenss選擇unique CSS Selector。
  勾選Multiple,注意在子選擇器中就不用勾選。
  這里加載可能會(huì )出現一點(diǎn)延時(shí),所以可以加一個(gè)1000ms的延時(shí)。
  
  然后再分別建立公司標題和公司簡(jiǎn)介的子選擇器,進(jìn)行抓取即可。
  
  5.二三級頁(yè)面元素采集Type=Link
  還是知乎的例子,如果還想要收集這個(gè)問(wèn)題的關(guān)注人數和瀏覽量,但這兩個(gè)數據在另外一個(gè)頁(yè)面,這里就需要用到選擇器中Type=Link的選項,它表示的是指向這個(gè)文本背后的鏈接。
  
  具體的操作步驟如下:
  在元素集的子選擇器中新建一個(gè)link的子選擇器。
  
  Type選擇Link,選中標題,這里會(huì )看到出現標題的鏈接。
  在link的下面再新建兩個(gè)選擇器,分別抓取關(guān)注和瀏覽量的數據。
  
  看下這個(gè)抓取的邏輯樹(shù),理解就更清晰了:
  
  6.抓取表單Type=Table
  利用Type=Table
  以抓取優(yōu)采云票余票信息為例子。
  網(wǎng)址鏈接:
  在選擇器中選擇Type=Table,Selector選擇整個(gè)表格。
  Header row selector,選擇表頭,這例子中選擇數據第一行為表頭,再修改表頭的名字,如果選擇第一行為表頭的話(huà),只能抓取出發(fā)地、目的地、余票數量三個(gè)元素,詳細的每日余票量抓取不了。
  修改表頭的標注
  Data rows selector中選擇所以抓取的數據項。
  7.Delay的設置
  在操作過(guò)程中,但選擇器多了之后,大家會(huì )看到很多Delay的設置,下面說(shuō)說(shuō)需要設置Delay的情況。
  點(diǎn)擊Scrape后,這里的Delay,它針對的是全局,所有鏈接發(fā)生變化的情況。
  
  點(diǎn)擊分頁(yè)、加載更多、滾動(dòng)下拉這類(lèi)頁(yè)面需要時(shí)間加載是,就設置delay,推薦2000ms。
  元素集中的子選擇器可以不設置delay。
  小結
  講解了web scraper的進(jìn)階操作后,是不是發(fā)現又有很多網(wǎng)站數據可以抓取了。
  進(jìn)階篇中主要的知識點(diǎn)有:
  1.根據抓取元素的不同情況,選擇不同的Type
  
  2.選擇樹(shù)Selector graph
  選擇器之間的邏輯關(guān)系。
  3.選擇快捷鍵Enable key
  4.Delay的設置
  頁(yè)面需要時(shí)間加載的情況設置Delay,元素集中的子選擇器可以不設 置。
  5.子選擇器中的Multiple不用勾選
  6.常見(jiàn)的問(wèn)題
  操作過(guò)程中會(huì )需要兩個(gè)常見(jiàn)問(wèn)題:
  思考題
  
  在知乎例子的這個(gè)抓取結果中,回答正文中,沒(méi)有把回答的全文抓取完。在網(wǎng)站上“閱讀全文”這四個(gè)字需要用鼠標點(diǎn)開(kāi),爬蟲(chóng)才能把全部回答抓取完,怎么設置這個(gè)選擇器呢?
  大家可以先思考,嘗試自己操作一下。
  公眾號回復“答案”,就可獲取具體的操作步驟。
  注:我學(xué)習課程為三節課的《人人都能學(xué)會(huì )的數據爬蟲(chóng)課》,此次僅為純粹的學(xué)習分享。
  搬運工的苦勞
  蘋(píng)果專(zhuān)用贊賞二維碼

Python爬蟲(chóng)之三:抓取貓眼電影TOP100

網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 112 次瀏覽 ? 2022-06-18 02:42 ? 來(lái)自相關(guān)話(huà)題

  Python爬蟲(chóng)之三:抓取貓眼電影TOP100
  今天我要利用requests庫和正則表達式抓取貓眼電影Top100榜單。
  運行平臺:Windows
  Python版本:Python3.6
  IDE:Sublime Text
  其他工具:Chrome瀏覽器
  1. 抓取單頁(yè)內容
  瀏覽器打開(kāi)貓眼電影首頁(yè),點(diǎn)擊“榜單”,然后再點(diǎn)擊"TOP100榜",就能看到想要的了。
  接下來(lái)通過(guò)代碼來(lái)獲取網(wǎng)頁(yè)的HTML代碼。
  運行結果如下:
  2. 正則表達式提取有用信息
  在上圖中,已經(jīng)標注出我們將要提取的內容,下面用代碼實(shí)現:
  運行結果如下:
  3. 保存信息
  獲取電影信息之后,要保存起來(lái)留用。要保存的有文本信息和電影封面。
  下面為保存結果:
  
  4.下載TOP100所有電影信息
  通過(guò)點(diǎn)擊標簽頁(yè)發(fā)現只是URL變化了:
  修改main函數以動(dòng)態(tài)改變URL:
  到此我們已經(jīng)將TOP100的電影信息和封面全部得到了。
  5.多線(xiàn)程抓取
  此次抓取的數據不算多,但是為了學(xué)習,使用多進(jìn)程進(jìn)行抓取,以應對以后大量的數據抓取。
  
  下面為普通抓取和多進(jìn)程抓取的時(shí)間對比:
  以下為完整代碼: 查看全部

  Python爬蟲(chóng)之三:抓取貓眼電影TOP100
  今天我要利用requests庫和正則表達式抓取貓眼電影Top100榜單。
  運行平臺:Windows
  Python版本:Python3.6
  IDE:Sublime Text
  其他工具:Chrome瀏覽器
  1. 抓取單頁(yè)內容
  瀏覽器打開(kāi)貓眼電影首頁(yè),點(diǎn)擊“榜單”,然后再點(diǎn)擊"TOP100榜",就能看到想要的了。
  接下來(lái)通過(guò)代碼來(lái)獲取網(wǎng)頁(yè)的HTML代碼。
  運行結果如下:
  2. 正則表達式提取有用信息
  在上圖中,已經(jīng)標注出我們將要提取的內容,下面用代碼實(shí)現:
  運行結果如下:
  3. 保存信息
  獲取電影信息之后,要保存起來(lái)留用。要保存的有文本信息和電影封面。
  下面為保存結果:
  
  4.下載TOP100所有電影信息
  通過(guò)點(diǎn)擊標簽頁(yè)發(fā)現只是URL變化了:
  修改main函數以動(dòng)態(tài)改變URL:
  到此我們已經(jīng)將TOP100的電影信息和封面全部得到了。
  5.多線(xiàn)程抓取
  此次抓取的數據不算多,但是為了學(xué)習,使用多進(jìn)程進(jìn)行抓取,以應對以后大量的數據抓取。
  
  下面為普通抓取和多進(jìn)程抓取的時(shí)間對比:
  以下為完整代碼:

高性能異步并發(fā)爬蟲(chóng)!- colly 自動(dòng)抓取資訊

網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 226 次瀏覽 ? 2022-06-12 08:31 ? 來(lái)自相關(guān)話(huà)題

  高性能異步并發(fā)爬蟲(chóng)!- colly 自動(dòng)抓取資訊
  colly 在 golang 中的地位,比之 scrapy 在 python 的作用,都是爬蟲(chóng)界的大佬。本文用其抓取博文資訊,從收集器實(shí)例配置,goQuery 進(jìn)行 dom 節點(diǎn)數據抓取,自動(dòng)分頁(yè)訪(fǎng)問(wèn),到 csv 數據持久化,json 控制臺輸出,全程簡(jiǎn)單直觀(guān)。
  
  Code
  抓取數據入口為社區某用戶(hù)博客列表頁(yè),比如
  package main<br /><br />import (<br /> "encoding/csv"<br /> "encoding/json"<br /> "log"<br /> "os"<br /> "regexp"<br /> "strconv"<br /> "strings"<br /><br /> "github.com/gocolly/colly"<br />)<br /><br />// Article 抓取blog數據<br />type Article struct {<br /> ID int `json:"id,omitempty"`<br /> Title string `json:"title,omitempty"`<br /> URL string `json:"url,omitempty"`<br /> Created string `json:"created,omitempty"`<br /> Reads string `json:"reads,omitempty"`<br /> Comments string `json:"comments,omitempty"`<br /> Feeds string `json:"feeds,omitempty"`<br />}<br /><br />// 數據持久化<br />func csvSave(fName string, data []Article) error {<br /> file, err := os.Create(fName)<br /> if err != nil {<br /> log.Fatalf("Cannot create file %q: %s\n", fName, err)<br /> }<br /> defer file.Close()<br /> writer := csv.NewWriter(file)<br /> defer writer.Flush()<br /><br /> writer.Write([]string{"ID", "Title", "URL", "Created", "Reads", "Comments", "Feeds"})<br /> for _, v := range data {<br /> writer.Write([]string{strconv.Itoa(v.ID), v.Title, v.URL, v.Created, v.Reads, v.Comments, v.Feeds})<br /> }<br /> return nil<br />}<br /><br />func main() {<br /> articles := make([]Article, 0, 200)<br /> // 1.準備收集器實(shí)例<br /> c := colly.NewCollector(<br /> // 開(kāi)啟本機debug<br /> // colly.Debugger(&debug.LogDebugger{}),<br /> colly.AllowedDomains("learnku.com"),<br /> // 防止頁(yè)面重復下載<br /> // colly.CacheDir("./learnku_cache"),<br /> )<br /><br /> // 2.分析頁(yè)面數據<br /> c.OnHTML("div.blog-article-list > .event", func(e *colly.HTMLElement) {<br /> article := Article{<br /> Title: e.ChildText("div.content > div.summary"),<br /> URL: e.ChildAttr("div.content a.title", "href"),<br /> Feeds: e.ChildText("div.item-meta > a:first-child"),<br /> }<br /> // 查找同一集合不同子項<br /> e.ForEach("div.content > div.meta > div.date>a", func(i int, el *colly.HTMLElement) {<br /> switch i {<br /> case 1:<br /> article.Created = el.Attr("data-tooltip")<br /> case 2:<br /> // 用空白切割字符串<br /> article.Reads = strings.Fields(el.Text)[1]<br /> case 3:<br /> article.Comments = strings.Fields(el.Text)[1]<br /> }<br /> })<br /> // 正則匹配替換,字符串轉整型<br /> article.ID, _ = strconv.Atoi(regexp.MustCompile(`\d+`).FindAllString(article.URL, -1)[0])<br /> articles = append(articles, article)<br /> })<br /><br /> // 下一頁(yè)<br /> c.OnHTML("a[href].page-link", func(e *colly.HTMLElement) {<br /> e.Request.Visit(e.Attr("href"))<br /> })<br /><br /> // 啟動(dòng)<br /> c.Visit("https://learnku.com/blog/pardon")<br /><br /> // 輸出<br /> csvSave("pardon.csv", articles)<br /> enc := json.NewEncoder(os.Stdout)<br /> enc.SetIndent("", " ")<br /> enc.Encode(articles)<br /><br /> // 顯示收集器的打印信息<br /> log.Println(c)<br />}<br />
  Output
  控制臺輸出
  ....<br /> "id": 30604,<br /> "title": "教程: TodoMVC 與 director 路由",<br /> "url": "https://learnku.com/articles/30604",<br /> "created": "2019-07-01 12:42:01",<br /> "reads": "650",<br /> "comments": "0",<br /> "feeds": "0"<br /> },<br /> {<br /> "id": 30579,<br /> "title": "flaskr 進(jìn)階筆記",<br /> "url": "https://learnku.com/articles/30579",<br /> "created": "2019-06-30 19:01:04",<br /> "reads": "895",<br /> "comments": "0",<br /> "feeds": "0"<br /> },<br /> {<br /> "id": 30542,<br /> "title": "教程 Redis+ flask+vue 在線(xiàn)聊天",<br /> "url": "https://learnku.com/articles/30542",<br /> "created": "2019-06-29 12:19:45",<br /> "reads": "2760",<br /> "comments": "1",<br /> "feeds": "2"<br /> }<br />]<br />2019/12/20 15:50:14 Requests made: 5 (5 responses) | Callbacks: OnRequest: 0, OnHTML: 2, OnResponse: 0, OnError: 0
  csv 文本輸出
  ID,Title,URL,Created,Reads,Comments,Feeds<br />37991,ferret 爬取動(dòng)態(tài)網(wǎng)頁(yè),https://learnku.com/articles/37991,2019-12-15 10:43:03,219,0,3<br />37803,匿名類(lèi) 與 索引重建,https://learnku.com/articles/37803,2019-12-09 19:35:09,323,1,0<br />37476,大話(huà)并發(fā),https://learnku.com/articles/37476,2019-12-08 21:17:55,612,0,4<br />37738,三元運算符,https://learnku.com/articles/37738,2019-12-08 09:44:36,606,0,0<br />37719,筆試之 模板變量替換,https://learnku.com/articles/37719,2019-12-07 18:30:42,843,0,0<br />37707,筆試之 連續數增維,https://learnku.com/articles/37707,2019-12-07 13:50:17,872,0,0<br />37616,筆試之 一行代碼求重,https://learnku.com/articles/37616,2019-12-05 12:10:24,792,0,0<br />....
  Colly 查看全部

  高性能異步并發(fā)爬蟲(chóng)!- colly 自動(dòng)抓取資訊
  colly 在 golang 中的地位,比之 scrapy 在 python 的作用,都是爬蟲(chóng)界的大佬。本文用其抓取博文資訊,從收集器實(shí)例配置,goQuery 進(jìn)行 dom 節點(diǎn)數據抓取,自動(dòng)分頁(yè)訪(fǎng)問(wèn),到 csv 數據持久化,json 控制臺輸出,全程簡(jiǎn)單直觀(guān)。
  
  Code
  抓取數據入口為社區某用戶(hù)博客列表頁(yè),比如
  package main<br /><br />import (<br /> "encoding/csv"<br /> "encoding/json"<br /> "log"<br /> "os"<br /> "regexp"<br /> "strconv"<br /> "strings"<br /><br /> "github.com/gocolly/colly"<br />)<br /><br />// Article 抓取blog數據<br />type Article struct {<br /> ID int `json:"id,omitempty"`<br /> Title string `json:"title,omitempty"`<br /> URL string `json:"url,omitempty"`<br /> Created string `json:"created,omitempty"`<br /> Reads string `json:"reads,omitempty"`<br /> Comments string `json:"comments,omitempty"`<br /> Feeds string `json:"feeds,omitempty"`<br />}<br /><br />// 數據持久化<br />func csvSave(fName string, data []Article) error {<br /> file, err := os.Create(fName)<br /> if err != nil {<br /> log.Fatalf("Cannot create file %q: %s\n", fName, err)<br /> }<br /> defer file.Close()<br /> writer := csv.NewWriter(file)<br /> defer writer.Flush()<br /><br /> writer.Write([]string{"ID", "Title", "URL", "Created", "Reads", "Comments", "Feeds"})<br /> for _, v := range data {<br /> writer.Write([]string{strconv.Itoa(v.ID), v.Title, v.URL, v.Created, v.Reads, v.Comments, v.Feeds})<br /> }<br /> return nil<br />}<br /><br />func main() {<br /> articles := make([]Article, 0, 200)<br /> // 1.準備收集器實(shí)例<br /> c := colly.NewCollector(<br /> // 開(kāi)啟本機debug<br /> // colly.Debugger(&debug.LogDebugger{}),<br /> colly.AllowedDomains("learnku.com"),<br /> // 防止頁(yè)面重復下載<br /> // colly.CacheDir("./learnku_cache"),<br /> )<br /><br /> // 2.分析頁(yè)面數據<br /> c.OnHTML("div.blog-article-list > .event", func(e *colly.HTMLElement) {<br /> article := Article{<br /> Title: e.ChildText("div.content > div.summary"),<br /> URL: e.ChildAttr("div.content a.title", "href"),<br /> Feeds: e.ChildText("div.item-meta > a:first-child"),<br /> }<br /> // 查找同一集合不同子項<br /> e.ForEach("div.content > div.meta > div.date>a", func(i int, el *colly.HTMLElement) {<br /> switch i {<br /> case 1:<br /> article.Created = el.Attr("data-tooltip")<br /> case 2:<br /> // 用空白切割字符串<br /> article.Reads = strings.Fields(el.Text)[1]<br /> case 3:<br /> article.Comments = strings.Fields(el.Text)[1]<br /> }<br /> })<br /> // 正則匹配替換,字符串轉整型<br /> article.ID, _ = strconv.Atoi(regexp.MustCompile(`\d+`).FindAllString(article.URL, -1)[0])<br /> articles = append(articles, article)<br /> })<br /><br /> // 下一頁(yè)<br /> c.OnHTML("a[href].page-link", func(e *colly.HTMLElement) {<br /> e.Request.Visit(e.Attr("href"))<br /> })<br /><br /> // 啟動(dòng)<br /> c.Visit("https://learnku.com/blog/pardon";)<br /><br /> // 輸出<br /> csvSave("pardon.csv", articles)<br /> enc := json.NewEncoder(os.Stdout)<br /> enc.SetIndent("", " ")<br /> enc.Encode(articles)<br /><br /> // 顯示收集器的打印信息<br /> log.Println(c)<br />}<br />
  Output
  控制臺輸出
  ....<br /> "id": 30604,<br /> "title": "教程: TodoMVC 與 director 路由",<br /> "url": "https://learnku.com/articles/30604",<br /> "created": "2019-07-01 12:42:01",<br /> "reads": "650",<br /> "comments": "0",<br /> "feeds": "0"<br /> },<br /> {<br /> "id": 30579,<br /> "title": "flaskr 進(jìn)階筆記",<br /> "url": "https://learnku.com/articles/30579",<br /> "created": "2019-06-30 19:01:04",<br /> "reads": "895",<br /> "comments": "0",<br /> "feeds": "0"<br /> },<br /> {<br /> "id": 30542,<br /> "title": "教程 Redis+ flask+vue 在線(xiàn)聊天",<br /> "url": "https://learnku.com/articles/30542",<br /> "created": "2019-06-29 12:19:45",<br /> "reads": "2760",<br /> "comments": "1",<br /> "feeds": "2"<br /> }<br />]<br />2019/12/20 15:50:14 Requests made: 5 (5 responses) | Callbacks: OnRequest: 0, OnHTML: 2, OnResponse: 0, OnError: 0
  csv 文本輸出
  ID,Title,URL,Created,Reads,Comments,Feeds<br />37991,ferret 爬取動(dòng)態(tài)網(wǎng)頁(yè),https://learnku.com/articles/37991,2019-12-15 10:43:03,219,0,3<br />37803,匿名類(lèi) 與 索引重建,https://learnku.com/articles/37803,2019-12-09 19:35:09,323,1,0<br />37476,大話(huà)并發(fā),https://learnku.com/articles/37476,2019-12-08 21:17:55,612,0,4<br />37738,三元運算符,https://learnku.com/articles/37738,2019-12-08 09:44:36,606,0,0<br />37719,筆試之 模板變量替換,https://learnku.com/articles/37719,2019-12-07 18:30:42,843,0,0<br />37707,筆試之 連續數增維,https://learnku.com/articles/37707,2019-12-07 13:50:17,872,0,0<br />37616,筆試之 一行代碼求重,https://learnku.com/articles/37616,2019-12-05 12:10:24,792,0,0<br />....
  Colly

Python網(wǎng)頁(yè)爬蟲(chóng)&文本處理&科學(xué)計算&機器學(xué)習&數據挖掘兵器譜(轉)

網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 71 次瀏覽 ? 2022-06-07 06:58 ? 來(lái)自相關(guān)話(huà)題

  Python網(wǎng)頁(yè)爬蟲(chóng)&文本處理&科學(xué)計算&機器學(xué)習&數據挖掘兵器譜(轉)
  已獲得授權
  周末時(shí)看到這篇不錯的文章,其中介紹了諸多python第三方庫和工具,與大家分享下,也算是門(mén)可羅雀的本號第一次轉載文章。后續看到精彩的文章也會(huì )繼續分享。
  
  Image Photograph by Pavliha Getty
  曾經(jīng)因為NLTK的緣故開(kāi)始學(xué)習Python,之后漸漸成為我工作中的第一輔助腳本語(yǔ)言,雖然開(kāi)發(fā)語(yǔ)言是C/C++,但平時(shí)的很多文本數據處理任務(wù)都交給了Python。
  離開(kāi)騰訊創(chuàng )業(yè)后,第一個(gè)作品課程圖譜也是選擇了Python系的Flask框架,漸漸的將自己的絕大部分工作交給了Python。這些年來(lái),接觸和使用了很多Python工具包,特別是在文本處理,科學(xué)計算,機器學(xué)習和數據挖掘領(lǐng)域,有很多很多優(yōu)秀的Python工具包可供使用,所以作為Pythoner,也是相當幸福的。
  其實(shí)如果仔細留意微博,你會(huì )發(fā)現很多這方面的分享,自己也Google了一下,發(fā)現也有同學(xué)總結了“Python機器學(xué)習庫”,不過(guò)總感覺(jué)缺少點(diǎn)什么。最近流行一個(gè)詞,全棧工程師(full stack engineer),作為一個(gè)苦逼的創(chuàng )業(yè)者,天然的要把自己打造成一個(gè)full stack engineer,而這個(gè)過(guò)程中,這些Python工具包給自己提供了足夠的火力,所以想起了這個(gè)系列。
  當然,這也僅僅是拋磚引玉,希望大家能提供更多的線(xiàn)索,來(lái)匯總整理一套Python網(wǎng)頁(yè)爬蟲(chóng),文本處理,科學(xué)計算,機器學(xué)習和數據挖掘的兵器譜。
  一、Python網(wǎng)頁(yè)爬蟲(chóng)工具集
  一個(gè)真實(shí)的項目,一定是從獲取數據開(kāi)始的。無(wú)論文本處理,機器學(xué)習和數據挖掘,都需要數據,除了通過(guò)一些渠道購買(mǎi)或者下載的專(zhuān)業(yè)數據外,常常需要大家自己動(dòng)手爬數據,這個(gè)時(shí)候,爬蟲(chóng)就顯得格外重要了,幸好,Python提供了一批很不錯的網(wǎng)頁(yè)爬蟲(chóng)工具框架,既能爬取數據,也能獲取和清洗數據,我們也就從這里開(kāi)始了:
  1.Scrapy
  Scrapy, a fast high-level screen scraping and web crawling framework for Python.
  鼎鼎大名的Scrapy,相信不少同學(xué)都有耳聞,課程圖譜中的很多課程都是依靠Scrapy抓去的,這方面的介紹文章有很多,推薦大牛pluskid早年的一篇文章:《Scrapy 輕松定制網(wǎng)絡(luò )爬蟲(chóng)》,歷久彌新。
  官方主頁(yè):
  Github代碼頁(yè):
  2.Beautiful Soup
  You didn’t write that awful page. You’re just trying to get some data out of it. Beautiful Soup is here to help. Since 2004, it’s been saving programmers hours or days of work on quick-turnaround screen scraping projects.
  讀書(shū)的時(shí)候通過(guò)《集體智慧編程》這本書(shū)知道Beautiful Soup的,后來(lái)也偶爾會(huì )用用,非常棒的一套工具??陀^(guān)的說(shuō),Beautifu Soup不完全是一套爬蟲(chóng)工具,需要配合urllib使用,而是一套HTML/XML數據分析,清洗和獲取工具。
  官方主頁(yè):
  3.Python-Goose
  Html Content / Article Extractor, web scrapping lib in Python
  Goose最早是用Java寫(xiě)得,后來(lái)用Scala重寫(xiě),是一個(gè)Scala項目。Python-Goose用Python重寫(xiě),依賴(lài)了Beautiful Soup。前段時(shí)間用過(guò),感覺(jué)很不錯,給定一個(gè)文章的URL, 獲取文章的標題和內容很方便。
  Github主頁(yè):
  二、Python文本處理工具集
  從網(wǎng)頁(yè)上獲取文本數據之后,依據任務(wù)的不同,就需要進(jìn)行基本的文本處理了,譬如對于英文來(lái)說(shuō),需要基本的tokenize,對于中文,則需要常見(jiàn)的中文分詞,進(jìn)一步的話(huà),無(wú)論英文中文,還可以詞性標注,句法分析,關(guān)鍵詞提取,文本分類(lèi),情感分析等等。這個(gè)方面,特別是面向英文領(lǐng)域,有很多優(yōu)秀的工具包,我們一一道來(lái)。
  1.NLTK— Natural Language Toolkit
  NLTK is a leading platform for building Python programs to work with human language data. It provides easy-to-use interfaces to over 50 corpora and lexical resources such as WordNet, along with a suite of text processing libraries for classification, tokenization, stemming, tagging, parsing, and semantic reasoning, and an active discussion forum.
  搞自然語(yǔ)言處理的同學(xué)應該沒(méi)有人不知道NLTK吧,這里也就不多說(shuō)了。不過(guò)推薦兩本書(shū)籍給剛剛接觸NLTK或者需要詳細了解NLTK的同學(xué): 一個(gè)是官方的《Natural Language Processing with Python》,以介紹NLTK里的功能用法為主,同時(shí)附帶一些Python知識,同時(shí)國內陳濤同學(xué)友情翻譯了一個(gè)中文版,這里可以看到:推薦《用Python進(jìn)行自然語(yǔ)言處理》中文翻譯-NLTK配套書(shū);另外一本是《Python Text Processing with NLTK 2.0 Cookbook》,這本書(shū)要深入一些,會(huì )涉及到NLTK的代碼結構,同時(shí)會(huì )介紹如何定制自己的語(yǔ)料和模型等,相當不錯。
  官方主頁(yè):
  Github代碼頁(yè):
  2.Pattern
  Pattern is a web mining module for the Python programming language.
  It has tools for data mining (Google, Twitter and Wikipedia API, a web crawler, a HTML DOM parser), natural language processing (part-of-speech taggers, n-gram search, sentiment analysis, WordNet), machine learning (vector space model, clustering, SVM), network analysis and canvas visualization.
  Pattern由比利時(shí)安特衛普大學(xué)CLiPS實(shí)驗室出品,客觀(guān)的說(shuō),Pattern不僅僅是一套文本處理工具,它更是一套web數據挖掘工具,囊括了數據抓取模塊(包括Google, Twitter, 維基百科的API,以及爬蟲(chóng)和HTML分析器),文本處理模塊(詞性標注,情感分析等),機器學(xué)習模塊(VSM, 聚類(lèi),SVM)以及可視化模塊等,可以說(shuō),Pattern的這一整套邏輯也是這篇文章的組織邏輯,不過(guò)這里我們暫且把Pattern放到文本處理部分。我個(gè)人主要使用的是它的英文處理模塊Pattern.en, 有很多很不錯的文本處理功能,包括基礎的tokenize, 詞性標注,句子切分,語(yǔ)法檢查,拼寫(xiě)糾錯,情感分析,句法分析等,相當不錯。
  官方主頁(yè):
  3.TextBlob: Simplified Text Processing
  TextBlob is a Python (2 and 3) library for processing textual data. It provides a simple API for diving into common natural language processing (NLP) tasks such as part-of-speech tagging, noun phrase extraction, sentiment analysis, classification, translation, and more.
  TextBlob是一個(gè)很有意思的Python文本處理工具包,它其實(shí)是基于上面兩個(gè)Python工具包NLKT和Pattern做了封裝(TextBlob stands on the giant shoulders of NLTK and pattern, and plays nicely with both),同時(shí)提供了很多文本處理功能的接口,包括詞性標注,名詞短語(yǔ)提取,情感分析,文本分類(lèi),拼寫(xiě)檢查等,甚至包括翻譯和語(yǔ)言檢測,不過(guò)這個(gè)是基于Google的API的,有調用次數限制。TextBlob相對比較年輕,有興趣的同學(xué)可以關(guān)注。
  官方主頁(yè):
  Github代碼頁(yè):
  4.MBSPfor Python
  MBSP is a text analysis system based on the TiMBL and MBT memory based learning applications developed at CLiPS and ILK. It provides tools for Tokenization and Sentence Splitting, Part of Speech Tagging, Chunking, Lemmatization, Relation Finding and Prepositional Phrase Attachment.
  MBSP與Pattern同源,同出自比利時(shí)安特衛普大學(xué)CLiPS實(shí)驗室,提供了Word Tokenization, 句子切分,詞性標注,Chunking, Lemmatization,句法分析等基本的文本處理功能,感興趣的同學(xué)可以關(guān)注。
  官方主頁(yè):
  5.Gensim: Topic modeling for humans
  Gensim是一個(gè)相當專(zhuān)業(yè)的主題模型Python工具包,無(wú)論是代碼還是文檔,我們曾經(jīng)用《如何計算兩個(gè)文檔的相似度》介紹過(guò)Gensim的安裝和使用過(guò)程,這里就不多說(shuō)了。
  官方主頁(yè):
  github代碼頁(yè):
  6.langid.py: Stand-alone language identification system
  語(yǔ)言檢測是一個(gè)很有意思的話(huà)題,不過(guò)相對比較成熟,這方面的解決方案很多,也有很多不錯的開(kāi)源工具包,不過(guò)對于Python來(lái)說(shuō),我使用過(guò)langid這個(gè)工具包,也非常愿意推薦它。langid目前支持97種語(yǔ)言的檢測,提供了很多易用的功能,包括可以啟動(dòng)一個(gè)建議的server,通過(guò)json調用其API,可定制訓練自己的語(yǔ)言檢測模型等,可以說(shuō)是“麻雀雖小,五臟俱全”。
  Github主頁(yè):
  7.Jieba: 結巴中文分詞
  “結巴”中文分詞:做最好的Python中文分詞組件 “Jieba” (Chinese for “to stutter”) Chinese text segmentation: built to be the best Python Chinese word segmentation module.
  好了,終于可以說(shuō)一個(gè)國內的Python文本處理工具包了:結巴分詞,其功能包括支持三種分詞模式(精確模式、全模式、搜索引擎模式),支持繁體分詞,支持自定義詞典等,是目前一個(gè)非常不錯的Python中文分詞解決方案。
  Github主頁(yè):
  8.xTAS
  xtas, the eXtensible Text Analysis Suite, a distributed text analysis package based on Celery and Elasticsearch.
  感謝微博朋友@大山坡的春提供的線(xiàn)索:我們組同事之前發(fā)布了xTAS,也是基于python的text mining工具包,歡迎使用,鏈接:??雌饋?lái)很不錯的樣子,回頭試用一下。
  Github代碼頁(yè):
  三、Python科學(xué)計算工具包
  說(shuō)起科學(xué)計算,大家首先想起的是Matlab,集數值計算,可視化工具及交互于一身,不過(guò)可惜是一個(gè)商業(yè)產(chǎn)品。開(kāi)源方面除了GNU Octave在嘗試做一個(gè)類(lèi)似Matlab的工具包外,Python的這幾個(gè)工具包集合到一起也可以替代Matlab的相應功能:NumPy+SciPy+Matplotlib+iPython。同時(shí),這幾個(gè)工具包,特別是NumPy和SciPy,也是很多Python文本處理 & 機器學(xué)習 & 數據挖掘工具包的基礎,非常重要。最后再推薦一個(gè)系列《用Python做科學(xué)計算》,將會(huì )涉及到NumPy, SciPy, Matplotlib,可以做參考。
  1.NumPy
  NumPy is the fundamental package for scientific computing with Python. It contains among other things:
  1)a powerful N-dimensional array object
  2)sophisticated (broadcasting) functions
  3)tools for integrating C/C++ and Fortran code
  4) useful linear algebra, Fourier transform, and random number capabilities
  Besides its obvious scientific uses, NumPy can also be used as an efficient multi-dimensional container of generic data. Arbitrary data-types can be defined. This allows NumPy to seamlessly and speedily integrate with a wide variety of databases.
  NumPy幾乎是一個(gè)無(wú)法回避的科學(xué)計算工具包,最常用的也許是它的N維數組對象,其他還包括一些成熟的函數庫,用于整合C/C++和Fortran代碼的工具包,線(xiàn)性代數、傅里葉變換和隨機數生成函數等。NumPy提供了兩種基本的對象:ndarray(N-dimensional array object)和 ufunc(universal function object)。ndarray是存儲單一數據類(lèi)型的多維數組,而ufunc則是能夠對數組進(jìn)行處理的函數。
  官方主頁(yè):
  2.SciPy:Scientific Computing Tools for Python
  SciPy refers to several related but distinct entities:
  1)The SciPy Stack, a collection of open source software for scientific computing in Python, and particularly a specified set of core packages.
  2)The community of people who use and develop this stack.
  3)Several conferences dedicated to scientific computing in Python – SciPy, EuroSciPy and SciPy.in.
  4)The SciPy library, one component of the SciPy stack, providing many numerical routines.
  “SciPy是一個(gè)開(kāi)源的Python算法庫和數學(xué)工具包,SciPy包含的模塊有最優(yōu)化、線(xiàn)性代數、積分、插值、特殊函數、快速傅里葉變換、信號處理和圖像處理、常微分方程求解和其他科學(xué)與工程中常用的計算。其功能與軟件MATLAB、Scilab和GNU Octave類(lèi)似。 Numpy和Scipy常常結合著(zhù)使用,Python大多數機器學(xué)習庫都依賴(lài)于這兩個(gè)模塊?!薄?引用自“Python機器學(xué)習庫”
  官方主頁(yè):
  3.Matplotlib
  matplotlib is a python 2D plotting library which produces publication quality figures in a variety of hardcopy formats and interactive environments across platforms. matplotlib can be used in python scripts, the python and ipython shell (ala MATLAB?* or Mathematica??), web application servers, and six graphical user interface toolkits.
  matplotlib 是python最著(zhù)名的繪圖庫,它提供了一整套和matlab相似的命令API,十分適合交互式地進(jìn)行制圖。而且也可以方便地將它作為繪圖控件,嵌入GUI應用程序中。Matplotlib可以配合ipython shell使用,提供不亞于Matlab的繪圖體驗,總之用過(guò)了都說(shuō)好。
  官方主頁(yè):
  4.iPython
  IPython provides a rich architecture for interactive computing with:
  1)Powerful interactive shells (terminal and Qt-based).
  2)A browser-based notebook with support for code, text, mathematical expressions, inline plots and other rich media.
  3)Support for interactive data visualization and use of GUI toolkits.
  4)Flexible, embeddable interpreters to load into your own projects.
  5)Easy to use, high performance tools for parallel computing.
  “iPython 是一個(gè)Python 的交互式Shell,比默認的Python Shell 好用得多,功能也更強大。 她支持語(yǔ)法高亮、自動(dòng)完成、代碼調試、對象自省,支持 Bash Shell 命令,內置了許多很有用的功能和函式等,非常容易使用。 ” 啟動(dòng)iPython的時(shí)候用這個(gè)命令“ipython –pylab”,默認開(kāi)啟了matploblib的繪圖交互,用起來(lái)很方便。
  官方主頁(yè):
  四、Python 機器學(xué)習 & 數據挖掘 工具包
  機器學(xué)習和數據挖掘這兩個(gè)概念不太好區分,這里就放到一起了。這方面的開(kāi)源Python工具包有很多,這里先從熟悉的講起,再補充其他來(lái)源的資料,也歡迎大家補充。
  1.scikit-learn: Machine Learning in Python
  scikit-learn (formerly scikits.learn) is an open source machine learning library for the Python programming language. It features various classification, regression and clustering algorithms including support vector machines, logistic regression, naive Bayes, random forests, gradient boosting, k-means and DBSCAN, and is designed to interoperate with the Python numerical and scientific libraries NumPy and SciPy.
  首先推薦大名鼎鼎的scikit-learn,scikit-learn是一個(gè)基于NumPy, SciPy, Matplotlib的開(kāi)源機器學(xué)習工具包,主要涵蓋分類(lèi),回歸和聚類(lèi)算法,例如SVM, 邏輯回歸,樸素貝葉斯,隨機森林,k-means等算法,代碼和文檔都非常不錯,在許多Python項目中都有應用。例如在我們熟悉的NLTK中,分類(lèi)器方面就有專(zhuān)門(mén)針對scikit-learn的接口,可以調用scikit-learn的分類(lèi)算法以及訓練數據來(lái)訓練分類(lèi)器模型。這里推薦一個(gè)視頻,也是我早期遇到scikit-learn的時(shí)候推薦過(guò)的:推薦一個(gè)Python機器學(xué)習工具包Scikit-learn以及相關(guān)視頻–Tutorial: scikit-learn – Machine Learning in Python
  官方主頁(yè):
  2.Pandas: Python Data Analysis Library
  Pandas is a software library written for the Python programming language for data manipulation and analysis. In particular, it offers data structures and operations for manipulating numerical tables and time series.
  第一次接觸Pandas是由于Udacity上的一門(mén)數據分析課程“Introduction to Data Science” 的Project需要用Pandas庫,所以學(xué)習了一下Pandas。Pandas也是基于NumPy和Matplotlib開(kāi)發(fā)的,主要用于數據分析和數據可視化,它的數據結構DataFrame和R語(yǔ)言里的data.frame很像,特別是對于時(shí)間序列數據有自己的一套分析機制,非常不錯。這里推薦一本書(shū)《Python for Data Analysis》,作者是Pandas的主力開(kāi)發(fā),依次介紹了iPython, NumPy, Pandas里的相關(guān)功能,數據可視化,數據清洗和加工,時(shí)間數據處理等,案例包括金融股票數據挖掘等,相當不錯。
  官方主頁(yè):
  =====================================================
  分割線(xiàn),以上工具包基本上都是自己用過(guò)的,以下來(lái)源于其他同學(xué)的線(xiàn)索,特別是《Python機器學(xué)習庫》,《23個(gè)python的機器學(xué)習包》,做了一點(diǎn)增刪修改,歡迎大家補充
  =====================================================
  3.mlpy – Machine Learning Python
  mlpy is a Python module for Machine Learning built on top of NumPy/SciPy and the GNU Scientific Libraries.
  mlpy provides a wide range of state-of-the-art machine learning methods for supervised and unsupervised problems and it is aimed at finding a reasonable compromise among modularity, maintainability, reproducibility, usability and efficiency. mlpy is multiplatform, it works with Python 2 and 3 and it is Open Source, distributed under the GNU General Public License version 3.
  官方主頁(yè):
  4.MDP:The Modular toolkit for Data Processing
  Modular toolkit for Data Processing (MDP) is a Python data processing framework.
  From the user’s perspective, MDP is a collection of supervised and unsupervised learning algorithms and other data processing units that can be combined into data processing sequences and more complex feed-forward network architectures.
  From the scientific developer’s perspective, MDP is a modular framework, which can easily be expanded. The implementation of new algorithms is easy and intuitive. The new implemented units are then automatically integrated with the rest of the library.
  The base of available algorithms is steadily increasing and includes signal processing methods (Principal Component Analysis, Independent Component Analysis, Slow Feature Analysis), manifold learning methods ([Hessian] Locally Linear Embedding), several classifiers, probabilistic methods (Factor Analysis, RBM), data pre-processing methods, and many others.
  “MDP用于數據處理的模塊化工具包,一個(gè)Python數據處理框架。 從用戶(hù)的觀(guān)點(diǎn),MDP是能夠被整合到數據處理序列和更復雜的前饋網(wǎng)絡(luò )結構的一批監督學(xué)習和非監督學(xué)習算法和其他數據處理單元。計算依照速度和內存需求而高效的執行。從科學(xué)開(kāi)發(fā)者的觀(guān)點(diǎn),MDP是一個(gè)模塊框架,它能夠被容易地擴展。新算法的實(shí)現是容易且直觀(guān)的。新實(shí)現的單元然后被自動(dòng)地與程序庫的其余部件進(jìn)行整合。MDP在神經(jīng)科學(xué)的理論研究背景下被編寫(xiě),但是它已經(jīng)被設計為在使用可訓練數據處理算法的任何情況中都是有用的。其站在用戶(hù)一邊的簡(jiǎn)單性,各種不同的隨時(shí)可用的算法,及應用單元的可重用性,使得它也是一個(gè)有用的教學(xué)工具?!?
  官方主頁(yè):
  5.PyBrain
  PyBrain is a modular Machine Learning Library for Python. Its goal is to offer flexible, easy-to-use yet still powerful algorithms for Machine Learning Tasks and a variety of predefined environments to test and compare your algorithms.
  PyBrain is short for Python-Based Reinforcement Learning, Artificial Intelligence and Neural Network Library. In fact, we came up with the name first and later reverse-engineered this quite descriptive “Backronym”.
  “PyBrain(Python-Based Reinforcement Learning, Artificial Intelligence and Neural Network)是Python的一個(gè)機器學(xué)習模塊,它的目標是為機器學(xué)習任務(wù)提供靈活、易應、強大的機器學(xué)習算法。(這名字很霸氣)
  PyBrain正如其名,包括神經(jīng)網(wǎng)絡(luò )、強化學(xué)習(及二者結合)、無(wú)監督學(xué)習、進(jìn)化算法。因為目前的許多問(wèn)題需要處理連續態(tài)和行為空間,必須使用函數逼近(如神經(jīng)網(wǎng)絡(luò ))以應對高維數據。PyBrain以神經(jīng)網(wǎng)絡(luò )為核心,所有的訓練方法都以神經(jīng)網(wǎng)絡(luò )為一個(gè)實(shí)例?!?
  官方主頁(yè):
  6.PyML– machine learning in Python
  PyML is an interactive object oriented framework for machine learning written in Python. PyML focuses on SVMs and other kernel methods. It is supported on Linux and Mac OS X.
  “PyML是一個(gè)Python機器學(xué)習工具包,為各分類(lèi)和回歸方法提供靈活的架構。它主要提供特征選擇、模型選擇、組合分類(lèi)器、分類(lèi)評估等功能?!?
  項目主頁(yè):
  7.Milk:Machine learning toolkit in Python.
  Its focus is on supervised classification with several classifiers available:
  SVMs (based on libsvm), k-NN, random forests, decision trees. It also performs
  feature selection. These classifiers can be combined in many ways to form
  different classification systems.
  “Milk是Python的一個(gè)機器學(xué)習工具箱,其重點(diǎn)是提供監督分類(lèi)法與幾種有效的分類(lèi)分析:SVMs(基于libsvm),K-NN,隨機森林經(jīng)濟和決策樹(shù)。它還可以進(jìn)行特征選擇。這些分類(lèi)可以在許多方面相結合,形成不同的分類(lèi)系統。對于無(wú)監督學(xué)習,它提供K-means和affinity propagation聚類(lèi)算法?!?
  官方主頁(yè):
  8.PyMVPA: MultiVariate Pattern Analysis (MVPA) in Python
  PyMVPA is a Python package intended to ease statistical learning analyses of large datasets. It offers an extensible framework with a high-level interface to a broad range of algorithms for classification, regression, feature selection, data import and export. It is designed to integrate well with related software packages, such as scikit-learn, and MDP. While it is not limited to the neuroimaging domain, it is eminently suited for such datasets. PyMVPA is free software and requires nothing but free-software to run.
  “PyMVPA(Multivariate Pattern Analysis in Python)是為大數據集提供統計學(xué)習分析的Python工具包,它提供了一個(gè)靈活可擴展的框架。它提供的功能有分類(lèi)、回歸、特征選擇、數據導入導出、可視化等”
  官方主頁(yè):
  9.Pyrallel– Parallel Data Analytics in Python
  Experimental project to investigate distributed computation patterns for machine learning and other semi-interactive data analytics tasks.
  “Pyrallel(Parallel Data Analytics in Python)基于分布式計算模式的機器學(xué)習和半交互式的試驗項目,可在小型集群上運行”
  Github代碼頁(yè):
  10.Monte– gradient based learning in Python
  Monte (python) is a Python framework for building gradient based learning machines, like neural networks, conditional random fields, logistic regression, etc. Monte contains modules (that hold parameters, a cost-function and a gradient-function) and trainers (that can adapt a module’s parameters by minimizing its cost-function on training data).
  Modules are usually composed of other modules, which can in turn contain other modules, etc. Gradients of decomposable systems like these can be computed with back-propagation.
  “Monte (machine learning in pure Python)是一個(gè)純Python機器學(xué)習庫。它可以迅速構建神經(jīng)網(wǎng)絡(luò )、條件隨機場(chǎng)、邏輯回歸等模型,使用inline-C優(yōu)化,極易使用和擴展?!?
  官方主頁(yè):
  11.Theano
  Theano is a Python library that allows you to define, optimize, and evaluate mathematical expressions involving multi-dimensional arrays efficiently. Theano features:
  1)tight integration with NumPy – Use numpy.ndarray in Theano-compiled functions.
  2)transparent use of a GPU – Perform data-intensive calculations up to 140x faster than with CPU.(float32 only)
  3)efficient symbolic differentiation – Theano does your derivatives for function with one or many inputs.
  4)speed and stability optimizations – Get the right answer for log(1+x) even when x is really tiny.
  5)dynamic C code generation – Evaluate expressions faster.
  6) extensive unit-testing and self-verification – Detect and diagnose many types of mistake.
  Theano has been powering large-scale computationally intensive scientific investigations since 2007. But it is also approachable enough to be used in the classroom (IFT6266 at the University of Montreal).
  “Theano 是一個(gè) Python 庫,用來(lái)定義、優(yōu)化和模擬數學(xué)表達式計算,用于高效的解決多維數組的計算問(wèn)題。Theano的特點(diǎn):緊密集成Numpy;高效的數據密集型GPU計算;高效的符號微分運算;高速和穩定的優(yōu)化;動(dòng)態(tài)生成c代碼;廣泛的單元測試和自我驗證。自2007年以來(lái),Theano已被廣泛應用于科學(xué)運算。theano使得構建深度學(xué)習模型更加容易,可以快速實(shí)現多種模型。PS:Theano,一位希臘美女,Croton最有權勢的Milo的女兒,后來(lái)成為了畢達哥拉斯的老婆?!?
  12.Pylearn2
  Pylearn2 is a machine learning library. Most of its functionality is built on top of Theano. This means you can write Pylearn2 plugins (new models, algorithms, etc) using mathematical expressions, and theano will optimize and stabilize those expressions for you, and compile them to a backend of your choice (CPU or GPU).
  “Pylearn2建立在theano上,部分依賴(lài)scikit-learn上,目前Pylearn2正處于開(kāi)發(fā)中,將可以處理向量、圖像、視頻等數據,提供MLP、RBM、SDA等深度學(xué)習模型?!?
  官方主頁(yè):
  其他的,歡迎大家補充。
  歡迎關(guān)注“牛衣古柳”
  門(mén)可羅雀,快來(lái)捕鳥(niǎo)!
   查看全部

  Python網(wǎng)頁(yè)爬蟲(chóng)&文本處理&科學(xué)計算&機器學(xué)習&數據挖掘兵器譜(轉)
  已獲得授權
  周末時(shí)看到這篇不錯的文章,其中介紹了諸多python第三方庫和工具,與大家分享下,也算是門(mén)可羅雀的本號第一次轉載文章。后續看到精彩的文章也會(huì )繼續分享。
  
  Image Photograph by Pavliha Getty
  曾經(jīng)因為NLTK的緣故開(kāi)始學(xué)習Python,之后漸漸成為我工作中的第一輔助腳本語(yǔ)言,雖然開(kāi)發(fā)語(yǔ)言是C/C++,但平時(shí)的很多文本數據處理任務(wù)都交給了Python。
  離開(kāi)騰訊創(chuàng )業(yè)后,第一個(gè)作品課程圖譜也是選擇了Python系的Flask框架,漸漸的將自己的絕大部分工作交給了Python。這些年來(lái),接觸和使用了很多Python工具包,特別是在文本處理,科學(xué)計算,機器學(xué)習和數據挖掘領(lǐng)域,有很多很多優(yōu)秀的Python工具包可供使用,所以作為Pythoner,也是相當幸福的。
  其實(shí)如果仔細留意微博,你會(huì )發(fā)現很多這方面的分享,自己也Google了一下,發(fā)現也有同學(xué)總結了“Python機器學(xué)習庫”,不過(guò)總感覺(jué)缺少點(diǎn)什么。最近流行一個(gè)詞,全棧工程師(full stack engineer),作為一個(gè)苦逼的創(chuàng )業(yè)者,天然的要把自己打造成一個(gè)full stack engineer,而這個(gè)過(guò)程中,這些Python工具包給自己提供了足夠的火力,所以想起了這個(gè)系列。
  當然,這也僅僅是拋磚引玉,希望大家能提供更多的線(xiàn)索,來(lái)匯總整理一套Python網(wǎng)頁(yè)爬蟲(chóng),文本處理,科學(xué)計算,機器學(xué)習和數據挖掘的兵器譜。
  一、Python網(wǎng)頁(yè)爬蟲(chóng)工具集
  一個(gè)真實(shí)的項目,一定是從獲取數據開(kāi)始的。無(wú)論文本處理,機器學(xué)習和數據挖掘,都需要數據,除了通過(guò)一些渠道購買(mǎi)或者下載的專(zhuān)業(yè)數據外,常常需要大家自己動(dòng)手爬數據,這個(gè)時(shí)候,爬蟲(chóng)就顯得格外重要了,幸好,Python提供了一批很不錯的網(wǎng)頁(yè)爬蟲(chóng)工具框架,既能爬取數據,也能獲取和清洗數據,我們也就從這里開(kāi)始了:
  1.Scrapy
  Scrapy, a fast high-level screen scraping and web crawling framework for Python.
  鼎鼎大名的Scrapy,相信不少同學(xué)都有耳聞,課程圖譜中的很多課程都是依靠Scrapy抓去的,這方面的介紹文章有很多,推薦大牛pluskid早年的一篇文章:《Scrapy 輕松定制網(wǎng)絡(luò )爬蟲(chóng)》,歷久彌新。
  官方主頁(yè):
  Github代碼頁(yè):
  2.Beautiful Soup
  You didn’t write that awful page. You’re just trying to get some data out of it. Beautiful Soup is here to help. Since 2004, it’s been saving programmers hours or days of work on quick-turnaround screen scraping projects.
  讀書(shū)的時(shí)候通過(guò)《集體智慧編程》這本書(shū)知道Beautiful Soup的,后來(lái)也偶爾會(huì )用用,非常棒的一套工具??陀^(guān)的說(shuō),Beautifu Soup不完全是一套爬蟲(chóng)工具,需要配合urllib使用,而是一套HTML/XML數據分析,清洗和獲取工具。
  官方主頁(yè):
  3.Python-Goose
  Html Content / Article Extractor, web scrapping lib in Python
  Goose最早是用Java寫(xiě)得,后來(lái)用Scala重寫(xiě),是一個(gè)Scala項目。Python-Goose用Python重寫(xiě),依賴(lài)了Beautiful Soup。前段時(shí)間用過(guò),感覺(jué)很不錯,給定一個(gè)文章的URL, 獲取文章的標題和內容很方便。
  Github主頁(yè):
  二、Python文本處理工具集
  從網(wǎng)頁(yè)上獲取文本數據之后,依據任務(wù)的不同,就需要進(jìn)行基本的文本處理了,譬如對于英文來(lái)說(shuō),需要基本的tokenize,對于中文,則需要常見(jiàn)的中文分詞,進(jìn)一步的話(huà),無(wú)論英文中文,還可以詞性標注,句法分析,關(guān)鍵詞提取,文本分類(lèi),情感分析等等。這個(gè)方面,特別是面向英文領(lǐng)域,有很多優(yōu)秀的工具包,我們一一道來(lái)。
  1.NLTK— Natural Language Toolkit
  NLTK is a leading platform for building Python programs to work with human language data. It provides easy-to-use interfaces to over 50 corpora and lexical resources such as WordNet, along with a suite of text processing libraries for classification, tokenization, stemming, tagging, parsing, and semantic reasoning, and an active discussion forum.
  搞自然語(yǔ)言處理的同學(xué)應該沒(méi)有人不知道NLTK吧,這里也就不多說(shuō)了。不過(guò)推薦兩本書(shū)籍給剛剛接觸NLTK或者需要詳細了解NLTK的同學(xué): 一個(gè)是官方的《Natural Language Processing with Python》,以介紹NLTK里的功能用法為主,同時(shí)附帶一些Python知識,同時(shí)國內陳濤同學(xué)友情翻譯了一個(gè)中文版,這里可以看到:推薦《用Python進(jìn)行自然語(yǔ)言處理》中文翻譯-NLTK配套書(shū);另外一本是《Python Text Processing with NLTK 2.0 Cookbook》,這本書(shū)要深入一些,會(huì )涉及到NLTK的代碼結構,同時(shí)會(huì )介紹如何定制自己的語(yǔ)料和模型等,相當不錯。
  官方主頁(yè):
  Github代碼頁(yè):
  2.Pattern
  Pattern is a web mining module for the Python programming language.
  It has tools for data mining (Google, Twitter and Wikipedia API, a web crawler, a HTML DOM parser), natural language processing (part-of-speech taggers, n-gram search, sentiment analysis, WordNet), machine learning (vector space model, clustering, SVM), network analysis and canvas visualization.
  Pattern由比利時(shí)安特衛普大學(xué)CLiPS實(shí)驗室出品,客觀(guān)的說(shuō),Pattern不僅僅是一套文本處理工具,它更是一套web數據挖掘工具,囊括了數據抓取模塊(包括Google, Twitter, 維基百科的API,以及爬蟲(chóng)和HTML分析器),文本處理模塊(詞性標注,情感分析等),機器學(xué)習模塊(VSM, 聚類(lèi),SVM)以及可視化模塊等,可以說(shuō),Pattern的這一整套邏輯也是這篇文章的組織邏輯,不過(guò)這里我們暫且把Pattern放到文本處理部分。我個(gè)人主要使用的是它的英文處理模塊Pattern.en, 有很多很不錯的文本處理功能,包括基礎的tokenize, 詞性標注,句子切分,語(yǔ)法檢查,拼寫(xiě)糾錯,情感分析,句法分析等,相當不錯。
  官方主頁(yè):
  3.TextBlob: Simplified Text Processing
  TextBlob is a Python (2 and 3) library for processing textual data. It provides a simple API for diving into common natural language processing (NLP) tasks such as part-of-speech tagging, noun phrase extraction, sentiment analysis, classification, translation, and more.
  TextBlob是一個(gè)很有意思的Python文本處理工具包,它其實(shí)是基于上面兩個(gè)Python工具包NLKT和Pattern做了封裝(TextBlob stands on the giant shoulders of NLTK and pattern, and plays nicely with both),同時(shí)提供了很多文本處理功能的接口,包括詞性標注,名詞短語(yǔ)提取,情感分析,文本分類(lèi),拼寫(xiě)檢查等,甚至包括翻譯和語(yǔ)言檢測,不過(guò)這個(gè)是基于Google的API的,有調用次數限制。TextBlob相對比較年輕,有興趣的同學(xué)可以關(guān)注。
  官方主頁(yè):
  Github代碼頁(yè):
  4.MBSPfor Python
  MBSP is a text analysis system based on the TiMBL and MBT memory based learning applications developed at CLiPS and ILK. It provides tools for Tokenization and Sentence Splitting, Part of Speech Tagging, Chunking, Lemmatization, Relation Finding and Prepositional Phrase Attachment.
  MBSP與Pattern同源,同出自比利時(shí)安特衛普大學(xué)CLiPS實(shí)驗室,提供了Word Tokenization, 句子切分,詞性標注,Chunking, Lemmatization,句法分析等基本的文本處理功能,感興趣的同學(xué)可以關(guān)注。
  官方主頁(yè):
  5.Gensim: Topic modeling for humans
  Gensim是一個(gè)相當專(zhuān)業(yè)的主題模型Python工具包,無(wú)論是代碼還是文檔,我們曾經(jīng)用《如何計算兩個(gè)文檔的相似度》介紹過(guò)Gensim的安裝和使用過(guò)程,這里就不多說(shuō)了。
  官方主頁(yè):
  github代碼頁(yè):
  6.langid.py: Stand-alone language identification system
  語(yǔ)言檢測是一個(gè)很有意思的話(huà)題,不過(guò)相對比較成熟,這方面的解決方案很多,也有很多不錯的開(kāi)源工具包,不過(guò)對于Python來(lái)說(shuō),我使用過(guò)langid這個(gè)工具包,也非常愿意推薦它。langid目前支持97種語(yǔ)言的檢測,提供了很多易用的功能,包括可以啟動(dòng)一個(gè)建議的server,通過(guò)json調用其API,可定制訓練自己的語(yǔ)言檢測模型等,可以說(shuō)是“麻雀雖小,五臟俱全”。
  Github主頁(yè):
  7.Jieba: 結巴中文分詞
  “結巴”中文分詞:做最好的Python中文分詞組件 “Jieba” (Chinese for “to stutter”) Chinese text segmentation: built to be the best Python Chinese word segmentation module.
  好了,終于可以說(shuō)一個(gè)國內的Python文本處理工具包了:結巴分詞,其功能包括支持三種分詞模式(精確模式、全模式、搜索引擎模式),支持繁體分詞,支持自定義詞典等,是目前一個(gè)非常不錯的Python中文分詞解決方案。
  Github主頁(yè):
  8.xTAS
  xtas, the eXtensible Text Analysis Suite, a distributed text analysis package based on Celery and Elasticsearch.
  感謝微博朋友@大山坡的春提供的線(xiàn)索:我們組同事之前發(fā)布了xTAS,也是基于python的text mining工具包,歡迎使用,鏈接:??雌饋?lái)很不錯的樣子,回頭試用一下。
  Github代碼頁(yè):
  三、Python科學(xué)計算工具包
  說(shuō)起科學(xué)計算,大家首先想起的是Matlab,集數值計算,可視化工具及交互于一身,不過(guò)可惜是一個(gè)商業(yè)產(chǎn)品。開(kāi)源方面除了GNU Octave在嘗試做一個(gè)類(lèi)似Matlab的工具包外,Python的這幾個(gè)工具包集合到一起也可以替代Matlab的相應功能:NumPy+SciPy+Matplotlib+iPython。同時(shí),這幾個(gè)工具包,特別是NumPy和SciPy,也是很多Python文本處理 & 機器學(xué)習 & 數據挖掘工具包的基礎,非常重要。最后再推薦一個(gè)系列《用Python做科學(xué)計算》,將會(huì )涉及到NumPy, SciPy, Matplotlib,可以做參考。
  1.NumPy
  NumPy is the fundamental package for scientific computing with Python. It contains among other things:
  1)a powerful N-dimensional array object
  2)sophisticated (broadcasting) functions
  3)tools for integrating C/C++ and Fortran code
  4) useful linear algebra, Fourier transform, and random number capabilities
  Besides its obvious scientific uses, NumPy can also be used as an efficient multi-dimensional container of generic data. Arbitrary data-types can be defined. This allows NumPy to seamlessly and speedily integrate with a wide variety of databases.
  NumPy幾乎是一個(gè)無(wú)法回避的科學(xué)計算工具包,最常用的也許是它的N維數組對象,其他還包括一些成熟的函數庫,用于整合C/C++和Fortran代碼的工具包,線(xiàn)性代數、傅里葉變換和隨機數生成函數等。NumPy提供了兩種基本的對象:ndarray(N-dimensional array object)和 ufunc(universal function object)。ndarray是存儲單一數據類(lèi)型的多維數組,而ufunc則是能夠對數組進(jìn)行處理的函數。
  官方主頁(yè):
  2.SciPy:Scientific Computing Tools for Python
  SciPy refers to several related but distinct entities:
  1)The SciPy Stack, a collection of open source software for scientific computing in Python, and particularly a specified set of core packages.
  2)The community of people who use and develop this stack.
  3)Several conferences dedicated to scientific computing in Python – SciPy, EuroSciPy and SciPy.in.
  4)The SciPy library, one component of the SciPy stack, providing many numerical routines.
  “SciPy是一個(gè)開(kāi)源的Python算法庫和數學(xué)工具包,SciPy包含的模塊有最優(yōu)化、線(xiàn)性代數、積分、插值、特殊函數、快速傅里葉變換、信號處理和圖像處理、常微分方程求解和其他科學(xué)與工程中常用的計算。其功能與軟件MATLAB、Scilab和GNU Octave類(lèi)似。 Numpy和Scipy常常結合著(zhù)使用,Python大多數機器學(xué)習庫都依賴(lài)于這兩個(gè)模塊?!薄?引用自“Python機器學(xué)習庫”
  官方主頁(yè):
  3.Matplotlib
  matplotlib is a python 2D plotting library which produces publication quality figures in a variety of hardcopy formats and interactive environments across platforms. matplotlib can be used in python scripts, the python and ipython shell (ala MATLAB?* or Mathematica??), web application servers, and six graphical user interface toolkits.
  matplotlib 是python最著(zhù)名的繪圖庫,它提供了一整套和matlab相似的命令API,十分適合交互式地進(jìn)行制圖。而且也可以方便地將它作為繪圖控件,嵌入GUI應用程序中。Matplotlib可以配合ipython shell使用,提供不亞于Matlab的繪圖體驗,總之用過(guò)了都說(shuō)好。
  官方主頁(yè):
  4.iPython
  IPython provides a rich architecture for interactive computing with:
  1)Powerful interactive shells (terminal and Qt-based).
  2)A browser-based notebook with support for code, text, mathematical expressions, inline plots and other rich media.
  3)Support for interactive data visualization and use of GUI toolkits.
  4)Flexible, embeddable interpreters to load into your own projects.
  5)Easy to use, high performance tools for parallel computing.
  “iPython 是一個(gè)Python 的交互式Shell,比默認的Python Shell 好用得多,功能也更強大。 她支持語(yǔ)法高亮、自動(dòng)完成、代碼調試、對象自省,支持 Bash Shell 命令,內置了許多很有用的功能和函式等,非常容易使用。 ” 啟動(dòng)iPython的時(shí)候用這個(gè)命令“ipython –pylab”,默認開(kāi)啟了matploblib的繪圖交互,用起來(lái)很方便。
  官方主頁(yè):
  四、Python 機器學(xué)習 & 數據挖掘 工具包
  機器學(xué)習和數據挖掘這兩個(gè)概念不太好區分,這里就放到一起了。這方面的開(kāi)源Python工具包有很多,這里先從熟悉的講起,再補充其他來(lái)源的資料,也歡迎大家補充。
  1.scikit-learn: Machine Learning in Python
  scikit-learn (formerly scikits.learn) is an open source machine learning library for the Python programming language. It features various classification, regression and clustering algorithms including support vector machines, logistic regression, naive Bayes, random forests, gradient boosting, k-means and DBSCAN, and is designed to interoperate with the Python numerical and scientific libraries NumPy and SciPy.
  首先推薦大名鼎鼎的scikit-learn,scikit-learn是一個(gè)基于NumPy, SciPy, Matplotlib的開(kāi)源機器學(xué)習工具包,主要涵蓋分類(lèi),回歸和聚類(lèi)算法,例如SVM, 邏輯回歸,樸素貝葉斯,隨機森林,k-means等算法,代碼和文檔都非常不錯,在許多Python項目中都有應用。例如在我們熟悉的NLTK中,分類(lèi)器方面就有專(zhuān)門(mén)針對scikit-learn的接口,可以調用scikit-learn的分類(lèi)算法以及訓練數據來(lái)訓練分類(lèi)器模型。這里推薦一個(gè)視頻,也是我早期遇到scikit-learn的時(shí)候推薦過(guò)的:推薦一個(gè)Python機器學(xué)習工具包Scikit-learn以及相關(guān)視頻–Tutorial: scikit-learn – Machine Learning in Python
  官方主頁(yè):
  2.Pandas: Python Data Analysis Library
  Pandas is a software library written for the Python programming language for data manipulation and analysis. In particular, it offers data structures and operations for manipulating numerical tables and time series.
  第一次接觸Pandas是由于Udacity上的一門(mén)數據分析課程“Introduction to Data Science” 的Project需要用Pandas庫,所以學(xué)習了一下Pandas。Pandas也是基于NumPy和Matplotlib開(kāi)發(fā)的,主要用于數據分析和數據可視化,它的數據結構DataFrame和R語(yǔ)言里的data.frame很像,特別是對于時(shí)間序列數據有自己的一套分析機制,非常不錯。這里推薦一本書(shū)《Python for Data Analysis》,作者是Pandas的主力開(kāi)發(fā),依次介紹了iPython, NumPy, Pandas里的相關(guān)功能,數據可視化,數據清洗和加工,時(shí)間數據處理等,案例包括金融股票數據挖掘等,相當不錯。
  官方主頁(yè):
  =====================================================
  分割線(xiàn),以上工具包基本上都是自己用過(guò)的,以下來(lái)源于其他同學(xué)的線(xiàn)索,特別是《Python機器學(xué)習庫》,《23個(gè)python的機器學(xué)習包》,做了一點(diǎn)增刪修改,歡迎大家補充
  =====================================================
  3.mlpy – Machine Learning Python
  mlpy is a Python module for Machine Learning built on top of NumPy/SciPy and the GNU Scientific Libraries.
  mlpy provides a wide range of state-of-the-art machine learning methods for supervised and unsupervised problems and it is aimed at finding a reasonable compromise among modularity, maintainability, reproducibility, usability and efficiency. mlpy is multiplatform, it works with Python 2 and 3 and it is Open Source, distributed under the GNU General Public License version 3.
  官方主頁(yè):
  4.MDP:The Modular toolkit for Data Processing
  Modular toolkit for Data Processing (MDP) is a Python data processing framework.
  From the user’s perspective, MDP is a collection of supervised and unsupervised learning algorithms and other data processing units that can be combined into data processing sequences and more complex feed-forward network architectures.
  From the scientific developer’s perspective, MDP is a modular framework, which can easily be expanded. The implementation of new algorithms is easy and intuitive. The new implemented units are then automatically integrated with the rest of the library.
  The base of available algorithms is steadily increasing and includes signal processing methods (Principal Component Analysis, Independent Component Analysis, Slow Feature Analysis), manifold learning methods ([Hessian] Locally Linear Embedding), several classifiers, probabilistic methods (Factor Analysis, RBM), data pre-processing methods, and many others.
  “MDP用于數據處理的模塊化工具包,一個(gè)Python數據處理框架。 從用戶(hù)的觀(guān)點(diǎn),MDP是能夠被整合到數據處理序列和更復雜的前饋網(wǎng)絡(luò )結構的一批監督學(xué)習和非監督學(xué)習算法和其他數據處理單元。計算依照速度和內存需求而高效的執行。從科學(xué)開(kāi)發(fā)者的觀(guān)點(diǎn),MDP是一個(gè)模塊框架,它能夠被容易地擴展。新算法的實(shí)現是容易且直觀(guān)的。新實(shí)現的單元然后被自動(dòng)地與程序庫的其余部件進(jìn)行整合。MDP在神經(jīng)科學(xué)的理論研究背景下被編寫(xiě),但是它已經(jīng)被設計為在使用可訓練數據處理算法的任何情況中都是有用的。其站在用戶(hù)一邊的簡(jiǎn)單性,各種不同的隨時(shí)可用的算法,及應用單元的可重用性,使得它也是一個(gè)有用的教學(xué)工具?!?
  官方主頁(yè):
  5.PyBrain
  PyBrain is a modular Machine Learning Library for Python. Its goal is to offer flexible, easy-to-use yet still powerful algorithms for Machine Learning Tasks and a variety of predefined environments to test and compare your algorithms.
  PyBrain is short for Python-Based Reinforcement Learning, Artificial Intelligence and Neural Network Library. In fact, we came up with the name first and later reverse-engineered this quite descriptive “Backronym”.
  “PyBrain(Python-Based Reinforcement Learning, Artificial Intelligence and Neural Network)是Python的一個(gè)機器學(xué)習模塊,它的目標是為機器學(xué)習任務(wù)提供靈活、易應、強大的機器學(xué)習算法。(這名字很霸氣)
  PyBrain正如其名,包括神經(jīng)網(wǎng)絡(luò )、強化學(xué)習(及二者結合)、無(wú)監督學(xué)習、進(jìn)化算法。因為目前的許多問(wèn)題需要處理連續態(tài)和行為空間,必須使用函數逼近(如神經(jīng)網(wǎng)絡(luò ))以應對高維數據。PyBrain以神經(jīng)網(wǎng)絡(luò )為核心,所有的訓練方法都以神經(jīng)網(wǎng)絡(luò )為一個(gè)實(shí)例?!?
  官方主頁(yè):
  6.PyML– machine learning in Python
  PyML is an interactive object oriented framework for machine learning written in Python. PyML focuses on SVMs and other kernel methods. It is supported on Linux and Mac OS X.
  “PyML是一個(gè)Python機器學(xué)習工具包,為各分類(lèi)和回歸方法提供靈活的架構。它主要提供特征選擇、模型選擇、組合分類(lèi)器、分類(lèi)評估等功能?!?
  項目主頁(yè):
  7.Milk:Machine learning toolkit in Python.
  Its focus is on supervised classification with several classifiers available:
  SVMs (based on libsvm), k-NN, random forests, decision trees. It also performs
  feature selection. These classifiers can be combined in many ways to form
  different classification systems.
  “Milk是Python的一個(gè)機器學(xué)習工具箱,其重點(diǎn)是提供監督分類(lèi)法與幾種有效的分類(lèi)分析:SVMs(基于libsvm),K-NN,隨機森林經(jīng)濟和決策樹(shù)。它還可以進(jìn)行特征選擇。這些分類(lèi)可以在許多方面相結合,形成不同的分類(lèi)系統。對于無(wú)監督學(xué)習,它提供K-means和affinity propagation聚類(lèi)算法?!?
  官方主頁(yè):
  8.PyMVPA: MultiVariate Pattern Analysis (MVPA) in Python
  PyMVPA is a Python package intended to ease statistical learning analyses of large datasets. It offers an extensible framework with a high-level interface to a broad range of algorithms for classification, regression, feature selection, data import and export. It is designed to integrate well with related software packages, such as scikit-learn, and MDP. While it is not limited to the neuroimaging domain, it is eminently suited for such datasets. PyMVPA is free software and requires nothing but free-software to run.
  “PyMVPA(Multivariate Pattern Analysis in Python)是為大數據集提供統計學(xué)習分析的Python工具包,它提供了一個(gè)靈活可擴展的框架。它提供的功能有分類(lèi)、回歸、特征選擇、數據導入導出、可視化等”
  官方主頁(yè):
  9.Pyrallel– Parallel Data Analytics in Python
  Experimental project to investigate distributed computation patterns for machine learning and other semi-interactive data analytics tasks.
  “Pyrallel(Parallel Data Analytics in Python)基于分布式計算模式的機器學(xué)習和半交互式的試驗項目,可在小型集群上運行”
  Github代碼頁(yè):
  10.Monte– gradient based learning in Python
  Monte (python) is a Python framework for building gradient based learning machines, like neural networks, conditional random fields, logistic regression, etc. Monte contains modules (that hold parameters, a cost-function and a gradient-function) and trainers (that can adapt a module’s parameters by minimizing its cost-function on training data).
  Modules are usually composed of other modules, which can in turn contain other modules, etc. Gradients of decomposable systems like these can be computed with back-propagation.
  “Monte (machine learning in pure Python)是一個(gè)純Python機器學(xué)習庫。它可以迅速構建神經(jīng)網(wǎng)絡(luò )、條件隨機場(chǎng)、邏輯回歸等模型,使用inline-C優(yōu)化,極易使用和擴展?!?
  官方主頁(yè):
  11.Theano
  Theano is a Python library that allows you to define, optimize, and evaluate mathematical expressions involving multi-dimensional arrays efficiently. Theano features:
  1)tight integration with NumPy – Use numpy.ndarray in Theano-compiled functions.
  2)transparent use of a GPU – Perform data-intensive calculations up to 140x faster than with CPU.(float32 only)
  3)efficient symbolic differentiation – Theano does your derivatives for function with one or many inputs.
  4)speed and stability optimizations – Get the right answer for log(1+x) even when x is really tiny.
  5)dynamic C code generation – Evaluate expressions faster.
  6) extensive unit-testing and self-verification – Detect and diagnose many types of mistake.
  Theano has been powering large-scale computationally intensive scientific investigations since 2007. But it is also approachable enough to be used in the classroom (IFT6266 at the University of Montreal).
  “Theano 是一個(gè) Python 庫,用來(lái)定義、優(yōu)化和模擬數學(xué)表達式計算,用于高效的解決多維數組的計算問(wèn)題。Theano的特點(diǎn):緊密集成Numpy;高效的數據密集型GPU計算;高效的符號微分運算;高速和穩定的優(yōu)化;動(dòng)態(tài)生成c代碼;廣泛的單元測試和自我驗證。自2007年以來(lái),Theano已被廣泛應用于科學(xué)運算。theano使得構建深度學(xué)習模型更加容易,可以快速實(shí)現多種模型。PS:Theano,一位希臘美女,Croton最有權勢的Milo的女兒,后來(lái)成為了畢達哥拉斯的老婆?!?
  12.Pylearn2
  Pylearn2 is a machine learning library. Most of its functionality is built on top of Theano. This means you can write Pylearn2 plugins (new models, algorithms, etc) using mathematical expressions, and theano will optimize and stabilize those expressions for you, and compile them to a backend of your choice (CPU or GPU).
  “Pylearn2建立在theano上,部分依賴(lài)scikit-learn上,目前Pylearn2正處于開(kāi)發(fā)中,將可以處理向量、圖像、視頻等數據,提供MLP、RBM、SDA等深度學(xué)習模型?!?
  官方主頁(yè):
  其他的,歡迎大家補充。
  歡迎關(guān)注“牛衣古柳”
  門(mén)可羅雀,快來(lái)捕鳥(niǎo)!
  

如何用C/C++寫(xiě)一個(gè)基于事件的爬蟲(chóng)

網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 84 次瀏覽 ? 2022-06-06 17:06 ? 來(lái)自相關(guān)話(huà)題

  如何用C/C++寫(xiě)一個(gè)基于事件的爬蟲(chóng)
  
  在去年三月份的時(shí)候,寫(xiě)過(guò)一篇文章,講了一下如何寫(xiě)一個(gè)知乎爬蟲(chóng),爬下最高票的答案,并且把代碼放到了github,。在這一年多的時(shí)間里,前前后后有很多人來(lái)問(wèn)我關(guān)于這個(gè)爬蟲(chóng)的一些實(shí)現細節,在回答他們的同時(shí)發(fā)現自己原來(lái)的代碼真是寫(xiě)得太爛了,最近正好有空,把代碼和架構都重寫(xiě)了一下,不能再誤人子弟了。
  所以有了這篇文章,記錄下自己的一些改進(jìn),以及盡可能說(shuō)清楚如何用C++實(shí)現一個(gè)高性能爬蟲(chóng)。
  為什么要用C++寫(xiě)
  在繼續往下看之前一定要先想清楚一個(gè)問(wèn)題,現在用Python或者NodeJS可以非??焖俚亻_(kāi)發(fā)出一個(gè)爬蟲(chóng),庫齊全,開(kāi)發(fā)成本非常低,那為什么還要用C來(lái)寫(xiě)爬蟲(chóng)?答案是這要看你的目的。如果你單純是為了完成一個(gè)數據抓取的任務(wù),當然是任務(wù)完成得越快越好,以后代碼越好修改越好,首選就是那些庫齊全的動(dòng)態(tài)語(yǔ)言,但如果你的目的是為了理解底層系統,理解抓取數據的每一個(gè)環(huán)節,那么我的推薦是用C++寫(xiě)吧,并且所有輪子都自己造。我的目的是后者,所以選擇了用C來(lái)寫(xiě)。既然所有輪子都自己造了,那這篇文章應該叫,如何不用任何第三方庫,只用C/C++內建函數來(lái)完成一個(gè)網(wǎng)絡(luò )爬蟲(chóng)。
  用Python寫(xiě)會(huì )是什么樣子?有Requests庫來(lái)封裝HTTP請求,有BeautifulSoup來(lái)解析HTML,大大減少了開(kāi)發(fā)難度,你只需要知道爬蟲(chóng)的一般流程,很容易寫(xiě)出一個(gè)能跑的代碼,用NodeJS也是一樣的。
  知乎爬蟲(chóng)原理
  如果有讀者不太清楚爬蟲(chóng)的原理,請先看一下這篇入門(mén)文章。
  接下來(lái)簡(jiǎn)單說(shuō)一個(gè)我的zhihu爬蟲(chóng)的原理,因為我的目標是爬下最高贊/最高關(guān)注這些類(lèi)型的答案和問(wèn)題,所以從用戶(hù)主頁(yè)出發(fā)是最好不過(guò)的,比如從用戶(hù)主頁(yè)點(diǎn)擊“回答”,就可以看到用戶(hù)的所有回答,然后抓下來(lái),點(diǎn)擊“提問(wèn)”,就可以看到用戶(hù)所有的提問(wèn)。把所有用戶(hù)的所有回答/提問(wèn)都抓下來(lái)然后根據點(diǎn)贊數/關(guān)注數排序,就是我想要的結果。那所有用戶(hù)怎么得到?從一個(gè)用戶(hù)出發(fā)(即隊列中的初始URL),把TA的所有關(guān)注的人和關(guān)注者都爬下來(lái),不重復地放入URL隊列中,等到當前用戶(hù)處理完,再從URL隊列里拿下一個(gè)用戶(hù),如此循環(huán)即可。
  仔細想想,這個(gè)方法會(huì )有一個(gè)問(wèn)題,如果一個(gè)人即不關(guān)注別人也不被別人關(guān)注,且不在初始URL隊列中,那么這個(gè)用戶(hù)的回答和提問(wèn)永遠不會(huì )被抓到。更一般的結論是,如果有用戶(hù)群構成“孤島”,那么這些用戶(hù)群都不會(huì )被爬蟲(chóng)訪(fǎng)問(wèn)。舉個(gè)例子,A、B互相關(guān)注,C、D互相關(guān)注,如果我們將A放入初始URL隊列,那么爬蟲(chóng)只可能抓下A、B的數據,因為C、D構成了“孤島”,怎么解決這個(gè)問(wèn)題?
  再想想,這個(gè)問(wèn)題真的有必要解決嗎?這個(gè)問(wèn)題會(huì )對我們造成困擾的情況是,一個(gè)大V答了一個(gè)贊數很高的問(wèn)題,但是TA竟然在某座“孤島”上,如果我們稱(chēng)大部分人所構成的連通圖叫主圖,那么這個(gè)大V構成的“孤島”和主圖上的人一點(diǎn)關(guān)系都沒(méi)有,即不被關(guān)注也不關(guān)注別人,這幾乎是不可能的事情,所以這個(gè)問(wèn)題不需要解決。
  如何用C++寫(xiě)爬蟲(chóng)
  無(wú)論用Python或者C++寫(xiě)爬蟲(chóng),底層都是一樣的,都是和server建立若干個(gè)TCP連接,然后把HTTP請求寫(xiě)入這個(gè)TCP socket中,等待server的數據返回。為了高效處理I/O,在linux平臺下需要用epoll(別的平臺請用各自的機制)。
  所以一個(gè)C++爬蟲(chóng)步驟大概是這樣的,本質(zhì)上就是一個(gè)事件循環(huán)(event loop):
  初始化epoll,并和server建立TCP連接
  從URL隊列中拿出url,并準備好http請求
  將http請求寫(xiě)入到這個(gè)TCP socket中,并把這個(gè)socket加入epoll中
  檢查活動(dòng)事件(epoll_wait)
  處理事件,讀取HTML,解析HTML,處理HTML,然后把相關(guān)未處理過(guò)的URL放入URL隊列中
  回到第2步
  原來(lái)的代碼結構
  先簡(jiǎn)單描述一下去年寫(xiě)的爬蟲(chóng)代碼是怎么誤人子弟的。
  程序從隊列里拿到一個(gè)URL后,需要去下載這個(gè)URL的頁(yè)面,解析出我需要的數據,然后把它的下一層URL加入隊列中。原來(lái)的爬蟲(chóng)代碼就老老實(shí)實(shí)地實(shí)現了這個(gè)步驟,阻塞地等待頁(yè)面下載完成,再去處理這個(gè)頁(yè)面。其實(shí)這是很低效的,因為阻塞的這段時(shí)期我們什么都干不了,浪費了帶寬。為什么不把隊列里的其它URL請求一起發(fā)出去呢,然后有數據來(lái)了我就處理。這就是為什么爬蟲(chóng)為什么要用基于事件來(lái)寫(xiě)的原因。
  這里需要理解爬蟲(chóng)這種程序的本質(zhì),它是網(wǎng)絡(luò )I/O密集程序,不是CPU密集,而處理I/O密集最高效的做法就是事件循環(huán)。
  所以我做的一個(gè)做大的改善就是把原來(lái)的阻塞爬蟲(chóng)改成了基于事件的爬蟲(chóng),它得到的好處是可以完全把帶寬跑滿(mǎn),爬取速度最大化。
  除此之外,還有一個(gè)改善是把多線(xiàn)程模型改成了單進(jìn)程模型。有同學(xué)可能會(huì )產(chǎn)生疑惑,難道利用多核還會(huì )比單核性能差?我們從以下兩點(diǎn)來(lái)分析:
  根據amdahl定律,對系統中一個(gè)模塊的加速,不僅取決于加速比,還取決于這個(gè)模塊在原來(lái)系統中占的比例。爬蟲(chóng)是I/O密集程序,絕大部分時(shí)間都花在了網(wǎng)絡(luò )I/O上,CPU大部分時(shí)間是空閑的,所以提高CPU的利用率其實(shí)效果很小。
  多線(xiàn)程會(huì )引入額外的開(kāi)銷(xiāo),最大的開(kāi)銷(xiāo)可能就是鎖了。比如你要把新的URL加入隊列,這時(shí)候在多線(xiàn)程環(huán)境下肯定要對隊列加鎖。
  那么問(wèn)題就是,第一點(diǎn)所帶來(lái)的性能提升和第二點(diǎn)所帶來(lái)的開(kāi)銷(xiāo),哪個(gè)更大一點(diǎn)?如果第二點(diǎn)大,我們果斷要換成單進(jìn)程。答案是看環(huán)境,我們極端點(diǎn)看,如果你的帶寬無(wú)窮大,網(wǎng)絡(luò )情況無(wú)窮好,那么請求一發(fā)出去立刻就回復了,這個(gè)網(wǎng)絡(luò )I/O密集程序硬生生變成了CPU密集,多線(xiàn)程會(huì )好;如果你的帶寬無(wú)窮小,那么鎖帶來(lái)的開(kāi)銷(xiāo)會(huì )占比更大,一個(gè)任務(wù)來(lái)了多線(xiàn)程之間還要競爭一下,單線(xiàn)程就直接處理了且沒(méi)有鎖的性能開(kāi)銷(xiāo),用單線(xiàn)程會(huì )好。我們需要在不同的環(huán)境下選擇最好的辦法,不過(guò)一般來(lái)說(shuō),現實(shí)中最大的時(shí)間開(kāi)銷(xiāo)一定在網(wǎng)絡(luò )I/O。
  用C++實(shí)現爬蟲(chóng)時(shí)的難點(diǎn)
  從TCP socket讀取數據到把完整的HTML數據交付上層需要一個(gè)數據層,因為如果調用read返回EAGAIN時(shí),這時(shí)是不知道到底有沒(méi)有接受到完整的HTML,需要保存好當前讀到的網(wǎng)頁(yè)內容,并通過(guò)一個(gè)狀態(tài)機來(lái)解析當前收到的數據,保存當前的狀態(tài),如果解析完成(讀到全部數據了)就返回SUCCESS,否則就就返回ERROR,等待下一次數據來(lái)臨,繼續解析狀態(tài)機。用動(dòng)態(tài)語(yǔ)言不需要考慮這一點(diǎn),會(huì )直接傳遞給用戶(hù)層完整的數據。
  請求得太快,知乎會(huì )返回429錯誤(即提示客戶(hù)請求太多,稍后再試),這個(gè)問(wèn)題怎么解決?乖乖地等待一段時(shí)間再去抓是一種浪費帶寬的行為。服務(wù)器判斷請求太多是看這個(gè)IP在一段時(shí)間的請求數太多了,如果我們IP分散為N個(gè)不同IP,那就解決這個(gè)問(wèn)題了。這個(gè)方案叫動(dòng)態(tài)IP或者代理IP。那么多IP意味著(zhù)要花很多的錢(qián),如果不愿意花錢(qián),還是乖乖等一段時(shí)間再發(fā)請求吧。
  爬蟲(chóng)里一個(gè)需求,要獲得一個(gè)用戶(hù)的所有關(guān)注的人和關(guān)注者,但這些東西都是通過(guò)ajax獲取的,所以要寫(xiě)一個(gè)post請求來(lái)模擬ajax。其中post data里有一個(gè)hash_id和_xsrf,這兩個(gè)值都在哪里可以獲得?后來(lái)在該用戶(hù)的主頁(yè)的HTML里找到了這兩個(gè)值。
  怎么用C++解析HTML?比如上面一點(diǎn)提到的,我要找到這個(gè)頁(yè)面里的hash_id,它可能是某個(gè)HTML元素的屬性,怎么得到這個(gè)屬性值?用過(guò)JQuery的同學(xué)這時(shí)會(huì )想,如果C++里面也有一個(gè)像JQuery那么好用的庫該多好,直接寫(xiě)個(gè)選擇器就獲得屬性的值了。我簡(jiǎn)單地調研了一下,C++還是有這樣的庫的?;趯W(xué)習的目的,最好自己寫(xiě)一個(gè)這樣的庫,所以,問(wèn)題來(lái)了,怎么實(shí)現一個(gè)HTML parser?或者更簡(jiǎn)單的,怎么實(shí)現一個(gè)正則匹配?
  如何管理一個(gè)請求的周期,因為一個(gè)請求的周期中,狀態(tài)太多了。為什么狀態(tài)多,因為一個(gè)請求會(huì )涉及很多異步操作,首先獲取該用戶(hù)的答案頁(yè)面,這時(shí)候要等待server的回復,處理完以后獲得改用戶(hù)所有關(guān)注的人和關(guān)注者的頁(yè)面,也要等待server的回復,再把這些所有用戶(hù)加入隊列后,這個(gè)請求周期才算結束。
  需要自己處理一些HTTP header的細節。比如不希望接受到HTTP response header里Transfer Encoding: chuncked回復,因為它顯然沒(méi)有Content-length直接獲取到數據長(cháng)度來(lái)得方便,該怎么辦?再比如不希望接受到gzip處理過(guò)的數據,希望收到plain text,又該怎么辦?
  架構怎么設計。首先最底層是TCP層,上層應該封裝一個(gè)數據接收層,再上層應該是HTML解析層,最后是事件循環(huán)層。這些層次/模塊怎么做到耦合度最低?
  網(wǎng)絡(luò )異常怎么處理,比如read返回error(eg Connection reset by peer),或者EOF。EOF需要重新建立一個(gè)新的連接,然后繼續前一個(gè)請求(或者說(shuō)繼續狀態(tài)機)。
  用C++相比Python,NodeJS的優(yōu)點(diǎn)
  系統的掌控性。比如我們希望TCP連接數要控制在1000,完全可能很容易地實(shí)現。并且可以知道哪里會(huì )耗內存、CPU,底層在發(fā)生什么我們更容易知道。比如,在HTTP request header里寫(xiě)上Connection: keep-alive可以讓很多請求復用一個(gè)TCP連接,在用C++實(shí)現的時(shí)候,對應的實(shí)現方法很簡(jiǎn)單粗暴:從socket讀完對方服務(wù)器發(fā)來(lái)的response后,再構造一個(gè)header發(fā)過(guò)去即可。
  因為一些內建庫的缺乏,并且出發(fā)點(diǎn)是學(xué)習,我們會(huì )重新造一些輪子,與此同時(shí),提高了編程能力。 比如說(shuō)讀配置文件,格式是json,可以自己用C寫(xiě)個(gè)json parser。再比如上文提到的HTML parser,也可以用C寫(xiě)一個(gè),還有基于epoll的事件循環(huán),可以抽象成一個(gè)通用的網(wǎng)絡(luò )庫。有太多輪子可以造,要把其中任意一個(gè)輪子寫(xiě)好都是非常難的事情。
  高性能??赡苡捎诰W(wǎng)絡(luò )的大延遲使得這個(gè)優(yōu)點(diǎn)不那么明顯。
  總結
  本文基于我一年多之前寫(xiě)的zhihu爬蟲(chóng)以及最近的大規模改進(jìn),總結了如何用C++編寫(xiě)的高效、基于事件驅動(dòng)的知乎爬蟲(chóng),同時(shí)也列出了用C++寫(xiě)爬蟲(chóng)時(shí)的一些難點(diǎn)與收獲。
  如果你有興趣看看竟然有人用C++寫(xiě)了一個(gè)爬蟲(chóng)究竟是什么樣子的,代碼在這里。
  . END.
  看完本文請分享一下吧!讓其他人也可以GET到新知識!
   查看全部

  如何用C/C++寫(xiě)一個(gè)基于事件的爬蟲(chóng)
  
  在去年三月份的時(shí)候,寫(xiě)過(guò)一篇文章,講了一下如何寫(xiě)一個(gè)知乎爬蟲(chóng),爬下最高票的答案,并且把代碼放到了github,。在這一年多的時(shí)間里,前前后后有很多人來(lái)問(wèn)我關(guān)于這個(gè)爬蟲(chóng)的一些實(shí)現細節,在回答他們的同時(shí)發(fā)現自己原來(lái)的代碼真是寫(xiě)得太爛了,最近正好有空,把代碼和架構都重寫(xiě)了一下,不能再誤人子弟了。
  所以有了這篇文章,記錄下自己的一些改進(jìn),以及盡可能說(shuō)清楚如何用C++實(shí)現一個(gè)高性能爬蟲(chóng)。
  為什么要用C++寫(xiě)
  在繼續往下看之前一定要先想清楚一個(gè)問(wèn)題,現在用Python或者NodeJS可以非??焖俚亻_(kāi)發(fā)出一個(gè)爬蟲(chóng),庫齊全,開(kāi)發(fā)成本非常低,那為什么還要用C來(lái)寫(xiě)爬蟲(chóng)?答案是這要看你的目的。如果你單純是為了完成一個(gè)數據抓取的任務(wù),當然是任務(wù)完成得越快越好,以后代碼越好修改越好,首選就是那些庫齊全的動(dòng)態(tài)語(yǔ)言,但如果你的目的是為了理解底層系統,理解抓取數據的每一個(gè)環(huán)節,那么我的推薦是用C++寫(xiě)吧,并且所有輪子都自己造。我的目的是后者,所以選擇了用C來(lái)寫(xiě)。既然所有輪子都自己造了,那這篇文章應該叫,如何不用任何第三方庫,只用C/C++內建函數來(lái)完成一個(gè)網(wǎng)絡(luò )爬蟲(chóng)。
  用Python寫(xiě)會(huì )是什么樣子?有Requests庫來(lái)封裝HTTP請求,有BeautifulSoup來(lái)解析HTML,大大減少了開(kāi)發(fā)難度,你只需要知道爬蟲(chóng)的一般流程,很容易寫(xiě)出一個(gè)能跑的代碼,用NodeJS也是一樣的。
  知乎爬蟲(chóng)原理
  如果有讀者不太清楚爬蟲(chóng)的原理,請先看一下這篇入門(mén)文章。
  接下來(lái)簡(jiǎn)單說(shuō)一個(gè)我的zhihu爬蟲(chóng)的原理,因為我的目標是爬下最高贊/最高關(guān)注這些類(lèi)型的答案和問(wèn)題,所以從用戶(hù)主頁(yè)出發(fā)是最好不過(guò)的,比如從用戶(hù)主頁(yè)點(diǎn)擊“回答”,就可以看到用戶(hù)的所有回答,然后抓下來(lái),點(diǎn)擊“提問(wèn)”,就可以看到用戶(hù)所有的提問(wèn)。把所有用戶(hù)的所有回答/提問(wèn)都抓下來(lái)然后根據點(diǎn)贊數/關(guān)注數排序,就是我想要的結果。那所有用戶(hù)怎么得到?從一個(gè)用戶(hù)出發(fā)(即隊列中的初始URL),把TA的所有關(guān)注的人和關(guān)注者都爬下來(lái),不重復地放入URL隊列中,等到當前用戶(hù)處理完,再從URL隊列里拿下一個(gè)用戶(hù),如此循環(huán)即可。
  仔細想想,這個(gè)方法會(huì )有一個(gè)問(wèn)題,如果一個(gè)人即不關(guān)注別人也不被別人關(guān)注,且不在初始URL隊列中,那么這個(gè)用戶(hù)的回答和提問(wèn)永遠不會(huì )被抓到。更一般的結論是,如果有用戶(hù)群構成“孤島”,那么這些用戶(hù)群都不會(huì )被爬蟲(chóng)訪(fǎng)問(wèn)。舉個(gè)例子,A、B互相關(guān)注,C、D互相關(guān)注,如果我們將A放入初始URL隊列,那么爬蟲(chóng)只可能抓下A、B的數據,因為C、D構成了“孤島”,怎么解決這個(gè)問(wèn)題?
  再想想,這個(gè)問(wèn)題真的有必要解決嗎?這個(gè)問(wèn)題會(huì )對我們造成困擾的情況是,一個(gè)大V答了一個(gè)贊數很高的問(wèn)題,但是TA竟然在某座“孤島”上,如果我們稱(chēng)大部分人所構成的連通圖叫主圖,那么這個(gè)大V構成的“孤島”和主圖上的人一點(diǎn)關(guān)系都沒(méi)有,即不被關(guān)注也不關(guān)注別人,這幾乎是不可能的事情,所以這個(gè)問(wèn)題不需要解決。
  如何用C++寫(xiě)爬蟲(chóng)
  無(wú)論用Python或者C++寫(xiě)爬蟲(chóng),底層都是一樣的,都是和server建立若干個(gè)TCP連接,然后把HTTP請求寫(xiě)入這個(gè)TCP socket中,等待server的數據返回。為了高效處理I/O,在linux平臺下需要用epoll(別的平臺請用各自的機制)。
  所以一個(gè)C++爬蟲(chóng)步驟大概是這樣的,本質(zhì)上就是一個(gè)事件循環(huán)(event loop):
  初始化epoll,并和server建立TCP連接
  從URL隊列中拿出url,并準備好http請求
  將http請求寫(xiě)入到這個(gè)TCP socket中,并把這個(gè)socket加入epoll中
  檢查活動(dòng)事件(epoll_wait)
  處理事件,讀取HTML,解析HTML,處理HTML,然后把相關(guān)未處理過(guò)的URL放入URL隊列中
  回到第2步
  原來(lái)的代碼結構
  先簡(jiǎn)單描述一下去年寫(xiě)的爬蟲(chóng)代碼是怎么誤人子弟的。
  程序從隊列里拿到一個(gè)URL后,需要去下載這個(gè)URL的頁(yè)面,解析出我需要的數據,然后把它的下一層URL加入隊列中。原來(lái)的爬蟲(chóng)代碼就老老實(shí)實(shí)地實(shí)現了這個(gè)步驟,阻塞地等待頁(yè)面下載完成,再去處理這個(gè)頁(yè)面。其實(shí)這是很低效的,因為阻塞的這段時(shí)期我們什么都干不了,浪費了帶寬。為什么不把隊列里的其它URL請求一起發(fā)出去呢,然后有數據來(lái)了我就處理。這就是為什么爬蟲(chóng)為什么要用基于事件來(lái)寫(xiě)的原因。
  這里需要理解爬蟲(chóng)這種程序的本質(zhì),它是網(wǎng)絡(luò )I/O密集程序,不是CPU密集,而處理I/O密集最高效的做法就是事件循環(huán)。
  所以我做的一個(gè)做大的改善就是把原來(lái)的阻塞爬蟲(chóng)改成了基于事件的爬蟲(chóng),它得到的好處是可以完全把帶寬跑滿(mǎn),爬取速度最大化。
  除此之外,還有一個(gè)改善是把多線(xiàn)程模型改成了單進(jìn)程模型。有同學(xué)可能會(huì )產(chǎn)生疑惑,難道利用多核還會(huì )比單核性能差?我們從以下兩點(diǎn)來(lái)分析:
  根據amdahl定律,對系統中一個(gè)模塊的加速,不僅取決于加速比,還取決于這個(gè)模塊在原來(lái)系統中占的比例。爬蟲(chóng)是I/O密集程序,絕大部分時(shí)間都花在了網(wǎng)絡(luò )I/O上,CPU大部分時(shí)間是空閑的,所以提高CPU的利用率其實(shí)效果很小。
  多線(xiàn)程會(huì )引入額外的開(kāi)銷(xiāo),最大的開(kāi)銷(xiāo)可能就是鎖了。比如你要把新的URL加入隊列,這時(shí)候在多線(xiàn)程環(huán)境下肯定要對隊列加鎖。
  那么問(wèn)題就是,第一點(diǎn)所帶來(lái)的性能提升和第二點(diǎn)所帶來(lái)的開(kāi)銷(xiāo),哪個(gè)更大一點(diǎn)?如果第二點(diǎn)大,我們果斷要換成單進(jìn)程。答案是看環(huán)境,我們極端點(diǎn)看,如果你的帶寬無(wú)窮大,網(wǎng)絡(luò )情況無(wú)窮好,那么請求一發(fā)出去立刻就回復了,這個(gè)網(wǎng)絡(luò )I/O密集程序硬生生變成了CPU密集,多線(xiàn)程會(huì )好;如果你的帶寬無(wú)窮小,那么鎖帶來(lái)的開(kāi)銷(xiāo)會(huì )占比更大,一個(gè)任務(wù)來(lái)了多線(xiàn)程之間還要競爭一下,單線(xiàn)程就直接處理了且沒(méi)有鎖的性能開(kāi)銷(xiāo),用單線(xiàn)程會(huì )好。我們需要在不同的環(huán)境下選擇最好的辦法,不過(guò)一般來(lái)說(shuō),現實(shí)中最大的時(shí)間開(kāi)銷(xiāo)一定在網(wǎng)絡(luò )I/O。
  用C++實(shí)現爬蟲(chóng)時(shí)的難點(diǎn)
  從TCP socket讀取數據到把完整的HTML數據交付上層需要一個(gè)數據層,因為如果調用read返回EAGAIN時(shí),這時(shí)是不知道到底有沒(méi)有接受到完整的HTML,需要保存好當前讀到的網(wǎng)頁(yè)內容,并通過(guò)一個(gè)狀態(tài)機來(lái)解析當前收到的數據,保存當前的狀態(tài),如果解析完成(讀到全部數據了)就返回SUCCESS,否則就就返回ERROR,等待下一次數據來(lái)臨,繼續解析狀態(tài)機。用動(dòng)態(tài)語(yǔ)言不需要考慮這一點(diǎn),會(huì )直接傳遞給用戶(hù)層完整的數據。
  請求得太快,知乎會(huì )返回429錯誤(即提示客戶(hù)請求太多,稍后再試),這個(gè)問(wèn)題怎么解決?乖乖地等待一段時(shí)間再去抓是一種浪費帶寬的行為。服務(wù)器判斷請求太多是看這個(gè)IP在一段時(shí)間的請求數太多了,如果我們IP分散為N個(gè)不同IP,那就解決這個(gè)問(wèn)題了。這個(gè)方案叫動(dòng)態(tài)IP或者代理IP。那么多IP意味著(zhù)要花很多的錢(qián),如果不愿意花錢(qián),還是乖乖等一段時(shí)間再發(fā)請求吧。
  爬蟲(chóng)里一個(gè)需求,要獲得一個(gè)用戶(hù)的所有關(guān)注的人和關(guān)注者,但這些東西都是通過(guò)ajax獲取的,所以要寫(xiě)一個(gè)post請求來(lái)模擬ajax。其中post data里有一個(gè)hash_id和_xsrf,這兩個(gè)值都在哪里可以獲得?后來(lái)在該用戶(hù)的主頁(yè)的HTML里找到了這兩個(gè)值。
  怎么用C++解析HTML?比如上面一點(diǎn)提到的,我要找到這個(gè)頁(yè)面里的hash_id,它可能是某個(gè)HTML元素的屬性,怎么得到這個(gè)屬性值?用過(guò)JQuery的同學(xué)這時(shí)會(huì )想,如果C++里面也有一個(gè)像JQuery那么好用的庫該多好,直接寫(xiě)個(gè)選擇器就獲得屬性的值了。我簡(jiǎn)單地調研了一下,C++還是有這樣的庫的?;趯W(xué)習的目的,最好自己寫(xiě)一個(gè)這樣的庫,所以,問(wèn)題來(lái)了,怎么實(shí)現一個(gè)HTML parser?或者更簡(jiǎn)單的,怎么實(shí)現一個(gè)正則匹配?
  如何管理一個(gè)請求的周期,因為一個(gè)請求的周期中,狀態(tài)太多了。為什么狀態(tài)多,因為一個(gè)請求會(huì )涉及很多異步操作,首先獲取該用戶(hù)的答案頁(yè)面,這時(shí)候要等待server的回復,處理完以后獲得改用戶(hù)所有關(guān)注的人和關(guān)注者的頁(yè)面,也要等待server的回復,再把這些所有用戶(hù)加入隊列后,這個(gè)請求周期才算結束。
  需要自己處理一些HTTP header的細節。比如不希望接受到HTTP response header里Transfer Encoding: chuncked回復,因為它顯然沒(méi)有Content-length直接獲取到數據長(cháng)度來(lái)得方便,該怎么辦?再比如不希望接受到gzip處理過(guò)的數據,希望收到plain text,又該怎么辦?
  架構怎么設計。首先最底層是TCP層,上層應該封裝一個(gè)數據接收層,再上層應該是HTML解析層,最后是事件循環(huán)層。這些層次/模塊怎么做到耦合度最低?
  網(wǎng)絡(luò )異常怎么處理,比如read返回error(eg Connection reset by peer),或者EOF。EOF需要重新建立一個(gè)新的連接,然后繼續前一個(gè)請求(或者說(shuō)繼續狀態(tài)機)。
  用C++相比Python,NodeJS的優(yōu)點(diǎn)
  系統的掌控性。比如我們希望TCP連接數要控制在1000,完全可能很容易地實(shí)現。并且可以知道哪里會(huì )耗內存、CPU,底層在發(fā)生什么我們更容易知道。比如,在HTTP request header里寫(xiě)上Connection: keep-alive可以讓很多請求復用一個(gè)TCP連接,在用C++實(shí)現的時(shí)候,對應的實(shí)現方法很簡(jiǎn)單粗暴:從socket讀完對方服務(wù)器發(fā)來(lái)的response后,再構造一個(gè)header發(fā)過(guò)去即可。
  因為一些內建庫的缺乏,并且出發(fā)點(diǎn)是學(xué)習,我們會(huì )重新造一些輪子,與此同時(shí),提高了編程能力。 比如說(shuō)讀配置文件,格式是json,可以自己用C寫(xiě)個(gè)json parser。再比如上文提到的HTML parser,也可以用C寫(xiě)一個(gè),還有基于epoll的事件循環(huán),可以抽象成一個(gè)通用的網(wǎng)絡(luò )庫。有太多輪子可以造,要把其中任意一個(gè)輪子寫(xiě)好都是非常難的事情。
  高性能??赡苡捎诰W(wǎng)絡(luò )的大延遲使得這個(gè)優(yōu)點(diǎn)不那么明顯。
  總結
  本文基于我一年多之前寫(xiě)的zhihu爬蟲(chóng)以及最近的大規模改進(jìn),總結了如何用C++編寫(xiě)的高效、基于事件驅動(dòng)的知乎爬蟲(chóng),同時(shí)也列出了用C++寫(xiě)爬蟲(chóng)時(shí)的一些難點(diǎn)與收獲。
  如果你有興趣看看竟然有人用C++寫(xiě)了一個(gè)爬蟲(chóng)究竟是什么樣子的,代碼在這里。
  . END.
  看完本文請分享一下吧!讓其他人也可以GET到新知識!
  

網(wǎng)站將用戶(hù)資料分門(mén)別類(lèi)的存儲在百度中

網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 77 次瀏覽 ? 2022-06-05 16:01 ? 來(lái)自相關(guān)話(huà)題

  網(wǎng)站將用戶(hù)資料分門(mén)別類(lèi)的存儲在百度中
  c爬蟲(chóng)抓取網(wǎng)頁(yè)數據,可以得到我們想要的各種格式的數據用戶(hù)信息是可以作為數據有價(jià)值的獲取來(lái)源。比如一個(gè)網(wǎng)站將用戶(hù)資料分門(mén)別類(lèi)的存儲在百度中,那么用戶(hù)不僅可以接受百度的url信息,還可以查看百度收錄了哪些對自己有用的用戶(hù)信息。根據產(chǎn)品上線(xiàn)的數據質(zhì)量對用戶(hù)信息的價(jià)值進(jìn)行確定,在這里對用戶(hù)信息的價(jià)值分為初級價(jià)值、中級價(jià)值、高級價(jià)值三類(lèi)(根據產(chǎn)品和相關(guān)業(yè)務(wù)流程的特征進(jìn)行下劃分),初級價(jià)值比如xxx寶馬集團電子商務(wù)平臺用戶(hù)在購物車(chē)不只是購買(mǎi)自己想要的產(chǎn)品,還可以查看新推薦的商品、查看優(yōu)惠券的使用情況中級價(jià)值比如xxx寶馬集團電子商務(wù)平臺用戶(hù)在購物車(chē)不只是購買(mǎi)自己想要的產(chǎn)品,還可以查看優(yōu)惠券的使用情況高級價(jià)值比如某寶同城生活服務(wù)平臺的用戶(hù)在微信上獲取到完整圖片視頻等內容的用戶(hù)信息通過(guò)以上的分類(lèi),一般可以根據產(chǎn)品的定位將用戶(hù)信息劃分出來(lái),放到哪里去獲取都可以。info_data_name。
  根據業(yè)務(wù)特征選擇,設計合理的信息模型和鏈路,及時(shí)對信息進(jìn)行處理對網(wǎng)頁(yè)中的信息進(jìn)行解析,提取信息特征,并儲存起來(lái)需要獲取什么樣的信息信息以數據庫的形式存儲即可,沒(méi)有特定指標來(lái)要求儲存速度,txt或者json,提取關(guān)鍵字,把抽象內容鏈接到一起即可,最重要的是全量的準確性,保證準確性的一點(diǎn)是有足夠快的讀寫(xiě)速度。
  對于廣告業(yè)務(wù)而言,定制特征是非常重要的,比如有的廣告有固定的位置標識、pagerank、ctr特征等等,然后如果參與定制特征的平臺多,定制特征的粒度夠細的話(huà),本地數據庫的使用率會(huì )比較低對數據進(jìn)行分類(lèi)管理,類(lèi)似etl,用一定的算法和策略將所有的存儲到不同數據庫中去如果需要進(jìn)行分析,可以自己對業(yè)務(wù)、流程進(jìn)行重構,比如:消息隊列,過(guò)濾流程,負載均衡等等,將不同的業(yè)務(wù)特征,流程拆分成不同粒度的數據倉庫。 查看全部

  網(wǎng)站將用戶(hù)資料分門(mén)別類(lèi)的存儲在百度中
  c爬蟲(chóng)抓取網(wǎng)頁(yè)數據,可以得到我們想要的各種格式的數據用戶(hù)信息是可以作為數據有價(jià)值的獲取來(lái)源。比如一個(gè)網(wǎng)站將用戶(hù)資料分門(mén)別類(lèi)的存儲在百度中,那么用戶(hù)不僅可以接受百度的url信息,還可以查看百度收錄了哪些對自己有用的用戶(hù)信息。根據產(chǎn)品上線(xiàn)的數據質(zhì)量對用戶(hù)信息的價(jià)值進(jìn)行確定,在這里對用戶(hù)信息的價(jià)值分為初級價(jià)值、中級價(jià)值、高級價(jià)值三類(lèi)(根據產(chǎn)品和相關(guān)業(yè)務(wù)流程的特征進(jìn)行下劃分),初級價(jià)值比如xxx寶馬集團電子商務(wù)平臺用戶(hù)在購物車(chē)不只是購買(mǎi)自己想要的產(chǎn)品,還可以查看新推薦的商品、查看優(yōu)惠券的使用情況中級價(jià)值比如xxx寶馬集團電子商務(wù)平臺用戶(hù)在購物車(chē)不只是購買(mǎi)自己想要的產(chǎn)品,還可以查看優(yōu)惠券的使用情況高級價(jià)值比如某寶同城生活服務(wù)平臺的用戶(hù)在微信上獲取到完整圖片視頻等內容的用戶(hù)信息通過(guò)以上的分類(lèi),一般可以根據產(chǎn)品的定位將用戶(hù)信息劃分出來(lái),放到哪里去獲取都可以。info_data_name。
  根據業(yè)務(wù)特征選擇,設計合理的信息模型和鏈路,及時(shí)對信息進(jìn)行處理對網(wǎng)頁(yè)中的信息進(jìn)行解析,提取信息特征,并儲存起來(lái)需要獲取什么樣的信息信息以數據庫的形式存儲即可,沒(méi)有特定指標來(lái)要求儲存速度,txt或者json,提取關(guān)鍵字,把抽象內容鏈接到一起即可,最重要的是全量的準確性,保證準確性的一點(diǎn)是有足夠快的讀寫(xiě)速度。
  對于廣告業(yè)務(wù)而言,定制特征是非常重要的,比如有的廣告有固定的位置標識、pagerank、ctr特征等等,然后如果參與定制特征的平臺多,定制特征的粒度夠細的話(huà),本地數據庫的使用率會(huì )比較低對數據進(jìn)行分類(lèi)管理,類(lèi)似etl,用一定的算法和策略將所有的存儲到不同數據庫中去如果需要進(jìn)行分析,可以自己對業(yè)務(wù)、流程進(jìn)行重構,比如:消息隊列,過(guò)濾流程,負載均衡等等,將不同的業(yè)務(wù)特征,流程拆分成不同粒度的數據倉庫。

如何構建一個(gè)分布式爬蟲(chóng):實(shí)戰篇

網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 87 次瀏覽 ? 2022-06-05 05:09 ? 來(lái)自相關(guān)話(huà)題

  如何構建一個(gè)分布式爬蟲(chóng):實(shí)戰篇
  
  種子博主具體信息
  這里我們就看到了他的具體信息了。然后,我們看該頁(yè)面的 url 構造
  我直接 copy 的地址欄的 url。這樣做有啥不好的呢?對于老鳥(niǎo)來(lái)說(shuō),一下就看出來(lái)了,這樣做的話(huà),可能會(huì )導致信息不全,因為可能有些信息是動(dòng)態(tài)加載的。所以,我們需要通過(guò)抓包來(lái)判斷到底微博會(huì )通過(guò)該 url 返回所有信息,還是需要請求一些 ajax 鏈接才會(huì )返回一些關(guān)鍵信息。這里我就重復一下我的觀(guān)點(diǎn):抓包很重要,抓包很重要,抓包很重要!重要的事情說(shuō)三遍。關(guān)于抓包,我在模擬登陸微博和模擬登陸百度云都詳細講過(guò)了,這里我就不講了。
  我們抓完包,發(fā)現并沒(méi)有 ajax 請求。那么可以肯定請求前面的 url,會(huì )返回所有信息。我們通過(guò)點(diǎn)擊鼠標右鍵,查看網(wǎng)頁(yè)源代碼,然后ctrl a、ctrl c將所有的頁(yè)面源碼保存到本地,這里我命名為personinfo.html。我們用瀏覽器打開(kāi)該文件,發(fā)現我們需要的所有信息都在這段源碼中,這個(gè)工作和抓包判斷數據是否全面有些重復,但是在我看來(lái)是必不可少的,因為我們解析頁(yè)面數據的時(shí)候還可以用到這個(gè) html 文件,如果我們每次都通過(guò)網(wǎng)絡(luò )請求去解析內容的話(huà),那么可能賬號沒(méi)一會(huì )兒就會(huì )被封了(因為頻繁訪(fǎng)問(wèn)微博信息),所以我們需要把要解析的文件保存到本地。
  從上面分析中我們可以得知
  這個(gè) url 就是獲取用戶(hù)數據的 url。那么我們在只知道用戶(hù) id 的時(shí)候怎么構造它呢?我們可以多拿幾個(gè)用戶(hù) id 來(lái)做測試,看構造是否有規律,比如我這里以用戶(hù)名為網(wǎng)易云音樂(lè )的用戶(hù)做分析,發(fā)現它的用戶(hù)信息頁(yè)面構造如下
  這個(gè)就和上面那個(gè)不同了。但是我們仔細觀(guān)察,可以發(fā)現上面那個(gè)是個(gè)人用戶(hù),下面是企業(yè)微博用戶(hù)。我們嘗試一下把它們 url 格式都統一為第一種或者第二種的格式
  這樣會(huì )出現 404,那么統一成上面那種呢?
  這樣子的話(huà),它會(huì )被重定向到用戶(hù)主頁(yè),而不是用戶(hù)詳細資料頁(yè)。所以也就不對了。那么該以什么依據判斷何時(shí)用第一種 url 格式,何時(shí)用第二種 url 格式呢?我們多翻幾個(gè)用戶(hù),會(huì )發(fā)現除了100505之外,還有100305、100206等前綴,那么我猜想這個(gè)應該可以區分不同用戶(hù)。這個(gè)前綴在哪里可以得到呢?我們打開(kāi)我們剛保存的頁(yè)面源碼,搜索100505,可以發(fā)現
  
  domain
  微博應該是根據這個(gè)來(lái)區分不同用戶(hù)類(lèi)型的。這里大家可以自己也可以試試,看不同用戶(hù)的domain是否不同。為了數據能全面,我也是做了大量測試,發(fā)現個(gè)人用戶(hù)的 domain 是1005051,作家是100305,其他基本都是認證的企業(yè)號。前兩個(gè)個(gè)人信息的 url 構造就是
  后者的是
  弄清楚了個(gè)人信息 url 的構造方式,但是還有一個(gè)問(wèn)題。我們已知只有 uid 啊,沒(méi)有 domain 啊。如果是企業(yè)號,我們通過(guò)domain=100505會(huì )被重定向到主頁(yè),如果是作家等(domain=100305 或者 100306),也會(huì )被重定向主頁(yè)。我們在主頁(yè)把 domain 提取出來(lái),再請求一次,不就能拿到用戶(hù)詳細信息了嗎?
  關(guān)于如何構造獲取用戶(hù)信息的 url 的相關(guān)分析就到這里了。因為我們是在登錄的情況下進(jìn)行數據抓取的,可能在抓取的時(shí)候,某個(gè)賬號突然就被封了,或者由于網(wǎng)絡(luò )原因,某次請求失敗了,該如何處理?對于前者,我們需要判斷每次請求返回的內容是否符合預期,也就是看 response url 是否正常,看 response content 是否是 404 或者讓你驗證手機號等,對于后者,我們可以做一個(gè)簡(jiǎn)單的重試策略,大概代碼如下
  <p>@timeout_decorator
  def get_page(url, user_verify=True, need_login=True):
   ? ?"""
   ? ?:param url: 待抓取 url
   ? ?:param user_verify: 是否為可能出現驗證碼的頁(yè)面(ajax 連接不會(huì )出現驗證碼,如果是請求微博或者用戶(hù)信息可能出現驗證碼),否為抓取轉發(fā)的 ajax 連接
   ? ?:param need_login: 抓取頁(yè)面是否需要登錄,這樣做可以減小一些賬號的壓力
   ? ?:return: 返回請求的數據,如果出現 404 或者 403,或者是別的異常,都返回空字符串
   ? ?"""
   ? ?crawler.info('本次抓取的 url 為{url}'.format(url=url))
   ? ?count = 0<p> ? ?while count 查看全部

  如何構建一個(gè)分布式爬蟲(chóng):實(shí)戰篇
  
  種子博主具體信息
  這里我們就看到了他的具體信息了。然后,我們看該頁(yè)面的 url 構造
  我直接 copy 的地址欄的 url。這樣做有啥不好的呢?對于老鳥(niǎo)來(lái)說(shuō),一下就看出來(lái)了,這樣做的話(huà),可能會(huì )導致信息不全,因為可能有些信息是動(dòng)態(tài)加載的。所以,我們需要通過(guò)抓包來(lái)判斷到底微博會(huì )通過(guò)該 url 返回所有信息,還是需要請求一些 ajax 鏈接才會(huì )返回一些關(guān)鍵信息。這里我就重復一下我的觀(guān)點(diǎn):抓包很重要,抓包很重要,抓包很重要!重要的事情說(shuō)三遍。關(guān)于抓包,我在模擬登陸微博和模擬登陸百度云都詳細講過(guò)了,這里我就不講了。
  我們抓完包,發(fā)現并沒(méi)有 ajax 請求。那么可以肯定請求前面的 url,會(huì )返回所有信息。我們通過(guò)點(diǎn)擊鼠標右鍵,查看網(wǎng)頁(yè)源代碼,然后ctrl a、ctrl c將所有的頁(yè)面源碼保存到本地,這里我命名為personinfo.html。我們用瀏覽器打開(kāi)該文件,發(fā)現我們需要的所有信息都在這段源碼中,這個(gè)工作和抓包判斷數據是否全面有些重復,但是在我看來(lái)是必不可少的,因為我們解析頁(yè)面數據的時(shí)候還可以用到這個(gè) html 文件,如果我們每次都通過(guò)網(wǎng)絡(luò )請求去解析內容的話(huà),那么可能賬號沒(méi)一會(huì )兒就會(huì )被封了(因為頻繁訪(fǎng)問(wèn)微博信息),所以我們需要把要解析的文件保存到本地。
  從上面分析中我們可以得知
  這個(gè) url 就是獲取用戶(hù)數據的 url。那么我們在只知道用戶(hù) id 的時(shí)候怎么構造它呢?我們可以多拿幾個(gè)用戶(hù) id 來(lái)做測試,看構造是否有規律,比如我這里以用戶(hù)名為網(wǎng)易云音樂(lè )的用戶(hù)做分析,發(fā)現它的用戶(hù)信息頁(yè)面構造如下
  這個(gè)就和上面那個(gè)不同了。但是我們仔細觀(guān)察,可以發(fā)現上面那個(gè)是個(gè)人用戶(hù),下面是企業(yè)微博用戶(hù)。我們嘗試一下把它們 url 格式都統一為第一種或者第二種的格式
  這樣會(huì )出現 404,那么統一成上面那種呢?
  這樣子的話(huà),它會(huì )被重定向到用戶(hù)主頁(yè),而不是用戶(hù)詳細資料頁(yè)。所以也就不對了。那么該以什么依據判斷何時(shí)用第一種 url 格式,何時(shí)用第二種 url 格式呢?我們多翻幾個(gè)用戶(hù),會(huì )發(fā)現除了100505之外,還有100305、100206等前綴,那么我猜想這個(gè)應該可以區分不同用戶(hù)。這個(gè)前綴在哪里可以得到呢?我們打開(kāi)我們剛保存的頁(yè)面源碼,搜索100505,可以發(fā)現
  
  domain
  微博應該是根據這個(gè)來(lái)區分不同用戶(hù)類(lèi)型的。這里大家可以自己也可以試試,看不同用戶(hù)的domain是否不同。為了數據能全面,我也是做了大量測試,發(fā)現個(gè)人用戶(hù)的 domain 是1005051,作家是100305,其他基本都是認證的企業(yè)號。前兩個(gè)個(gè)人信息的 url 構造就是
  后者的是
  弄清楚了個(gè)人信息 url 的構造方式,但是還有一個(gè)問(wèn)題。我們已知只有 uid 啊,沒(méi)有 domain 啊。如果是企業(yè)號,我們通過(guò)domain=100505會(huì )被重定向到主頁(yè),如果是作家等(domain=100305 或者 100306),也會(huì )被重定向主頁(yè)。我們在主頁(yè)把 domain 提取出來(lái),再請求一次,不就能拿到用戶(hù)詳細信息了嗎?
  關(guān)于如何構造獲取用戶(hù)信息的 url 的相關(guān)分析就到這里了。因為我們是在登錄的情況下進(jìn)行數據抓取的,可能在抓取的時(shí)候,某個(gè)賬號突然就被封了,或者由于網(wǎng)絡(luò )原因,某次請求失敗了,該如何處理?對于前者,我們需要判斷每次請求返回的內容是否符合預期,也就是看 response url 是否正常,看 response content 是否是 404 或者讓你驗證手機號等,對于后者,我們可以做一個(gè)簡(jiǎn)單的重試策略,大概代碼如下
  <p>@timeout_decorator
  def get_page(url, user_verify=True, need_login=True):
   ? ?"""
   ? ?:param url: 待抓取 url
   ? ?:param user_verify: 是否為可能出現驗證碼的頁(yè)面(ajax 連接不會(huì )出現驗證碼,如果是請求微博或者用戶(hù)信息可能出現驗證碼),否為抓取轉發(fā)的 ajax 連接
   ? ?:param need_login: 抓取頁(yè)面是否需要登錄,這樣做可以減小一些賬號的壓力
   ? ?:return: 返回請求的數據,如果出現 404 或者 403,或者是別的異常,都返回空字符串
   ? ?"""
   ? ?crawler.info('本次抓取的 url 為{url}'.format(url=url))
   ? ?count = 0<p> ? ?while count

微博各種數據抓取思路與難點(diǎn)總結——小白爬蟲(chóng)進(jìn)階(1)

網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 312 次瀏覽 ? 2022-06-04 11:43 ? 來(lái)自相關(guān)話(huà)題

  微博各種數據抓取思路與難點(diǎn)總結——小白爬蟲(chóng)進(jìn)階(1)
  最近后臺留言異常的多,還有不少催更,看來(lái)各位小伙伴都是寒假稍歇后就立刻又投身于禿頭事業(yè)了,讓大家久等了,2022一起繼續加油。
  在之前的小白爬蟲(chóng)實(shí)戰(1)里,我們以馬云的微博為例初步演示了如何爬取一個(gè)微博用戶(hù)的所有微博文本(回顧戳這→),最近有很多同學(xué)后臺問(wèn)起詳細的思路,也有小伙伴對如何進(jìn)一步抓取微博轉發(fā)、評論、點(diǎn)贊數據甚至配圖的抓取方法提出了疑問(wèn)。
  針對以上問(wèn)題,本篇對微博數據的抓取做一個(gè)專(zhuān)門(mén)的梳理與總結,本文分為以下三部分:
  1、抓取URL的構造
  2、微博文本、轉發(fā)、評論、點(diǎn)贊數據的抓取與保存
  3、微博圖片的抓取與保存
  經(jīng)過(guò)這三部分的梳理,相信各位能對有關(guān)微博的抓取有更進(jìn)一步的了解,無(wú)論是抓取話(huà)題還是抓取熱搜,萬(wàn)變不離其宗,只需要按需求在本文基礎上進(jìn)行些改動(dòng)即可。
  注意:本篇是基于爬蟲(chóng)實(shí)戰(1)等前面相關(guān)內容之上的總結,一些基礎的內容便不再贅述,有需要的小伙伴可以回顧之前的相關(guān)內容:
  下面我們開(kāi)始這三部分——
  1
  抓取URL的構造
  在爬蟲(chóng)實(shí)戰(1)中,我們用檢查中的XHR過(guò)濾器找到了獲取數據所需的鏈接地址,這個(gè)鏈接地址有一大坨,第一頁(yè)鏈接與之后鏈接的差距就在于第一頁(yè)的鏈接尾部沒(méi)有since_id參數,這次我們進(jìn)一步對這一大坨鏈接進(jìn)行分解分析。
  %3D1%26q%3D%E9%A9%AC%E4%BA%91&type=uid&value=2145291155&containerid=91155&since_id=44903
  上面即是馬云微博數據的第二頁(yè)鏈接,若是把鏈接末尾的since_id刪去即為第一頁(yè)鏈接。在這么一大坨鏈接里,最終是靠著(zhù)末尾since_id的變化實(shí)現獲取下一頁(yè)數據的,在爬蟲(chóng)實(shí)戰(1)中,我們是直接將這一大坨復制粘貼到代碼中,而為since_id專(zhuān)門(mén)設了一個(gè)變量,這次我們再進(jìn)一步將這個(gè)鏈接拆分看看。
  實(shí)際上,這么一大坨連接中,只有
  為基礎連接,后面的一長(cháng)串都是各種各樣的參數組合,比如uid、t、luicode等等,而這一長(cháng)串由百分號、數字和字母構成的部分我們可以通過(guò)解碼得到它的實(shí)際文本
  %3D1%26q%3D%E9%A9%AC%E4%BA%91
  我們可以在中對上面這行奇奇怪怪的內容進(jìn)行URL解碼:
  
  解碼之后:
  
  通過(guò)解碼可知,%3D1%26q%3D%E9%A9%AC%E4%BA%91的實(shí)際文本含義為“=1&q=馬云”,據此可得這一大串鏈接的真實(shí)表達為:
  =1&q=馬云&type=uid&value=2145291155&containerid=91155&since_id=44903
  也就是一個(gè)基礎鏈接加上各種必要參數的組合。在Python中我們可以通過(guò)調用urlencode()方法將構造的參數字典與基礎連接組合生成完整鏈接,據此我們首先構造一個(gè)生成完整請求鏈接的函數:
  from urllib.parse import urlencode
  def generate_url(since_id='0'):
  """
  構造完整鏈接 """
  base_url = ''
  params = {
  'uid': '2145291155',
  't': '0',
  'luicode': '10000011',
  'lfid': '100103type=1',
  'q': '馬云',
  'type': 'uid',
  'value': '2145291155',
  'containerid': '91155',
  'since_id': since_id
  }
  url = base_url + urlencode(params)
  return url
  generate_url
  因為只有since_id是變化的,而第一頁(yè)鏈接又不含since_id,所以這里設一個(gè)since_id默認值為0的變量。
  到此,抓取所需的URL便構造完成了。
  2
  微博文本、轉發(fā)、評論、點(diǎn)贊數據的抓取與保存
  在爬蟲(chóng)實(shí)戰(1)中說(shuō)到,若用火狐瀏覽器訪(fǎng)問(wèn)我們所構造的URL,可以得到結構化的json數據,而我們所需要抓取的目標就在這些json數據之中。微博文本在mblog的text下,而轉發(fā)、評論、點(diǎn)贊數據也異曲同工:
  數據位置
  數據含義
  mblog→reposts_count
  點(diǎn)贊數
  mblog→comments_count 查看全部

  微博各種數據抓取思路與難點(diǎn)總結——小白爬蟲(chóng)進(jìn)階(1)
  最近后臺留言異常的多,還有不少催更,看來(lái)各位小伙伴都是寒假稍歇后就立刻又投身于禿頭事業(yè)了,讓大家久等了,2022一起繼續加油。
  在之前的小白爬蟲(chóng)實(shí)戰(1)里,我們以馬云的微博為例初步演示了如何爬取一個(gè)微博用戶(hù)的所有微博文本(回顧戳這→),最近有很多同學(xué)后臺問(wèn)起詳細的思路,也有小伙伴對如何進(jìn)一步抓取微博轉發(fā)、評論、點(diǎn)贊數據甚至配圖的抓取方法提出了疑問(wèn)。
  針對以上問(wèn)題,本篇對微博數據的抓取做一個(gè)專(zhuān)門(mén)的梳理與總結,本文分為以下三部分:
  1、抓取URL的構造
  2、微博文本、轉發(fā)、評論、點(diǎn)贊數據的抓取與保存
  3、微博圖片的抓取與保存
  經(jīng)過(guò)這三部分的梳理,相信各位能對有關(guān)微博的抓取有更進(jìn)一步的了解,無(wú)論是抓取話(huà)題還是抓取熱搜,萬(wàn)變不離其宗,只需要按需求在本文基礎上進(jìn)行些改動(dòng)即可。
  注意:本篇是基于爬蟲(chóng)實(shí)戰(1)等前面相關(guān)內容之上的總結,一些基礎的內容便不再贅述,有需要的小伙伴可以回顧之前的相關(guān)內容:
  下面我們開(kāi)始這三部分——
  1
  抓取URL的構造
  在爬蟲(chóng)實(shí)戰(1)中,我們用檢查中的XHR過(guò)濾器找到了獲取數據所需的鏈接地址,這個(gè)鏈接地址有一大坨,第一頁(yè)鏈接與之后鏈接的差距就在于第一頁(yè)的鏈接尾部沒(méi)有since_id參數,這次我們進(jìn)一步對這一大坨鏈接進(jìn)行分解分析。
  %3D1%26q%3D%E9%A9%AC%E4%BA%91&type=uid&value=2145291155&containerid=91155&since_id=44903
  上面即是馬云微博數據的第二頁(yè)鏈接,若是把鏈接末尾的since_id刪去即為第一頁(yè)鏈接。在這么一大坨鏈接里,最終是靠著(zhù)末尾since_id的變化實(shí)現獲取下一頁(yè)數據的,在爬蟲(chóng)實(shí)戰(1)中,我們是直接將這一大坨復制粘貼到代碼中,而為since_id專(zhuān)門(mén)設了一個(gè)變量,這次我們再進(jìn)一步將這個(gè)鏈接拆分看看。
  實(shí)際上,這么一大坨連接中,只有
  為基礎連接,后面的一長(cháng)串都是各種各樣的參數組合,比如uid、t、luicode等等,而這一長(cháng)串由百分號、數字和字母構成的部分我們可以通過(guò)解碼得到它的實(shí)際文本
  %3D1%26q%3D%E9%A9%AC%E4%BA%91
  我們可以在中對上面這行奇奇怪怪的內容進(jìn)行URL解碼:
  
  解碼之后:
  
  通過(guò)解碼可知,%3D1%26q%3D%E9%A9%AC%E4%BA%91的實(shí)際文本含義為“=1&q=馬云”,據此可得這一大串鏈接的真實(shí)表達為:
  =1&q=馬云&type=uid&value=2145291155&containerid=91155&since_id=44903
  也就是一個(gè)基礎鏈接加上各種必要參數的組合。在Python中我們可以通過(guò)調用urlencode()方法將構造的參數字典與基礎連接組合生成完整鏈接,據此我們首先構造一個(gè)生成完整請求鏈接的函數:
  from urllib.parse import urlencode
  def generate_url(since_id='0'):
  """
  構造完整鏈接 """
  base_url = ''
  params = {
  'uid': '2145291155',
  't': '0',
  'luicode': '10000011',
  'lfid': '100103type=1',
  'q': '馬云',
  'type': 'uid',
  'value': '2145291155',
  'containerid': '91155',
  'since_id': since_id
  }
  url = base_url + urlencode(params)
  return url
  generate_url
  因為只有since_id是變化的,而第一頁(yè)鏈接又不含since_id,所以這里設一個(gè)since_id默認值為0的變量。
  到此,抓取所需的URL便構造完成了。
  2
  微博文本、轉發(fā)、評論、點(diǎn)贊數據的抓取與保存
  在爬蟲(chóng)實(shí)戰(1)中說(shuō)到,若用火狐瀏覽器訪(fǎng)問(wèn)我們所構造的URL,可以得到結構化的json數據,而我們所需要抓取的目標就在這些json數據之中。微博文本在mblog的text下,而轉發(fā)、評論、點(diǎn)贊數據也異曲同工:
  數據位置
  數據含義
  mblog→reposts_count
  點(diǎn)贊數
  mblog→comments_count

Python爬蟲(chóng)入門(mén),8個(gè)常用爬蟲(chóng)技巧盤(pán)點(diǎn)

網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 139 次瀏覽 ? 2022-06-04 06:47 ? 來(lái)自相關(guān)話(huà)題

  Python爬蟲(chóng)入門(mén),8個(gè)常用爬蟲(chóng)技巧盤(pán)點(diǎn)
  
  
  5、頁(yè)面解析
  對于頁(yè)面解析最強大的當然是正則表達式,
  這個(gè)對于不同網(wǎng)站不同的使用者都不一樣,就不用過(guò)多的說(shuō)明。
  
  其次就是解析庫了,常用的有兩個(gè)lxml和BeautifulSoup。
  對于這兩個(gè)庫,我的評價(jià)是,
  都是HTML/XML的處理庫,Beautifulsoup純python實(shí)現,效率低,
  但是功能實(shí)用,比如能用通過(guò)結果搜索獲得某個(gè)HTML節點(diǎn)的源碼;
  lxmlC語(yǔ)言編碼,高效,支持Xpath。
  
  6.驗證碼的處理
  碰到驗證碼咋辦?
  這里分兩種情況處理:
  google那種驗證碼,沒(méi)辦法。
  簡(jiǎn)單的驗證碼:字符個(gè)數有限,只使用了簡(jiǎn)單的平移或旋轉加噪音而沒(méi)有扭曲的,
  這種還是有可能可以處理的,一般思路是旋轉的轉回來(lái),噪音去掉,
  然后劃分單個(gè)字符,劃分好了以后再通過(guò)特征提取的方法(例如PCA)降維并生成特征庫,
  然后把驗證碼和特征庫進(jìn)行比較。
  這個(gè)比較復雜,這里就不展開(kāi)了,
  具體做法請弄本相關(guān)教科書(shū)好好研究一下。
  
  7. gzip/deflate支持
  現在的網(wǎng)頁(yè)普遍支持gzip壓縮,這往往可以解決大量傳輸時(shí)間,
  以VeryCD的主頁(yè)為例,未壓縮版本247K,壓縮了以后45K,為原來(lái)的1/5。
  這就意味著(zhù)抓取速度會(huì )快5倍。
  然而python的urllib/urllib2默認都不支持壓縮
  要返回壓縮格式,必須在request的header里面寫(xiě)明’accept-encoding’,
  然后讀取response后更要檢查header查看是否有’content-encoding’一項來(lái)判斷是否需要解碼,很繁瑣瑣碎。
  如何讓urllib2自動(dòng)支持gzip, defalte呢?
  其實(shí)可以繼承BaseHanlder類(lèi),
  然后build_opener的方式來(lái)處理:
  
  
  8、多線(xiàn)程并發(fā)抓取
  單線(xiàn)程太慢的話(huà),就需要多線(xiàn)程了,
  這里給個(gè)簡(jiǎn)單的線(xiàn)程池模板 這個(gè)程序只是簡(jiǎn)單地打印了1-10,
  但是可以看出是并發(fā)的。
  雖然說(shuō)Python的多線(xiàn)程很雞肋
  但是對于爬蟲(chóng)這種網(wǎng)絡(luò )頻繁型,
  還是能一定程度提高效率的。
  
  
  9. 總結
  閱讀Python編寫(xiě)的代碼感覺(jué)像在閱讀英語(yǔ)一樣,這讓使用者可以專(zhuān)注于解決問(wèn)題而不是去搞明白語(yǔ)言本身。
  Python雖然是基于C語(yǔ)言編寫(xiě),但是摒棄了C中復雜的指針,使其變得簡(jiǎn)明易學(xué)。
  并且作為開(kāi)源軟件,Python允許對代碼進(jìn)行閱讀,拷貝甚至改進(jìn)。
  這些性能成就了Python的高效率,有“人生苦短,我用Python”之說(shuō),是一種十分精彩又強大的語(yǔ)言。
  總而言之,開(kāi)始學(xué)Python一定要注意這4點(diǎn):
  1.代碼規范,這本身就是一個(gè)非常好的習慣,如果開(kāi)始不養好好的代碼規劃,以后會(huì )很痛苦。
  2.多動(dòng)手,少看書(shū),很多人學(xué)Python就一味的看書(shū),這不是學(xué)數學(xué)物理,你看例題可能就會(huì )了,學(xué)習Python主要是學(xué)習編程思想。
  3.勤練習,學(xué)完新的知識點(diǎn),一定要記得如何去應用,不然學(xué)完就會(huì )忘,學(xué)我們這行主要都是實(shí)際操作。
  4.學(xué)習要有效率,如果自己都覺(jué)得效率非常低,那就停不停,找一下原因,去問(wèn)問(wèn)過(guò)來(lái)人這是為什么。
  推薦↓↓↓
  
  長(cháng)
  按
  關(guān)
  注
  【】都在這里!
  涵蓋:程序員大咖、源碼共讀、程序員共讀、數據結構與算法、黑客技術(shù)和網(wǎng)絡(luò )安全、大數據科技、編程前端、Java、Python、Web編程開(kāi)發(fā)、Android、iOS開(kāi)發(fā)、Linux、數據庫研發(fā)、幽默程序員等。 查看全部

  Python爬蟲(chóng)入門(mén),8個(gè)常用爬蟲(chóng)技巧盤(pán)點(diǎn)
  
  
  5、頁(yè)面解析
  對于頁(yè)面解析最強大的當然是正則表達式,
  這個(gè)對于不同網(wǎng)站不同的使用者都不一樣,就不用過(guò)多的說(shuō)明。
  
  其次就是解析庫了,常用的有兩個(gè)lxml和BeautifulSoup。
  對于這兩個(gè)庫,我的評價(jià)是,
  都是HTML/XML的處理庫,Beautifulsoup純python實(shí)現,效率低,
  但是功能實(shí)用,比如能用通過(guò)結果搜索獲得某個(gè)HTML節點(diǎn)的源碼;
  lxmlC語(yǔ)言編碼,高效,支持Xpath。
  
  6.驗證碼的處理
  碰到驗證碼咋辦?
  這里分兩種情況處理:
  google那種驗證碼,沒(méi)辦法。
  簡(jiǎn)單的驗證碼:字符個(gè)數有限,只使用了簡(jiǎn)單的平移或旋轉加噪音而沒(méi)有扭曲的,
  這種還是有可能可以處理的,一般思路是旋轉的轉回來(lái),噪音去掉,
  然后劃分單個(gè)字符,劃分好了以后再通過(guò)特征提取的方法(例如PCA)降維并生成特征庫,
  然后把驗證碼和特征庫進(jìn)行比較。
  這個(gè)比較復雜,這里就不展開(kāi)了,
  具體做法請弄本相關(guān)教科書(shū)好好研究一下。
  
  7. gzip/deflate支持
  現在的網(wǎng)頁(yè)普遍支持gzip壓縮,這往往可以解決大量傳輸時(shí)間,
  以VeryCD的主頁(yè)為例,未壓縮版本247K,壓縮了以后45K,為原來(lái)的1/5。
  這就意味著(zhù)抓取速度會(huì )快5倍。
  然而python的urllib/urllib2默認都不支持壓縮
  要返回壓縮格式,必須在request的header里面寫(xiě)明’accept-encoding’,
  然后讀取response后更要檢查header查看是否有’content-encoding’一項來(lái)判斷是否需要解碼,很繁瑣瑣碎。
  如何讓urllib2自動(dòng)支持gzip, defalte呢?
  其實(shí)可以繼承BaseHanlder類(lèi),
  然后build_opener的方式來(lái)處理:
  
  
  8、多線(xiàn)程并發(fā)抓取
  單線(xiàn)程太慢的話(huà),就需要多線(xiàn)程了,
  這里給個(gè)簡(jiǎn)單的線(xiàn)程池模板 這個(gè)程序只是簡(jiǎn)單地打印了1-10,
  但是可以看出是并發(fā)的。
  雖然說(shuō)Python的多線(xiàn)程很雞肋
  但是對于爬蟲(chóng)這種網(wǎng)絡(luò )頻繁型,
  還是能一定程度提高效率的。
  
  
  9. 總結
  閱讀Python編寫(xiě)的代碼感覺(jué)像在閱讀英語(yǔ)一樣,這讓使用者可以專(zhuān)注于解決問(wèn)題而不是去搞明白語(yǔ)言本身。
  Python雖然是基于C語(yǔ)言編寫(xiě),但是摒棄了C中復雜的指針,使其變得簡(jiǎn)明易學(xué)。
  并且作為開(kāi)源軟件,Python允許對代碼進(jìn)行閱讀,拷貝甚至改進(jìn)。
  這些性能成就了Python的高效率,有“人生苦短,我用Python”之說(shuō),是一種十分精彩又強大的語(yǔ)言。
  總而言之,開(kāi)始學(xué)Python一定要注意這4點(diǎn):
  1.代碼規范,這本身就是一個(gè)非常好的習慣,如果開(kāi)始不養好好的代碼規劃,以后會(huì )很痛苦。
  2.多動(dòng)手,少看書(shū),很多人學(xué)Python就一味的看書(shū),這不是學(xué)數學(xué)物理,你看例題可能就會(huì )了,學(xué)習Python主要是學(xué)習編程思想。
  3.勤練習,學(xué)完新的知識點(diǎn),一定要記得如何去應用,不然學(xué)完就會(huì )忘,學(xué)我們這行主要都是實(shí)際操作。
  4.學(xué)習要有效率,如果自己都覺(jué)得效率非常低,那就停不停,找一下原因,去問(wèn)問(wèn)過(guò)來(lái)人這是為什么。
  推薦↓↓↓
  
  長(cháng)
  按
  關(guān)
  注
  【】都在這里!
  涵蓋:程序員大咖、源碼共讀、程序員共讀、數據結構與算法、黑客技術(shù)和網(wǎng)絡(luò )安全、大數據科技、編程前端、Java、Python、Web編程開(kāi)發(fā)、Android、iOS開(kāi)發(fā)、Linux、數據庫研發(fā)、幽默程序員等。

實(shí)戰演練——愛(ài)嬰醫院中莆田系醫院數據分析(一)

網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 72 次瀏覽 ? 2022-06-04 06:44 ? 來(lái)自相關(guān)話(huà)題

  實(shí)戰演練——愛(ài)嬰醫院中莆田系醫院數據分析(一)
  技術(shù)總編:張 邯
  爬蟲(chóng)俱樂(lè )部將于2020年1月5日至11日在湖北武漢舉行為期一周的Stata編程技術(shù)定制培訓,此次采取初級班和高級班分批次培訓。課程通過(guò)案例教學(xué)模式,旨在幫助大家在短期內掌握Stata軟件編程、金融計量知識和實(shí)證分析方法,使大家熟悉Stata核心的爬蟲(chóng)技術(shù),以及Stata與其他軟件交互的高端技術(shù)。目前正在火熱招生中~詳細培訓大綱及報名方式,請點(diǎn)擊《》或點(diǎn)擊文末閱讀原文呦~
  自2015年黨的十八屆五中全會(huì )開(kāi)放二孩政策實(shí)施以來(lái),越來(lái)越多天真可愛(ài)的孩子在這個(gè)中國特色社會(huì )新時(shí)代呱呱墜地。但是,“7歲男童墜樓身亡”、“幼兒園虐童”等新聞時(shí)時(shí)刻刻提醒我們,要全方位、多角度對這些祖國未來(lái)的建設者進(jìn)行保護。當然,保護他們要從保護他們的出生做起。
  開(kāi)放二孩政策實(shí)施后,國家婦幼健康司響應號召,在2015年11月公布了《國家衛生計生委關(guān)于公布全國愛(ài)嬰醫院名單的公告》,旨在“不斷改善產(chǎn)科兒科服務(wù)質(zhì)量,逐步提高母乳喂養率,降低非醫學(xué)指征剖宮產(chǎn)率,保障調整完善生育政策順利實(shí)施”。(網(wǎng)址:)
  
  當小編打開(kāi)這些名單瀏覽的時(shí)候,這里面有些醫院的名字竟形同“莆田系醫院”,為了識別這其中為數不多的“莆田系醫院”,小編決定使用Python來(lái)一探究竟。
  由于篇幅限制,本篇重點(diǎn)介紹如何獲取所需的.docx文件,下篇重點(diǎn)介紹如何提取.docx文件中的表格信息并與已有的數據庫進(jìn)行匹配。
  本文涉及的技術(shù)要點(diǎn):
 ?、佾@取公告附件②獲取word文件中的表格信息③ 將.doc文件轉換為.docx文件
  一、使用網(wǎng)絡(luò )爬蟲(chóng)技術(shù)抓取愛(ài)嬰醫院名單
  1、創(chuàng )建文件夾并改變缺省路徑
  導入Python的os標準庫,判斷是否存在我們需要的文件夾,如果不存在則創(chuàng )建,將新創(chuàng )建的文件夾作為缺省路徑,程序如下:
  import osif not os.path.exists(r"D:/愛(ài)嬰醫院"): os.mkdir(r"D:/愛(ài)嬰醫院")os.chdir(r"D:/愛(ài)嬰醫院")
  2、導入requests標準庫和re標準庫抓取WORD文件
  requests和re庫的使用在爬蟲(chóng)俱樂(lè )部往期推文《》和《》中已詳細介紹。首先,導入標準庫,構造headers,并抓取網(wǎng)頁(yè)源代碼,程序如下:
  import requestsimport reheaders = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36', 'Host': 'www.nhc.gov.cn', 'Referer': 'http://www.nhc.gov.cn/fys/s7906/201511/e5650712dbcd449e9d2e01129a698b9c.shtml', 'Cookie': 'FSSBBIl1UgzbN7N80S=IIRSdCvBkEfkV.B2JY9RYhaETIf1BuxVpvEkSoPAJNFoG0jDMD0Ful2W19MSwjQT; yfx_c_g_u_id_10006654=_ck19080819145412635280045357765; _gscu_2059686908=65262894vmq4k445; yfx_f_l_v_t_10006654=f_t_1565262894262__r_t_1566175543011__v_t_1566175543011__r_c_2; _gscbrs_2059686908=1; yfx_mr_10006654=%3A%3Amarket_type_free_search%3A%3A%3A%3Abaidu%3A%3A%3A%3A%3A%3A%3A%3Awww.baidu.com%3A%3A%3A%3Apmf_from_free_search; yfx_mr_f_10006654=%3A%3Amarket_type_free_search%3A%3A%3A%3Abaidu%3A%3A%3A%3A%3A%3A%3A%3Awww.baidu.com%3A%3A%3A%3Apmf_from_free_search; yfx_key_10006654=; security_session_verify=27b11d4bf074ab3d320a0abb616f351f; banggoo.nuva.cookie=1|XVn2H|XVnyw; FSSBBIl1UgzbN7N80T=3r.zHapFkhZJ9axZJ1O.c4IFBETpXD7V97EmMfYcNch3_sxH_Btj9.wKGGKtWVFD4JTZMrYQH4I_cyZS.TVLlnmOlnWWQYX1KSl_0JUVaqTV5NSoiWZ2yDjJtV0RKxM3mtcPiY3b6wUjzJcPd4Z3u2ns76vO.lskE3joV_Gsk37Wj7hd7a.qnhOQazlKQrIZW8zGEH.8cPkVTO626ptQpnK35KuJcjrdVKTUEIq7bS81Ba.CKHUaDxNyxwsVMVkUiIGOGGD9sL3MFcik_S05TQa174cT51WxsHLZ_d4FFWBq3LZzaqvAM.ybpZ0vwVcPApVOILVksCY4w7adafW4.rYWCq_.1437bDWfT7f6FtSnb9G' }html = requests.get("http://www.nhc.gov.cn/fys/s790 ... 6quot;)text = html.content.decode('utf-8')#先抓取字節碼再轉換為字符串,避免亂碼。print(text)
  結果如下:
  
  可見(jiàn),我們使用requests庫成功將網(wǎng)頁(yè)源代碼抓取下來(lái)。源代碼中存有WORD文件的URL,我們將其中一個(gè)復制下來(lái)進(jìn)行分析:
  <A target=_blankhref="/ewebeditor/uploadfile/2015/11/20151117160507435.doc">1.北京市愛(ài)嬰醫院名單.doc</A></P>
  其中的URL可以使用正則表達式A[ ]target.*?href="(.*?)"進(jìn)行提取,我們提取出32個(gè)WORD文件的URL并放在一個(gè)列表中,程序如下:
  urls = re.findall('A[ ]target.*?href="(.*?)"', text, re.S)print(urls)c_url = []for url in urls: ur = "http://www.nhc.gov.cn" + url c_url.append(ur)print(c_url)
  結果如下:
  
  最后,使用requests庫,根據列表中的URL下載WORD文件,程序如下:
  for nu,c in enumerate(c_url): co = requests.get(c) #獲取文件 suffix = os.path.splitext(c)[1] #分離文件名與文件后綴(.doc或.docx) filename = str(nu)+suffix #用序號給文件命名,生成新的文件名 with open(filename,'wb') as f:????????f.write(co.content)
  此時(shí),在缺省路徑中就出現了我們需要的WORD文件,結果如下:
  
  二、將.doc文件轉換為.docx文件
  由于Python無(wú)法讀取.doc文件,因此我們先將.doc轉換為.docx。
  導入標準庫并定義轉化函數:
  from win32com import client# win32com.client可以直接調用VBA的庫,對Word、Excel進(jìn)行操作def doc_to_docx(path): if os.path.splitext(path)[1] == ".doc": word = client.Dispatch('Word.Application') #打開(kāi)word。 doc = word.Documents.Open(path) # 打開(kāi)目標路徑下的文件 doc.SaveAs(os.path.splitext(path)[0]+".docx", 16) doc.Close()????????word.Quit()???????#退出
  上述函數需要傳入文件名。接下來(lái)定義一個(gè)函數,用來(lái)將指定文件夾中的所有文件存入歷列表中:
  def find_file(path, ext, file_list=[]): dir = os.listdir(path) for i in dir: i = os.path.join(path, i) #拼接文件路徑, 將多個(gè)路徑組合后返回 if os.path.isdir(i): #用于判斷某一對象是否為目錄 find_file(i, ext, file_list) else: if ext == os.path.splitext(i)[1]: file_list.append(i)????return?file_list
  調用上述函數進(jìn)行轉換并刪掉.doc文件,程序如下:
  dir_path = "D:\愛(ài)嬰醫院" #批量轉換文件夾ext = ".doc"file_list = find_file(dir_path, ext)for file in file_list: doc_to_docx(file)#刪掉.doc文件files = os.listdir()print(files)for c in files: if os.path.splitext(c)[1] == ".doc":????????os.remove(c)
  結果如下:
  
  此時(shí),文件就全部轉換為了.docx文件。
  
  對我們的推文累計打賞超過(guò)1000元,我們即可給您開(kāi)具發(fā)票,發(fā)票類(lèi)別為“咨詢(xún)費”。用心做事,不負您的支持!
  往期推文推薦
  關(guān)于我們
  微信公眾號“Stata and Python數據分析”分享實(shí)用的stata、python等軟件的數據處理知識,歡迎轉載、打賞。我們是由李春濤教授領(lǐng)導下的研究生及本科生組成的大數據處理和分析團隊。
  此外,歡迎大家踴躍投稿,介紹一些關(guān)于stata和python的數據處理和分析技巧。投稿郵箱:投稿要求:
  1)必須原創(chuàng ),禁止抄襲;
  2)必須準確,詳細,有例子,有截圖;
  注意事項:
  1)所有投稿都會(huì )經(jīng)過(guò)本公眾號運營(yíng)團隊成員的審核,審核通過(guò)才可錄用,一經(jīng)錄用,會(huì )在該推文里為作者署名,并有賞金分成。
  2)郵件請注明投稿,郵件名稱(chēng)為“投稿+推文名稱(chēng)”。
  3)應廣大讀者要求,現開(kāi)通有償問(wèn)答服務(wù),如果大家遇到有關(guān)數據處理、分析等問(wèn)題,可以在公眾號中提出,只需支付少量賞金,我們會(huì )在后期的推文里給予解答。
   查看全部

  實(shí)戰演練——愛(ài)嬰醫院中莆田系醫院數據分析(一)
  技術(shù)總編:張 邯
  爬蟲(chóng)俱樂(lè )部將于2020年1月5日至11日在湖北武漢舉行為期一周的Stata編程技術(shù)定制培訓,此次采取初級班和高級班分批次培訓。課程通過(guò)案例教學(xué)模式,旨在幫助大家在短期內掌握Stata軟件編程、金融計量知識和實(shí)證分析方法,使大家熟悉Stata核心的爬蟲(chóng)技術(shù),以及Stata與其他軟件交互的高端技術(shù)。目前正在火熱招生中~詳細培訓大綱及報名方式,請點(diǎn)擊《》或點(diǎn)擊文末閱讀原文呦~
  自2015年黨的十八屆五中全會(huì )開(kāi)放二孩政策實(shí)施以來(lái),越來(lái)越多天真可愛(ài)的孩子在這個(gè)中國特色社會(huì )新時(shí)代呱呱墜地。但是,“7歲男童墜樓身亡”、“幼兒園虐童”等新聞時(shí)時(shí)刻刻提醒我們,要全方位、多角度對這些祖國未來(lái)的建設者進(jìn)行保護。當然,保護他們要從保護他們的出生做起。
  開(kāi)放二孩政策實(shí)施后,國家婦幼健康司響應號召,在2015年11月公布了《國家衛生計生委關(guān)于公布全國愛(ài)嬰醫院名單的公告》,旨在“不斷改善產(chǎn)科兒科服務(wù)質(zhì)量,逐步提高母乳喂養率,降低非醫學(xué)指征剖宮產(chǎn)率,保障調整完善生育政策順利實(shí)施”。(網(wǎng)址:)
  
  當小編打開(kāi)這些名單瀏覽的時(shí)候,這里面有些醫院的名字竟形同“莆田系醫院”,為了識別這其中為數不多的“莆田系醫院”,小編決定使用Python來(lái)一探究竟。
  由于篇幅限制,本篇重點(diǎn)介紹如何獲取所需的.docx文件,下篇重點(diǎn)介紹如何提取.docx文件中的表格信息并與已有的數據庫進(jìn)行匹配。
  本文涉及的技術(shù)要點(diǎn):
 ?、佾@取公告附件②獲取word文件中的表格信息③ 將.doc文件轉換為.docx文件
  一、使用網(wǎng)絡(luò )爬蟲(chóng)技術(shù)抓取愛(ài)嬰醫院名單
  1、創(chuàng )建文件夾并改變缺省路徑
  導入Python的os標準庫,判斷是否存在我們需要的文件夾,如果不存在則創(chuàng )建,將新創(chuàng )建的文件夾作為缺省路徑,程序如下:
  import osif not os.path.exists(r"D:/愛(ài)嬰醫院"): os.mkdir(r"D:/愛(ài)嬰醫院")os.chdir(r"D:/愛(ài)嬰醫院")
  2、導入requests標準庫和re標準庫抓取WORD文件
  requests和re庫的使用在爬蟲(chóng)俱樂(lè )部往期推文《》和《》中已詳細介紹。首先,導入標準庫,構造headers,并抓取網(wǎng)頁(yè)源代碼,程序如下:
  import requestsimport reheaders = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36', 'Host': 'www.nhc.gov.cn', 'Referer': 'http://www.nhc.gov.cn/fys/s7906/201511/e5650712dbcd449e9d2e01129a698b9c.shtml', 'Cookie': 'FSSBBIl1UgzbN7N80S=IIRSdCvBkEfkV.B2JY9RYhaETIf1BuxVpvEkSoPAJNFoG0jDMD0Ful2W19MSwjQT; yfx_c_g_u_id_10006654=_ck19080819145412635280045357765; _gscu_2059686908=65262894vmq4k445; yfx_f_l_v_t_10006654=f_t_1565262894262__r_t_1566175543011__v_t_1566175543011__r_c_2; _gscbrs_2059686908=1; yfx_mr_10006654=%3A%3Amarket_type_free_search%3A%3A%3A%3Abaidu%3A%3A%3A%3A%3A%3A%3A%3Awww.baidu.com%3A%3A%3A%3Apmf_from_free_search; yfx_mr_f_10006654=%3A%3Amarket_type_free_search%3A%3A%3A%3Abaidu%3A%3A%3A%3A%3A%3A%3A%3Awww.baidu.com%3A%3A%3A%3Apmf_from_free_search; yfx_key_10006654=; security_session_verify=27b11d4bf074ab3d320a0abb616f351f; banggoo.nuva.cookie=1|XVn2H|XVnyw; FSSBBIl1UgzbN7N80T=3r.zHapFkhZJ9axZJ1O.c4IFBETpXD7V97EmMfYcNch3_sxH_Btj9.wKGGKtWVFD4JTZMrYQH4I_cyZS.TVLlnmOlnWWQYX1KSl_0JUVaqTV5NSoiWZ2yDjJtV0RKxM3mtcPiY3b6wUjzJcPd4Z3u2ns76vO.lskE3joV_Gsk37Wj7hd7a.qnhOQazlKQrIZW8zGEH.8cPkVTO626ptQpnK35KuJcjrdVKTUEIq7bS81Ba.CKHUaDxNyxwsVMVkUiIGOGGD9sL3MFcik_S05TQa174cT51WxsHLZ_d4FFWBq3LZzaqvAM.ybpZ0vwVcPApVOILVksCY4w7adafW4.rYWCq_.1437bDWfT7f6FtSnb9G' }html = requests.get("http://www.nhc.gov.cn/fys/s790 ... 6quot;)text = html.content.decode('utf-8')#先抓取字節碼再轉換為字符串,避免亂碼。print(text)
  結果如下:
  
  可見(jiàn),我們使用requests庫成功將網(wǎng)頁(yè)源代碼抓取下來(lái)。源代碼中存有WORD文件的URL,我們將其中一個(gè)復制下來(lái)進(jìn)行分析:
  <A target=_blankhref="/ewebeditor/uploadfile/2015/11/20151117160507435.doc">1.北京市愛(ài)嬰醫院名單.doc</A></P>
  其中的URL可以使用正則表達式A[ ]target.*?href="(.*?)"進(jìn)行提取,我們提取出32個(gè)WORD文件的URL并放在一個(gè)列表中,程序如下:
  urls = re.findall('A[ ]target.*?href="(.*?)"', text, re.S)print(urls)c_url = []for url in urls: ur = "http://www.nhc.gov.cn" + url c_url.append(ur)print(c_url)
  結果如下:
  
  最后,使用requests庫,根據列表中的URL下載WORD文件,程序如下:
  for nu,c in enumerate(c_url): co = requests.get(c) #獲取文件 suffix = os.path.splitext(c)[1] #分離文件名與文件后綴(.doc或.docx) filename = str(nu)+suffix #用序號給文件命名,生成新的文件名 with open(filename,'wb') as f:????????f.write(co.content)
  此時(shí),在缺省路徑中就出現了我們需要的WORD文件,結果如下:
  
  二、將.doc文件轉換為.docx文件
  由于Python無(wú)法讀取.doc文件,因此我們先將.doc轉換為.docx。
  導入標準庫并定義轉化函數:
  from win32com import client# win32com.client可以直接調用VBA的庫,對Word、Excel進(jìn)行操作def doc_to_docx(path): if os.path.splitext(path)[1] == ".doc": word = client.Dispatch('Word.Application') #打開(kāi)word。 doc = word.Documents.Open(path) # 打開(kāi)目標路徑下的文件 doc.SaveAs(os.path.splitext(path)[0]+".docx", 16) doc.Close()????????word.Quit()???????#退出
  上述函數需要傳入文件名。接下來(lái)定義一個(gè)函數,用來(lái)將指定文件夾中的所有文件存入歷列表中:
  def find_file(path, ext, file_list=[]): dir = os.listdir(path) for i in dir: i = os.path.join(path, i) #拼接文件路徑, 將多個(gè)路徑組合后返回 if os.path.isdir(i): #用于判斷某一對象是否為目錄 find_file(i, ext, file_list) else: if ext == os.path.splitext(i)[1]: file_list.append(i)????return?file_list
  調用上述函數進(jìn)行轉換并刪掉.doc文件,程序如下:
  dir_path = "D:\愛(ài)嬰醫院" #批量轉換文件夾ext = ".doc"file_list = find_file(dir_path, ext)for file in file_list: doc_to_docx(file)#刪掉.doc文件files = os.listdir()print(files)for c in files: if os.path.splitext(c)[1] == ".doc":????????os.remove(c)
  結果如下:
  
  此時(shí),文件就全部轉換為了.docx文件。
  
  對我們的推文累計打賞超過(guò)1000元,我們即可給您開(kāi)具發(fā)票,發(fā)票類(lèi)別為“咨詢(xún)費”。用心做事,不負您的支持!
  往期推文推薦
  關(guān)于我們
  微信公眾號“Stata and Python數據分析”分享實(shí)用的stata、python等軟件的數據處理知識,歡迎轉載、打賞。我們是由李春濤教授領(lǐng)導下的研究生及本科生組成的大數據處理和分析團隊。
  此外,歡迎大家踴躍投稿,介紹一些關(guān)于stata和python的數據處理和分析技巧。投稿郵箱:投稿要求:
  1)必須原創(chuàng ),禁止抄襲;
  2)必須準確,詳細,有例子,有截圖;
  注意事項:
  1)所有投稿都會(huì )經(jīng)過(guò)本公眾號運營(yíng)團隊成員的審核,審核通過(guò)才可錄用,一經(jīng)錄用,會(huì )在該推文里為作者署名,并有賞金分成。
  2)郵件請注明投稿,郵件名稱(chēng)為“投稿+推文名稱(chēng)”。
  3)應廣大讀者要求,現開(kāi)通有償問(wèn)答服務(wù),如果大家遇到有關(guān)數據處理、分析等問(wèn)題,可以在公眾號中提出,只需支付少量賞金,我們會(huì )在后期的推文里給予解答。
  

小白學(xué) Python 爬蟲(chóng)(42):春節去哪里玩(系列終篇)

網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 192 次瀏覽 ? 2022-05-26 12:39 ? 來(lái)自相關(guān)話(huà)題

  小白學(xué) Python 爬蟲(chóng)(42):春節去哪里玩(系列終篇)
  
  
  
  人生苦短,我用 Python
  前文傳送門(mén):
  引言
  首先恭喜看到這篇文章的同學(xué),本篇內容為 「小白學(xué) Python 爬蟲(chóng)」 系列的最后一篇。
  
  看了下上面的前文傳送門(mén),加上這篇內容,總共有 42 篇,小編還是成就感滿(mǎn)滿(mǎn),小編翻看了下公眾號,第一篇文章是在 2019 年的 11 月 17 日推送的,大致數了數,將近兩個(gè)月的時(shí)間。
  當然,其中一些文章的質(zhì)量并不高,很多都是在比較有限的時(shí)間中趕工趕出來(lái)的,還是感謝各位讀者對小編的不離不棄,寫(xiě)的這么爛還沒(méi)取關(guān)的絕對是真愛(ài)了。
  正好下周就要過(guò)年了,從推送的時(shí)間算的話(huà)還有 10 個(gè)自然日左右的時(shí)間,可能很多同學(xué)可能過(guò)年是要出去玩的,那么去哪里玩就成了一個(gè)問(wèn)題。
  那么,怎么挑選去哪里玩最快的,小編想了想,直接去抓某站的數據吧,抓下來(lái)自己根據自己的情況查詢(xún)下就好了。
  那么今天的目標站是:馬蜂窩。
  這里小編還想說(shuō)一點(diǎn),雖然我們在前面 7、 8 篇文章中都是在講如何使用爬蟲(chóng)框架 Scrapy ,說(shuō)實(shí)話(huà),小編并不覺(jué)得 Scrapy 有多方便,在一些簡(jiǎn)單的應用場(chǎng)景下,使用 Requests 庫可能是最方便的選擇, Scrapy 小編個(gè)人感覺(jué)還是更適合使用在一些中大型的爬蟲(chóng)項目中,簡(jiǎn)單的爬蟲(chóng)腳本使用最簡(jiǎn)單的技術(shù)棧就 ok 了,所以小編在本文中使用的技術(shù)棧還是 Requests + PyQuery 。
  不要問(wèn)為啥,問(wèn)就是喜歡。
  分析
  首先我們訪(fǎng)問(wèn)鏈接,打開(kāi)我們將要抓取的站點(diǎn):。
  
  這里是攻略的列表頁(yè),我們的目標是抓取來(lái)自游記的數據,其余的數據放過(guò),原因是在游記中我們才能獲取到一些具體的我們需要的數據。
  
  數據的來(lái)源搞清楚了,接下來(lái)是翻頁(yè)功能,只有清楚了如何翻頁(yè),我們才能源源不斷的獲取數據,否則就只能抓取第一頁(yè)的數據了。
  當把頁(yè)面翻到最下面的時(shí)候就尷尬了,發(fā)現是自動(dòng)加載更多,這個(gè)當然難不倒帥氣逼人的小編我,掏出大殺器, Chrome 的開(kāi)發(fā)者工具 F12 ,選到 network 標簽頁(yè),再往下滾動(dòng)一下,我們查看下這個(gè)頁(yè)面發(fā)出的請求。
  
  這個(gè)請求很有意思,請求的路徑和我們訪(fǎng)問(wèn)的頁(yè)面路徑一樣,但是請求類(lèi)型變成 POST ,并且增加了請求參數,類(lèi)型還是 Form 表單格式的。
  截止這里,我們已經(jīng)清楚了目標站點(diǎn)的數據路徑以及翻頁(yè)方式,雖然目前我們并不知道最大頁(yè)數是多少,但是我們可以人為的設置一個(gè)最大頁(yè)數,比如 100 或者 200 ,小編相信,這么大的站點(diǎn)上,幾百頁(yè)的游記應該是還有的。
  代碼
  代碼小編就直接貼出來(lái),之前有同學(xué)希望數據是保存在 Excel 中的,本次實(shí)戰的數據就不存數據庫了,直接寫(xiě)入 Excel 。
  import requests<br />from pyquery import PyQuery<br />import xlsxwriter<br /><br />headers = {<br /> 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36',<br /> 'cookie': '__jsluid_s=6fc5b4a3b5235afbfdafff4bbf7e6dbd; PHPSESSID=v9hm8hc3s56ogrn8si12fejdm3; mfw_uuid=5e1db855-ab4a-da12-309c-afb9cf90d3dd; _r=baidu; _rp=a%3A2%3A%7Bs%3A1%3A%22p%22%3Bs%3A18%3A%22www.baidu.com%2Flink%22%3Bs%3A1%3A%22t%22%3Bi%3A1579006045%3B%7D; oad_n=a%3A5%3A%7Bs%3A5%3A%22refer%22%3Bs%3A21%3A%22https%3A%2F%2Fwww.baidu.com%22%3Bs%3A2%3A%22hp%22%3Bs%3A13%3A%22www.baidu.com%22%3Bs%3A3%3A%22oid%22%3Bi%3A1026%3Bs%3A2%3A%22dm%22%3Bs%3A15%3A%22www.mafengwo.cn%22%3Bs%3A2%3A%22ft%22%3Bs%3A19%3A%222020-01-14+20%3A47%3A25%22%3B%7D; __mfwothchid=referrer%7Cwww.baidu.com; __omc_chl=; __mfwc=referrer%7Cwww.baidu.com; Hm_lvt_8288b2ed37e5bc9b4c9f7008798d2de0=1579006048; uva=s%3A264%3A%22a%3A4%3A%7Bs%3A13%3A%22host_pre_time%22%3Bs%3A10%3A%222020-01-14%22%3Bs%3A2%3A%22lt%22%3Bi%3A1579006046%3Bs%3A10%3A%22last_refer%22%3Bs%3A137%3A%22https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DuR5Oj9n_xm4TSj7_1drQ1HRnFTYNM0M2TCljkjVrdIiUE-B2qPgh0MifEkceLE_U%26wd%3D%26eqid%3D93c920a80002dc72000000035e1db85c%22%3Bs%3A5%3A%22rhost%22%3Bs%3A13%3A%22www.baidu.com%22%3B%7D%22%3B; __mfwurd=a%3A3%3A%7Bs%3A6%3A%22f_time%22%3Bi%3A1579006046%3Bs%3A9%3A%22f_rdomain%22%3Bs%3A13%3A%22www.baidu.com%22%3Bs%3A6%3A%22f_host%22%3Bs%3A3%3A%22www%22%3B%7D; __mfwuuid=5e1db855-ab4a-da12-309c-afb9cf90d3dd; UM_distinctid=16fa418373e40f-070db24dfac29d-c383f64-1fa400-16fa418373fe31; __jsluid_h=b3f11fd3c79469af5c49be9ecb7f7b86; __omc_r=; __mfwa=1579006047379.58159.3.1579011903001.1579015057723; __mfwlv=1579015057; __mfwvn=2; CNZZDATA30065558=cnzz_eid%3D448020855-1579003717-https%253A%252F%252Fwww.baidu.com%252F%26ntime%3D1579014923; bottom_ad_status=0; __mfwb=5e663dbc8869.7.direct; __mfwlt=1579019025; Hm_lpvt_8288b2ed37e5bc9b4c9f7008798d2de0=1579019026; __jsl_clearance=1579019146.235|0|fpZQ1rm7BHtgd6GdjVUIX8FJJ9o%3D'<br />}<br /><br /><br />s = requests.Session()<br /><br /><br />value = []<br /><br />defgetList(maxNum):<br /> """<br /> 獲取列表頁(yè)面數據<br /> :param maxNum: 最大抓取頁(yè)數<br /> :return:<br /> """<br /> url = 'http://www.mafengwo.cn/gonglve/'<br /> s.get(url, headers = headers)<br /> for page in range(1, maxNum + 1):<br /> data = {'page': page}<br /> response = s.post(url, data = data, headers = headers)<br /> doc = PyQuery(response.text)<br /> items = doc('.feed-item').items()<br /> for item in items:<br /> if item('.type strong').text() == '游記':<br /> # 如果是游記,則進(jìn)入內頁(yè)數據抓取<br /> inner_url = item('a').attr('href')<br /> getInfo(inner_url)<br /><br /><br />defgetInfo(url):<br /> """<br /> 獲取內頁(yè)數據<br /> :param url: 內頁(yè)鏈接<br /> :return:<br /> """<br /> response = s.get(url, headers = headers)<br /> doc = PyQuery(response.text)<br /> title = doc('title').text()<br /> # 獲取數據采集區<br /> item = doc('.tarvel_dir_list')<br /> if len(item) == 0:<br /> return<br /> time = item('.time').text()<br /> day = item('.day').text()<br /> people = item('.people').text()<br /> cost = item('.cost').text()<br /> # 數據格式化<br /> if time == '':<br /> pass<br /> else:<br /> time = time.split('/')[1] if len(time.split('/')) > 1 else ''<br /><br /> if day == '':<br /> pass<br /> else:<br /> day = day.split('/')[1] if len(day.split('/')) > 1 else ''<br /><br /> if people == '':<br /> pass<br /> else:<br /> people = people.split('/')[1] if len(people.split('/')) > 1 else ''<br /><br /> if cost == '':<br /> pass<br /> else:<br /> cost = cost.split('/')[1] if len(cost.split('/')) > 1 else ''<br /><br /><br /> value.append([title, time, day, people, cost, url])<br /><br /><br />defwrite_excel_xlsx(value):<br /> """<br /> 數據寫(xiě)入Excel<br /> :param value:<br /> :return:<br /> """<br /> index = len(value)<br /><br /> workbook = xlsxwriter.Workbook('mfw.xlsx')<br /> sheet = workbook.add_worksheet()<br /> for i in range(1, index + 1):<br /> row = 'A' + str(i)<br /> sheet.write_row(row, value[i - 1])<br /> workbook.close()<br /> print("xlsx格式表格寫(xiě)入數據成功!")<br /><br /><br />defmain():<br /> getList(5)<br /> write_excel_xlsx(value)<br /><br />if __name__ == '__main__':<br /> main()<br />
  因為馬蜂窩在游記的詳情頁(yè)面上有反爬的限制,小編這里為了簡(jiǎn)單,直接從瀏覽器中將 cookie copy 出來(lái),加在了請求頭上。
  小編這里簡(jiǎn)單的爬取了 5 個(gè)列表頁(yè)的信息,如下:
  
  好像數據量并不是很多的樣子,各位同學(xué)可以嘗試爬取 50 頁(yè)或者 100 頁(yè)的數據,這樣得到的結果會(huì )有比較不錯的參考價(jià)值。
  好了,本篇內容到這里就結束了,小編隨后會(huì )將全部的文章索引整理出來(lái)推在公眾號上,方便大家查閱。
  示例代碼
  本系列的所有代碼小編都會(huì )放在代碼管理倉庫 Github 和 Gitee 上,方便大家取用。
  示例代碼-Github:
  示例代碼-Gitee:
  
   查看全部

  小白學(xué) Python 爬蟲(chóng)(42):春節去哪里玩(系列終篇)
  
  
  
  人生苦短,我用 Python
  前文傳送門(mén):
  引言
  首先恭喜看到這篇文章的同學(xué),本篇內容為 「小白學(xué) Python 爬蟲(chóng)」 系列的最后一篇。
  
  看了下上面的前文傳送門(mén),加上這篇內容,總共有 42 篇,小編還是成就感滿(mǎn)滿(mǎn),小編翻看了下公眾號,第一篇文章是在 2019 年的 11 月 17 日推送的,大致數了數,將近兩個(gè)月的時(shí)間。
  當然,其中一些文章的質(zhì)量并不高,很多都是在比較有限的時(shí)間中趕工趕出來(lái)的,還是感謝各位讀者對小編的不離不棄,寫(xiě)的這么爛還沒(méi)取關(guān)的絕對是真愛(ài)了。
  正好下周就要過(guò)年了,從推送的時(shí)間算的話(huà)還有 10 個(gè)自然日左右的時(shí)間,可能很多同學(xué)可能過(guò)年是要出去玩的,那么去哪里玩就成了一個(gè)問(wèn)題。
  那么,怎么挑選去哪里玩最快的,小編想了想,直接去抓某站的數據吧,抓下來(lái)自己根據自己的情況查詢(xún)下就好了。
  那么今天的目標站是:馬蜂窩。
  這里小編還想說(shuō)一點(diǎn),雖然我們在前面 7、 8 篇文章中都是在講如何使用爬蟲(chóng)框架 Scrapy ,說(shuō)實(shí)話(huà),小編并不覺(jué)得 Scrapy 有多方便,在一些簡(jiǎn)單的應用場(chǎng)景下,使用 Requests 庫可能是最方便的選擇, Scrapy 小編個(gè)人感覺(jué)還是更適合使用在一些中大型的爬蟲(chóng)項目中,簡(jiǎn)單的爬蟲(chóng)腳本使用最簡(jiǎn)單的技術(shù)棧就 ok 了,所以小編在本文中使用的技術(shù)棧還是 Requests + PyQuery 。
  不要問(wèn)為啥,問(wèn)就是喜歡。
  分析
  首先我們訪(fǎng)問(wèn)鏈接,打開(kāi)我們將要抓取的站點(diǎn):。
  
  這里是攻略的列表頁(yè),我們的目標是抓取來(lái)自游記的數據,其余的數據放過(guò),原因是在游記中我們才能獲取到一些具體的我們需要的數據。
  
  數據的來(lái)源搞清楚了,接下來(lái)是翻頁(yè)功能,只有清楚了如何翻頁(yè),我們才能源源不斷的獲取數據,否則就只能抓取第一頁(yè)的數據了。
  當把頁(yè)面翻到最下面的時(shí)候就尷尬了,發(fā)現是自動(dòng)加載更多,這個(gè)當然難不倒帥氣逼人的小編我,掏出大殺器, Chrome 的開(kāi)發(fā)者工具 F12 ,選到 network 標簽頁(yè),再往下滾動(dòng)一下,我們查看下這個(gè)頁(yè)面發(fā)出的請求。
  
  這個(gè)請求很有意思,請求的路徑和我們訪(fǎng)問(wèn)的頁(yè)面路徑一樣,但是請求類(lèi)型變成 POST ,并且增加了請求參數,類(lèi)型還是 Form 表單格式的。
  截止這里,我們已經(jīng)清楚了目標站點(diǎn)的數據路徑以及翻頁(yè)方式,雖然目前我們并不知道最大頁(yè)數是多少,但是我們可以人為的設置一個(gè)最大頁(yè)數,比如 100 或者 200 ,小編相信,這么大的站點(diǎn)上,幾百頁(yè)的游記應該是還有的。
  代碼
  代碼小編就直接貼出來(lái),之前有同學(xué)希望數據是保存在 Excel 中的,本次實(shí)戰的數據就不存數據庫了,直接寫(xiě)入 Excel 。
  import requests<br />from pyquery import PyQuery<br />import xlsxwriter<br /><br />headers = {<br /> 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36',<br /> 'cookie': '__jsluid_s=6fc5b4a3b5235afbfdafff4bbf7e6dbd; PHPSESSID=v9hm8hc3s56ogrn8si12fejdm3; mfw_uuid=5e1db855-ab4a-da12-309c-afb9cf90d3dd; _r=baidu; _rp=a%3A2%3A%7Bs%3A1%3A%22p%22%3Bs%3A18%3A%22www.baidu.com%2Flink%22%3Bs%3A1%3A%22t%22%3Bi%3A1579006045%3B%7D; oad_n=a%3A5%3A%7Bs%3A5%3A%22refer%22%3Bs%3A21%3A%22https%3A%2F%2Fwww.baidu.com%22%3Bs%3A2%3A%22hp%22%3Bs%3A13%3A%22www.baidu.com%22%3Bs%3A3%3A%22oid%22%3Bi%3A1026%3Bs%3A2%3A%22dm%22%3Bs%3A15%3A%22www.mafengwo.cn%22%3Bs%3A2%3A%22ft%22%3Bs%3A19%3A%222020-01-14+20%3A47%3A25%22%3B%7D; __mfwothchid=referrer%7Cwww.baidu.com; __omc_chl=; __mfwc=referrer%7Cwww.baidu.com; Hm_lvt_8288b2ed37e5bc9b4c9f7008798d2de0=1579006048; uva=s%3A264%3A%22a%3A4%3A%7Bs%3A13%3A%22host_pre_time%22%3Bs%3A10%3A%222020-01-14%22%3Bs%3A2%3A%22lt%22%3Bi%3A1579006046%3Bs%3A10%3A%22last_refer%22%3Bs%3A137%3A%22https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DuR5Oj9n_xm4TSj7_1drQ1HRnFTYNM0M2TCljkjVrdIiUE-B2qPgh0MifEkceLE_U%26wd%3D%26eqid%3D93c920a80002dc72000000035e1db85c%22%3Bs%3A5%3A%22rhost%22%3Bs%3A13%3A%22www.baidu.com%22%3B%7D%22%3B; __mfwurd=a%3A3%3A%7Bs%3A6%3A%22f_time%22%3Bi%3A1579006046%3Bs%3A9%3A%22f_rdomain%22%3Bs%3A13%3A%22www.baidu.com%22%3Bs%3A6%3A%22f_host%22%3Bs%3A3%3A%22www%22%3B%7D; __mfwuuid=5e1db855-ab4a-da12-309c-afb9cf90d3dd; UM_distinctid=16fa418373e40f-070db24dfac29d-c383f64-1fa400-16fa418373fe31; __jsluid_h=b3f11fd3c79469af5c49be9ecb7f7b86; __omc_r=; __mfwa=1579006047379.58159.3.1579011903001.1579015057723; __mfwlv=1579015057; __mfwvn=2; CNZZDATA30065558=cnzz_eid%3D448020855-1579003717-https%253A%252F%252Fwww.baidu.com%252F%26ntime%3D1579014923; bottom_ad_status=0; __mfwb=5e663dbc8869.7.direct; __mfwlt=1579019025; Hm_lpvt_8288b2ed37e5bc9b4c9f7008798d2de0=1579019026; __jsl_clearance=1579019146.235|0|fpZQ1rm7BHtgd6GdjVUIX8FJJ9o%3D'<br />}<br /><br /><br />s = requests.Session()<br /><br /><br />value = []<br /><br />defgetList(maxNum):<br /> """<br /> 獲取列表頁(yè)面數據<br /> :param maxNum: 最大抓取頁(yè)數<br /> :return:<br /> """<br /> url = 'http://www.mafengwo.cn/gonglve/'<br /> s.get(url, headers = headers)<br /> for page in range(1, maxNum + 1):<br /> data = {'page': page}<br /> response = s.post(url, data = data, headers = headers)<br /> doc = PyQuery(response.text)<br /> items = doc('.feed-item').items()<br /> for item in items:<br /> if item('.type strong').text() == '游記':<br /> # 如果是游記,則進(jìn)入內頁(yè)數據抓取<br /> inner_url = item('a').attr('href')<br /> getInfo(inner_url)<br /><br /><br />defgetInfo(url):<br /> """<br /> 獲取內頁(yè)數據<br /> :param url: 內頁(yè)鏈接<br /> :return:<br /> """<br /> response = s.get(url, headers = headers)<br /> doc = PyQuery(response.text)<br /> title = doc('title').text()<br /> # 獲取數據采集區<br /> item = doc('.tarvel_dir_list')<br /> if len(item) == 0:<br /> return<br /> time = item('.time').text()<br /> day = item('.day').text()<br /> people = item('.people').text()<br /> cost = item('.cost').text()<br /> # 數據格式化<br /> if time == '':<br /> pass<br /> else:<br /> time = time.split('/')[1] if len(time.split('/')) > 1 else ''<br /><br /> if day == '':<br /> pass<br /> else:<br /> day = day.split('/')[1] if len(day.split('/')) > 1 else ''<br /><br /> if people == '':<br /> pass<br /> else:<br /> people = people.split('/')[1] if len(people.split('/')) > 1 else ''<br /><br /> if cost == '':<br /> pass<br /> else:<br /> cost = cost.split('/')[1] if len(cost.split('/')) > 1 else ''<br /><br /><br /> value.append([title, time, day, people, cost, url])<br /><br /><br />defwrite_excel_xlsx(value):<br /> """<br /> 數據寫(xiě)入Excel<br /> :param value:<br /> :return:<br /> """<br /> index = len(value)<br /><br /> workbook = xlsxwriter.Workbook('mfw.xlsx')<br /> sheet = workbook.add_worksheet()<br /> for i in range(1, index + 1):<br /> row = 'A' + str(i)<br /> sheet.write_row(row, value[i - 1])<br /> workbook.close()<br /> print("xlsx格式表格寫(xiě)入數據成功!")<br /><br /><br />defmain():<br /> getList(5)<br /> write_excel_xlsx(value)<br /><br />if __name__ == '__main__':<br /> main()<br />
  因為馬蜂窩在游記的詳情頁(yè)面上有反爬的限制,小編這里為了簡(jiǎn)單,直接從瀏覽器中將 cookie copy 出來(lái),加在了請求頭上。
  小編這里簡(jiǎn)單的爬取了 5 個(gè)列表頁(yè)的信息,如下:
  
  好像數據量并不是很多的樣子,各位同學(xué)可以嘗試爬取 50 頁(yè)或者 100 頁(yè)的數據,這樣得到的結果會(huì )有比較不錯的參考價(jià)值。
  好了,本篇內容到這里就結束了,小編隨后會(huì )將全部的文章索引整理出來(lái)推在公眾號上,方便大家查閱。
  示例代碼
  本系列的所有代碼小編都會(huì )放在代碼管理倉庫 Github 和 Gitee 上,方便大家取用。
  示例代碼-Github:
  示例代碼-Gitee:
  
  

一文搞懂爬蟲(chóng)Scrapy框架詳解

網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 60 次瀏覽 ? 2022-05-21 05:55 ? 來(lái)自相關(guān)話(huà)題

  一文搞懂爬蟲(chóng)Scrapy框架詳解
  
  “Python爬蟲(chóng)Scrapy框架實(shí)踐?!?
  大數據已經(jīng)滲透到當今每一個(gè)行業(yè)和業(yè)務(wù)職能領(lǐng)域,成為重要的生產(chǎn)因素?!比藗儗τ诤A繑祿耐诰蚝瓦\用越來(lái)越密切,預示著(zhù)爬蟲(chóng)工作者已經(jīng)成為互聯(lián)網(wǎng)數據公司的關(guān)鍵性職位,他們不但要精通數據抓取和分析,還要掌握搜索引擎和相關(guān)檢索的算法,對內存、性能、分布式算法都要有一定的了解,并針對工作進(jìn)程編排合理的布局。依據數據來(lái)預測某一種事物未來(lái)的發(fā)展趨勢,以及對應的風(fēng)險,提早解決未來(lái)即將遇到的風(fēng)險,防范于未然。
  一 Scrapy框架簡(jiǎn)介
  Scrapy,Python開(kāi)發(fā)的一個(gè)快速,高層次的屏幕抓取和web抓取框架,用于抓取web站點(diǎn)并從頁(yè)面中提取結構化的數據。Scrapy用途廣泛,可以用于數據挖掘、監測和自動(dòng)化測試。
  了解scrapy爬蟲(chóng)原理:Scrapy 使用了 Twisted異步網(wǎng)絡(luò )庫來(lái)處理網(wǎng)絡(luò )通訊。整體架構如下:
  
  總結-scrapy大概流程如下:
  Scrapy Engine:Scrapy引擎。負責控制數據流在系統中所有組件中流動(dòng),并在相應動(dòng)作發(fā)生時(shí)觸發(fā)事件。
  Scheduler:調度器。從Scrapy Engine接受請求(requests)并排序列入隊列,并在引擎再次請求時(shí)返回。用它來(lái)決定下一個(gè)抓取的網(wǎng)址是什么,同時(shí)去除重復的網(wǎng)址。
  Downloader:下載器。抓取網(wǎng)頁(yè)并將網(wǎng)頁(yè)內容返還給Spiders。建立在twisted異步模型。
  Spiders:爬蟲(chóng)。用戶(hù)自定義的類(lèi),主要用來(lái)解析網(wǎng)頁(yè),提取Items,發(fā)送url跟進(jìn)等新請求等。
  Item Pipelines:管道。主要用來(lái)處理Spider解析出來(lái)的Items,進(jìn)行按規則過(guò)濾,驗證,持久化存儲(如數據庫存儲)等
  Downloader Middlewares:下載中間件。位于Scrapy Engine和Downloader之間,主要是處理Scrapy引擎與下載器之間的請求及響應。
  Spider Middlewares:爬蟲(chóng)中間件。位于Scrapy Engine和Spiders之間,主要工作是處理Spiders的響應輸入和請求輸出。
  Scheduler Middlewares:調度中間件。位于Scrapy Engine和Scheduler之間。主要工作是處理從Scrapy Engine發(fā)送到Scheduler的請求和響應。
  二 Scrapy框架詳解Scrapy由Python語(yǔ)言編寫(xiě),是一個(gè)快速、高層次的屏幕抓取和Web抓取框架。1. 數據流向Scrapy數據流是由執行流程的核心引擎來(lái)控制的,流程如圖所示。
  
  框架組件數據流
  1.ScrapyEngine打開(kāi)一個(gè)網(wǎng)站,找到處理該網(wǎng)站的Spider,并向該Spider請求第一個(gè)(批)要爬取的url(s);
  2.ScrapyEngine向調度器請求第一個(gè)要爬取的url,并加入到Schedule作為請求以備調度;
  3.ScrapyEngine向調度器請求下一個(gè)要爬取的url;
  4.Schedule返回下一個(gè)要爬取的url給ScrapyEngine,ScrapyEngine通過(guò)DownloaderMiddlewares將url轉發(fā)給Downloader;
  5.頁(yè)面下載完畢,Downloader生成一個(gè)頁(yè)面的Response,通過(guò)DownloaderMiddlewares發(fā)送給ScrapyEngine;
  6.ScrapyEngine從Downloader中接收到Response,通過(guò)SpiderMiddlewares發(fā)送給Spider處理;
  7.Spider處理Response并返回提取到的Item以及新的Request給ScrapyEngine;
  8.ScrapyEngine將Spider返回的Item交給ItemPipeline,將Spider返回的Request交給Schedule進(jìn)行從第二步開(kāi)始的重復操作,直到調度器中沒(méi)有待處理的Request,ScrapyEngine關(guān)閉。
  2Scrapy 的運作流程
  制作 Scrapy 爬蟲(chóng) 一共需要 4 步:
  1 新建項目 (scrapy startproject xxx):新建一個(gè)新的爬蟲(chóng)項目
  2 明確目標 (編寫(xiě) items.py):明確你想要抓取的目標,想要爬什么信息
  3 制作爬蟲(chóng) (spiders/xxspider.py):制作爬蟲(chóng)開(kāi)始爬取網(wǎng)頁(yè)
  4 存儲內容 (pipelines.py):設計管道存儲爬取內容
  具體流程
  1、scrapy安裝
  pip install scrapy<br /><br />Successfully installed Automat-20.2.0 PyDispatcher-2.0.5 Twisted-21.2.0 attrs-21.2.0 constantly-15.1.0 cssselect-1.1.0 h2-3.2.0 hpack-3.0.0 hyperframe-5.2.0 hyperlink-21.0.0 incremental-21.3.0 itemadapter-0.2.0 itemloaders-1.0.4 parsel-1.6.0 priority-1.3.0 protego-0.1.16 pyOpenSSL-20.0.1 pyasn1-0.4.8 pyasn1-modules-0.2.8 queuelib-1.6.1 scrapy-2.5.0 service-identity-21.1.0 twisted-iocpsupport-1.0.1 w3lib-1.22.0 zope.interface-5.4.0
  檢查是否安裝成功:
  scrapy?versionScrapy 2.5.0
  scrapy常用命令使用:
  
  Usage: scrapy [options] [args]<br />Available commands: bench Run quick benchmark test check Check spider contracts commands crawl Run a spider edit Edit spider fetch Fetch a URL using the Scrapy downloader genspider Generate new spider using pre-defined templates list List available spiders parse Parse URL (using its spider) and print the results runspider Run a self-contained spider (without creating a project) settings Get settings values shell Interactive scraping console startproject Create new project version Print Scrapy version view Open URL in browser, as seen by Scrapy<br />Use "scrapy -h" to see more info about a command
  2、創(chuàng )建項目
  //創(chuàng )建一個(gè)測試項目scrapy startproject scrapyproject<br />New Scrapy project 'scrapyproject', using template directory 'c:\users\username\appdata\local\programs\python\python36\lib\site-packages\scrapy\templates\project', created in: C:\Users\username\PycharmProjects\scrapyproject<br />You can start your first spider with: cd scrapyproject scrapy genspider example example.com
  3、第一個(gè)爬蟲(chóng)項目
  注釋?zhuān)?
  scrapy genspider -l 查看當前可以使用的爬蟲(chóng)模板
  scrapy genspider -t 創(chuàng )建爬蟲(chóng)文件
  1.scrapy?startproject?scrapyproject2.在工程目錄下創(chuàng )建爬蟲(chóng)baidu 格式:scrapy genspider [-t template] <br />支持模板template:basic(默認)、crawl、csvfeed、xmlfeed這里name是爬蟲(chóng)的名字;domain是設置allowed_domains以及start_urls,這兩個(gè)屬性可以在爬蟲(chóng)類(lèi)中修改<br /><br />cd scrapyprojectscrapy?genspider?baidu?baidu.com?(baidu?為爬蟲(chóng)的名稱(chēng),baidu.com為要爬取的網(wǎng)站的域名)<br />輸出:Created spider 'baidu' using template 'basic' in module: scrapyproject.spiders.baidu<br />3.使用pycharm 打開(kāi)第一步創(chuàng )建的項目
  目錄及文件結構:
  
  文件說(shuō)明:
  scrapy.cfg 項目的配置信息,主要為Scrapy命令行工具提供一個(gè)基礎的配置信息。(真正爬蟲(chóng)相關(guān)的配置信息在settings.py文件中)
  items.py 設置數據存儲模板,用于結構化數據,如:Django的Model
  pipelines 數據處理行為,如:一般結構化的數據持久化
  settings.py 配置文件,如:遞歸的層數、并發(fā)數,延遲下載等
  spiders 爬蟲(chóng)目錄,如:創(chuàng )建文件,編寫(xiě)爬蟲(chóng)規則
  注意:一般創(chuàng )建爬蟲(chóng)文件時(shí),以網(wǎng)站域名命名。
  4. cd 項目目錄,重寫(xiě)parse函數,然后啟動(dòng)爬蟲(chóng),命令:
  
  注意ROBOTSTXT_OBEY = False baidu的robots.txt里面禁止了scrapy
  scrapy?crawl?baidu
  生成爬取結果
  
  打開(kāi)是界面:
  
  05Scrapy?;ňW(wǎng)爬取實(shí)踐
  以?;ňW(wǎng)為例進(jìn)行爬取,?;ňW(wǎng):
  創(chuàng )建xiaohuar spider:
  scrapy genspider xiaohuar xiaohuar.comCreated spider 'xiaohuar' using template 'basic' in module: scrapyproject.spiders.xiaohuar
  準備: 查看全部

  一文搞懂爬蟲(chóng)Scrapy框架詳解
  
  “Python爬蟲(chóng)Scrapy框架實(shí)踐?!?
  大數據已經(jīng)滲透到當今每一個(gè)行業(yè)和業(yè)務(wù)職能領(lǐng)域,成為重要的生產(chǎn)因素?!比藗儗τ诤A繑祿耐诰蚝瓦\用越來(lái)越密切,預示著(zhù)爬蟲(chóng)工作者已經(jīng)成為互聯(lián)網(wǎng)數據公司的關(guān)鍵性職位,他們不但要精通數據抓取和分析,還要掌握搜索引擎和相關(guān)檢索的算法,對內存、性能、分布式算法都要有一定的了解,并針對工作進(jìn)程編排合理的布局。依據數據來(lái)預測某一種事物未來(lái)的發(fā)展趨勢,以及對應的風(fēng)險,提早解決未來(lái)即將遇到的風(fēng)險,防范于未然。
  一 Scrapy框架簡(jiǎn)介
  Scrapy,Python開(kāi)發(fā)的一個(gè)快速,高層次的屏幕抓取和web抓取框架,用于抓取web站點(diǎn)并從頁(yè)面中提取結構化的數據。Scrapy用途廣泛,可以用于數據挖掘、監測和自動(dòng)化測試。
  了解scrapy爬蟲(chóng)原理:Scrapy 使用了 Twisted異步網(wǎng)絡(luò )庫來(lái)處理網(wǎng)絡(luò )通訊。整體架構如下:
  
  總結-scrapy大概流程如下:
  Scrapy Engine:Scrapy引擎。負責控制數據流在系統中所有組件中流動(dòng),并在相應動(dòng)作發(fā)生時(shí)觸發(fā)事件。
  Scheduler:調度器。從Scrapy Engine接受請求(requests)并排序列入隊列,并在引擎再次請求時(shí)返回。用它來(lái)決定下一個(gè)抓取的網(wǎng)址是什么,同時(shí)去除重復的網(wǎng)址。
  Downloader:下載器。抓取網(wǎng)頁(yè)并將網(wǎng)頁(yè)內容返還給Spiders。建立在twisted異步模型。
  Spiders:爬蟲(chóng)。用戶(hù)自定義的類(lèi),主要用來(lái)解析網(wǎng)頁(yè),提取Items,發(fā)送url跟進(jìn)等新請求等。
  Item Pipelines:管道。主要用來(lái)處理Spider解析出來(lái)的Items,進(jìn)行按規則過(guò)濾,驗證,持久化存儲(如數據庫存儲)等
  Downloader Middlewares:下載中間件。位于Scrapy Engine和Downloader之間,主要是處理Scrapy引擎與下載器之間的請求及響應。
  Spider Middlewares:爬蟲(chóng)中間件。位于Scrapy Engine和Spiders之間,主要工作是處理Spiders的響應輸入和請求輸出。
  Scheduler Middlewares:調度中間件。位于Scrapy Engine和Scheduler之間。主要工作是處理從Scrapy Engine發(fā)送到Scheduler的請求和響應。
  二 Scrapy框架詳解Scrapy由Python語(yǔ)言編寫(xiě),是一個(gè)快速、高層次的屏幕抓取和Web抓取框架。1. 數據流向Scrapy數據流是由執行流程的核心引擎來(lái)控制的,流程如圖所示。
  
  框架組件數據流
  1.ScrapyEngine打開(kāi)一個(gè)網(wǎng)站,找到處理該網(wǎng)站的Spider,并向該Spider請求第一個(gè)(批)要爬取的url(s);
  2.ScrapyEngine向調度器請求第一個(gè)要爬取的url,并加入到Schedule作為請求以備調度;
  3.ScrapyEngine向調度器請求下一個(gè)要爬取的url;
  4.Schedule返回下一個(gè)要爬取的url給ScrapyEngine,ScrapyEngine通過(guò)DownloaderMiddlewares將url轉發(fā)給Downloader;
  5.頁(yè)面下載完畢,Downloader生成一個(gè)頁(yè)面的Response,通過(guò)DownloaderMiddlewares發(fā)送給ScrapyEngine;
  6.ScrapyEngine從Downloader中接收到Response,通過(guò)SpiderMiddlewares發(fā)送給Spider處理;
  7.Spider處理Response并返回提取到的Item以及新的Request給ScrapyEngine;
  8.ScrapyEngine將Spider返回的Item交給ItemPipeline,將Spider返回的Request交給Schedule進(jìn)行從第二步開(kāi)始的重復操作,直到調度器中沒(méi)有待處理的Request,ScrapyEngine關(guān)閉。
  2Scrapy 的運作流程
  制作 Scrapy 爬蟲(chóng) 一共需要 4 步:
  1 新建項目 (scrapy startproject xxx):新建一個(gè)新的爬蟲(chóng)項目
  2 明確目標 (編寫(xiě) items.py):明確你想要抓取的目標,想要爬什么信息
  3 制作爬蟲(chóng) (spiders/xxspider.py):制作爬蟲(chóng)開(kāi)始爬取網(wǎng)頁(yè)
  4 存儲內容 (pipelines.py):設計管道存儲爬取內容
  具體流程
  1、scrapy安裝
  pip install scrapy<br /><br />Successfully installed Automat-20.2.0 PyDispatcher-2.0.5 Twisted-21.2.0 attrs-21.2.0 constantly-15.1.0 cssselect-1.1.0 h2-3.2.0 hpack-3.0.0 hyperframe-5.2.0 hyperlink-21.0.0 incremental-21.3.0 itemadapter-0.2.0 itemloaders-1.0.4 parsel-1.6.0 priority-1.3.0 protego-0.1.16 pyOpenSSL-20.0.1 pyasn1-0.4.8 pyasn1-modules-0.2.8 queuelib-1.6.1 scrapy-2.5.0 service-identity-21.1.0 twisted-iocpsupport-1.0.1 w3lib-1.22.0 zope.interface-5.4.0
  檢查是否安裝成功:
  scrapy?versionScrapy 2.5.0
  scrapy常用命令使用:
  
  Usage: scrapy [options] [args]<br />Available commands: bench Run quick benchmark test check Check spider contracts commands crawl Run a spider edit Edit spider fetch Fetch a URL using the Scrapy downloader genspider Generate new spider using pre-defined templates list List available spiders parse Parse URL (using its spider) and print the results runspider Run a self-contained spider (without creating a project) settings Get settings values shell Interactive scraping console startproject Create new project version Print Scrapy version view Open URL in browser, as seen by Scrapy<br />Use "scrapy -h" to see more info about a command
  2、創(chuàng )建項目
  //創(chuàng )建一個(gè)測試項目scrapy startproject scrapyproject<br />New Scrapy project 'scrapyproject', using template directory 'c:\users\username\appdata\local\programs\python\python36\lib\site-packages\scrapy\templates\project', created in: C:\Users\username\PycharmProjects\scrapyproject<br />You can start your first spider with: cd scrapyproject scrapy genspider example example.com
  3、第一個(gè)爬蟲(chóng)項目
  注釋?zhuān)?
  scrapy genspider -l 查看當前可以使用的爬蟲(chóng)模板
  scrapy genspider -t 創(chuàng )建爬蟲(chóng)文件
  1.scrapy?startproject?scrapyproject2.在工程目錄下創(chuàng )建爬蟲(chóng)baidu 格式:scrapy genspider [-t template] <br />支持模板template:basic(默認)、crawl、csvfeed、xmlfeed這里name是爬蟲(chóng)的名字;domain是設置allowed_domains以及start_urls,這兩個(gè)屬性可以在爬蟲(chóng)類(lèi)中修改<br /><br />cd scrapyprojectscrapy?genspider?baidu?baidu.com?(baidu?為爬蟲(chóng)的名稱(chēng),baidu.com為要爬取的網(wǎng)站的域名)<br />輸出:Created spider 'baidu' using template 'basic' in module: scrapyproject.spiders.baidu<br />3.使用pycharm 打開(kāi)第一步創(chuàng )建的項目
  目錄及文件結構:
  
  文件說(shuō)明:
  scrapy.cfg 項目的配置信息,主要為Scrapy命令行工具提供一個(gè)基礎的配置信息。(真正爬蟲(chóng)相關(guān)的配置信息在settings.py文件中)
  items.py 設置數據存儲模板,用于結構化數據,如:Django的Model
  pipelines 數據處理行為,如:一般結構化的數據持久化
  settings.py 配置文件,如:遞歸的層數、并發(fā)數,延遲下載等
  spiders 爬蟲(chóng)目錄,如:創(chuàng )建文件,編寫(xiě)爬蟲(chóng)規則
  注意:一般創(chuàng )建爬蟲(chóng)文件時(shí),以網(wǎng)站域名命名。
  4. cd 項目目錄,重寫(xiě)parse函數,然后啟動(dòng)爬蟲(chóng),命令:
  
  注意ROBOTSTXT_OBEY = False baidu的robots.txt里面禁止了scrapy
  scrapy?crawl?baidu
  生成爬取結果
  
  打開(kāi)是界面:
  
  05Scrapy?;ňW(wǎng)爬取實(shí)踐
  以?;ňW(wǎng)為例進(jìn)行爬取,?;ňW(wǎng):
  創(chuàng )建xiaohuar spider:
  scrapy genspider xiaohuar xiaohuar.comCreated spider 'xiaohuar' using template 'basic' in module: scrapyproject.spiders.xiaohuar
  準備:

Python爬蟲(chóng)—破解JS加密的Cookie

網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 288 次瀏覽 ? 2022-05-21 02:21 ? 來(lái)自相關(guān)話(huà)題

  Python爬蟲(chóng)—破解JS加密的Cookie
  專(zhuān) 欄
  
  ?Jerry,Python中文社區專(zhuān)欄作者。
  blog:
  github:
  ?前言 在GitHub上維護了一個(gè)代理池的項目,代理來(lái)源是抓取一些免費的代理發(fā)布網(wǎng)站。上午有個(gè)小哥告訴我說(shuō)有個(gè)代理抓取接口不能用了,返回狀態(tài)521。抱著(zhù)幫人解決問(wèn)題的心態(tài)去跑了一遍代碼。發(fā)現果真是這樣。
  通過(guò)Fiddler抓包比較,基本可以確定是JavaScript生成加密Cookie導致原來(lái)的請求返回521。
  發(fā)現問(wèn)題
  打開(kāi)Fiddler軟件,用瀏覽器打開(kāi)目標站點(diǎn)() ??梢园l(fā)現瀏覽器對這個(gè)頁(yè)面加載了兩次,第一次返回521,第二次才正常返回數據。很多沒(méi)有寫(xiě)過(guò)網(wǎng)站或是爬蟲(chóng)經(jīng)驗不足的童鞋,可能就會(huì )覺(jué)得奇怪為什么會(huì )這樣?為什么瀏覽器可能正常返回數據而代碼卻不行?
  
  仔細觀(guān)察兩次返回的結果可以發(fā)現:
  
  
  1、第二次請求比第一次請求的Cookie內容多了個(gè)這個(gè)_ydclearance=0c316df6ea04c5281b421aa8-5570-47ae-9768-2510d9fe971
  2、第一次返回的內容一些復雜看不懂的JS代碼,第二次返回的就是正確的內容
  其實(shí)這是網(wǎng)站反爬蟲(chóng)的常用手段。大致過(guò)程是這樣的:首次請求數據時(shí),服務(wù)端返回動(dòng)態(tài)的混淆加密過(guò)的JS,而這段JS的作用是給Cookie添加新的內容用于服務(wù)端驗證,此時(shí)返回的狀態(tài)碼是521。瀏覽器帶上新的Cookie再次請求,服務(wù)端驗證Cookie通過(guò)返回數據(這也是為嘛代碼不能返回數據的原因)。
  解決問(wèn)題
  其實(shí)我第一次遇到這樣的問(wèn)題是,一開(kāi)始想的就是既然你是用JS生成的Cookie, 那么我也可以將JS函數翻譯成Python運行。但是最后還是發(fā)現我太傻太天真,因為現在的JS都流行混淆加密,原始的JS這樣的:
  <p>function lq(VA) {
   ? ?var qo, mo = "", no = "", oo = [0x8c, 0xcd, 0x4c, 0xf9, 0xd7, 0x4d, 0x25, 0xba, 0x3c, 0x16, 0x96, 0x44, 0x8d, 0x0b, 0x90, 0x1e, 0xa3, 0x39, 0xc9, 0x86, 0x23, 0x61, 0x2f, 0xc8, 0x30, 0xdd, 0x57, 0xec, 0x92, 0x84, 0xc4, 0x6a, 0xeb, 0x99, 0x37, 0xeb, 0x25, 0x0e, 0xbb, 0xb0, 0x95, 0x76, 0x45, 0xde, 0x80, 0x59, 0xf6, 0x9c, 0x58, 0x39, 0x12, 0xc7, 0x9c, 0x8d, 0x18, 0xe0, 0xc5, 0x77, 0x50, 0x39, 0x01, 0xed, 0x93, 0x39, 0x02, 0x7e, 0x72, 0x4f, 0x24, 0x01, 0xe9, 0x66, 0x75, 0x4e, 0x2b, 0xd8, 0x6e, 0xe2, 0xfa, 0xc7, 0xa4, 0x85, 0x4e, 0xc2, 0xa5, 0x96, 0x6b, 0x58, 0x39, 0xd2, 0x7f, 0x44, 0xe5, 0x7b, 0x48, 0x2d, 0xf6, 0xdf, 0xbc, 0x31, 0x1e, 0xf6, 0xbf, 0x84, 0x6d, 0x5e, 0x33, 0x0c, 0x97, 0x5c, 0x39, 0x26, 0xf2, 0x9b, 0x77, 0x0d, 0xd6, 0xc0, 0x46, 0x38, 0x5f, 0xf4, 0xe2, 0x9f, 0xf1, 0x7b, 0xe8, 0xbe, 0x37, 0xdf, 0xd0, 0xbd, 0xb9, 0x36, 0x2c, 0xd1, 0xc3, 0x40, 0xe7, 0xcc, 0xa9, 0x52, 0x3b, 0x20, 0x40, 0x09, 0xe1, 0xd2, 0xa3, 0x80, 0x25, 0x0a, 0xb2, 0xd8, 0xce, 0x21, 0x69, 0x3e, 0xe6, 0x80, 0xfd, 0x73, 0xab, 0x51, 0xde, 0x60, 0x15, 0x95, 0x07, 0x94, 0x6a, 0x18, 0x9d, 0x37, 0x31, 0xde, 0x64, 0xdd, 0x63, 0xe3, 0x57, 0x05, 0x82, 0xff, 0xcc, 0x75, 0x79, 0x63, 0x09, 0xe2, 0x6c, 0x21, 0x5c, 0xe0, 0x7d, 0x4a, 0xf2, 0xd8, 0x9c, 0x22, 0xa3, 0x3d, 0xba, 0xa0, 0xaf, 0x30, 0xc1, 0x47, 0xf4, 0xca, 0xee, 0x64, 0xf9, 0x7b, 0x55, 0xd5, 0xd2, 0x4c, 0xc9, 0x7f, 0x25, 0xfe, 0x48, 0xcd, 0x4b, 0xcc, 0x81, 0x1b, 0x05, 0x82, 0x38, 0x0e, 0x83, 0x19, 0xe3, 0x65, 0x3f, 0xbf, 0x16, 0x88, 0x93, 0xdd, 0x3b];<p> ? ?qo = "qo=241; do{oo[qo]=(-oo[qo])&0xff; oo[qo]=(((oo[qo]>>3)|((oo[qo] 查看全部

  Python爬蟲(chóng)—破解JS加密的Cookie
  專(zhuān) 欄
  
  ?Jerry,Python中文社區專(zhuān)欄作者。
  blog:
  github:
  ?前言 在GitHub上維護了一個(gè)代理池的項目,代理來(lái)源是抓取一些免費的代理發(fā)布網(wǎng)站。上午有個(gè)小哥告訴我說(shuō)有個(gè)代理抓取接口不能用了,返回狀態(tài)521。抱著(zhù)幫人解決問(wèn)題的心態(tài)去跑了一遍代碼。發(fā)現果真是這樣。
  通過(guò)Fiddler抓包比較,基本可以確定是JavaScript生成加密Cookie導致原來(lái)的請求返回521。
  發(fā)現問(wèn)題
  打開(kāi)Fiddler軟件,用瀏覽器打開(kāi)目標站點(diǎn)() ??梢园l(fā)現瀏覽器對這個(gè)頁(yè)面加載了兩次,第一次返回521,第二次才正常返回數據。很多沒(méi)有寫(xiě)過(guò)網(wǎng)站或是爬蟲(chóng)經(jīng)驗不足的童鞋,可能就會(huì )覺(jué)得奇怪為什么會(huì )這樣?為什么瀏覽器可能正常返回數據而代碼卻不行?
  
  仔細觀(guān)察兩次返回的結果可以發(fā)現:
  
  
  1、第二次請求比第一次請求的Cookie內容多了個(gè)這個(gè)_ydclearance=0c316df6ea04c5281b421aa8-5570-47ae-9768-2510d9fe971
  2、第一次返回的內容一些復雜看不懂的JS代碼,第二次返回的就是正確的內容
  其實(shí)這是網(wǎng)站反爬蟲(chóng)的常用手段。大致過(guò)程是這樣的:首次請求數據時(shí),服務(wù)端返回動(dòng)態(tài)的混淆加密過(guò)的JS,而這段JS的作用是給Cookie添加新的內容用于服務(wù)端驗證,此時(shí)返回的狀態(tài)碼是521。瀏覽器帶上新的Cookie再次請求,服務(wù)端驗證Cookie通過(guò)返回數據(這也是為嘛代碼不能返回數據的原因)。
  解決問(wèn)題
  其實(shí)我第一次遇到這樣的問(wèn)題是,一開(kāi)始想的就是既然你是用JS生成的Cookie, 那么我也可以將JS函數翻譯成Python運行。但是最后還是發(fā)現我太傻太天真,因為現在的JS都流行混淆加密,原始的JS這樣的:
  <p>function lq(VA) {
   ? ?var qo, mo = "", no = "", oo = [0x8c, 0xcd, 0x4c, 0xf9, 0xd7, 0x4d, 0x25, 0xba, 0x3c, 0x16, 0x96, 0x44, 0x8d, 0x0b, 0x90, 0x1e, 0xa3, 0x39, 0xc9, 0x86, 0x23, 0x61, 0x2f, 0xc8, 0x30, 0xdd, 0x57, 0xec, 0x92, 0x84, 0xc4, 0x6a, 0xeb, 0x99, 0x37, 0xeb, 0x25, 0x0e, 0xbb, 0xb0, 0x95, 0x76, 0x45, 0xde, 0x80, 0x59, 0xf6, 0x9c, 0x58, 0x39, 0x12, 0xc7, 0x9c, 0x8d, 0x18, 0xe0, 0xc5, 0x77, 0x50, 0x39, 0x01, 0xed, 0x93, 0x39, 0x02, 0x7e, 0x72, 0x4f, 0x24, 0x01, 0xe9, 0x66, 0x75, 0x4e, 0x2b, 0xd8, 0x6e, 0xe2, 0xfa, 0xc7, 0xa4, 0x85, 0x4e, 0xc2, 0xa5, 0x96, 0x6b, 0x58, 0x39, 0xd2, 0x7f, 0x44, 0xe5, 0x7b, 0x48, 0x2d, 0xf6, 0xdf, 0xbc, 0x31, 0x1e, 0xf6, 0xbf, 0x84, 0x6d, 0x5e, 0x33, 0x0c, 0x97, 0x5c, 0x39, 0x26, 0xf2, 0x9b, 0x77, 0x0d, 0xd6, 0xc0, 0x46, 0x38, 0x5f, 0xf4, 0xe2, 0x9f, 0xf1, 0x7b, 0xe8, 0xbe, 0x37, 0xdf, 0xd0, 0xbd, 0xb9, 0x36, 0x2c, 0xd1, 0xc3, 0x40, 0xe7, 0xcc, 0xa9, 0x52, 0x3b, 0x20, 0x40, 0x09, 0xe1, 0xd2, 0xa3, 0x80, 0x25, 0x0a, 0xb2, 0xd8, 0xce, 0x21, 0x69, 0x3e, 0xe6, 0x80, 0xfd, 0x73, 0xab, 0x51, 0xde, 0x60, 0x15, 0x95, 0x07, 0x94, 0x6a, 0x18, 0x9d, 0x37, 0x31, 0xde, 0x64, 0xdd, 0x63, 0xe3, 0x57, 0x05, 0x82, 0xff, 0xcc, 0x75, 0x79, 0x63, 0x09, 0xe2, 0x6c, 0x21, 0x5c, 0xe0, 0x7d, 0x4a, 0xf2, 0xd8, 0x9c, 0x22, 0xa3, 0x3d, 0xba, 0xa0, 0xaf, 0x30, 0xc1, 0x47, 0xf4, 0xca, 0xee, 0x64, 0xf9, 0x7b, 0x55, 0xd5, 0xd2, 0x4c, 0xc9, 0x7f, 0x25, 0xfe, 0x48, 0xcd, 0x4b, 0xcc, 0x81, 0x1b, 0x05, 0x82, 0x38, 0x0e, 0x83, 0x19, 0xe3, 0x65, 0x3f, 0xbf, 0x16, 0x88, 0x93, 0xdd, 0x3b];<p> ? ?qo = "qo=241; do{oo[qo]=(-oo[qo])&0xff; oo[qo]=(((oo[qo]>>3)|((oo[qo]

一只知乎爬蟲(chóng)

網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 202 次瀏覽 ? 2022-05-15 05:53 ? 來(lái)自相關(guān)話(huà)題

  一只知乎爬蟲(chóng)
  本文經(jīng)作者授權發(fā)布。
  文 | 程柳鋒@Tencent
  爬蟲(chóng)的基本流程
  
  網(wǎng)絡(luò )爬蟲(chóng)的基本工作流程如下:
  爬蟲(chóng)的抓取策略
  在爬蟲(chóng)系統中,待抓取 URL 隊列是很重要的一部分。待抓取 URL 隊列中的 URL 以什么樣的順序排列也是一個(gè)很重要的問(wèn)題,因為這涉及到先抓取那個(gè)頁(yè)面,后抓取哪個(gè)頁(yè)面。而決定這些 URL 排列順序的方法,叫做抓取策略。下面重點(diǎn)介紹幾種常見(jiàn)的抓取策略:
  
  了解了爬蟲(chóng)的工作流程和爬取策略后,就可以動(dòng)手實(shí)現一個(gè)爬蟲(chóng)了!那么在 python 里怎么實(shí)現呢?
  技術(shù)?;緦?shí)現
  下面是一個(gè)偽代碼
  <p>import Queue
  initial_page = "https://www.zhihu.com/people/gaoming623"
  url_queue = Queue.Queue()
  seen = set()
  seen.insert(initial_page)
  url_queue.put(initial_page)
  while(True): #一直進(jìn)行
   ? ?if url_queue.size()>0:
   ? ? ? ?current_url = url_queue.get() ? ? ? ? ? ? ?#拿出隊例中第一個(gè)的 url
   ? ? ? ?store(current_url) ? ? ? ? ? ? ? ? ? ? ? ? #把這個(gè) url 代表的網(wǎng)頁(yè)存儲好
   ? ? ? ?for next_url in extract_urls(current_url): #提取把這個(gè) url 里鏈向的 url
   ? ? ? ? ? ?if next_url not in seen: ? ? ?
   ? ? ? ? ? ? ? ?seen.put(next_url)
   ? ? ? ? ? ? ? ?url_queue.put(next_url)
   ? ?else:
   ? ? ? ?break</p>
  如果你直接加工一下上面的代碼直接運行的話(huà),你需要很長(cháng)的時(shí)間才能爬下整個(gè)知乎用戶(hù)的信息,畢竟知乎有 6000 萬(wàn)月活躍用戶(hù)。更別說(shuō) Google 這樣的搜索引擎需要爬下全網(wǎng)的內容了。那么問(wèn)題出現在哪里?
  布隆過(guò)濾器
  需要爬的網(wǎng)頁(yè)實(shí)在太多太多了,而上面的代碼太慢太慢了。設想全網(wǎng)有 N 個(gè)網(wǎng)站,那么分析一下判重的復雜度就是 N*log(N),因為所有網(wǎng)頁(yè)要遍歷一次,而每次判重用 set 的話(huà)需要 log(N) 的復雜度。OK,我知道 python 的 set 實(shí)現是 hash——不過(guò)這樣還是太慢了,至少內存使用效率不高。
  通常的判重做法是怎樣呢?Bloom Filter. 簡(jiǎn)單講它仍然是一種 hash 的方法,但是它的特點(diǎn)是,它可以使用固定的內存(不隨 url 的數量而增長(cháng))以 O(1) 的效率判定 url 是否已經(jīng)在 set 中??上煜聸](méi)有白吃的午餐,它的唯一問(wèn)題在于,如果這個(gè) url 不在 set 中,BF 可以 100%確定這個(gè) url 沒(méi)有看過(guò)。但是如果這個(gè) url 在 set 中,它會(huì )告訴你:這個(gè) url 應該已經(jīng)出現過(guò),不過(guò)我有 2%的不確定性。注意這里的不確定性在你分配的內存足夠大的時(shí)候,可以變得很小很少。
  <p># bloom_filter.py
  BIT_SIZE = 5000000
  class BloomFilter:
   ? ?def __init__(self):
   ? ? ? ?# Initialize bloom filter, set size and all bits to 0
   ? ? ? ?bit_array = bitarray(BIT_SIZE)
   ? ? ? ?bit_array.setall(0)
   ? ? ? ?self.bit_array = bit_array
   ? ?def add(self, url):
   ? ? ? ?# Add a url, and set points in bitarray to 1 (Points count is equal to hash funcs count.)
   ? ? ? ?# Here use 7 hash functions.
   ? ? ? ?point_list = self.get_postions(url)
   ? ? ? ?for b in point_list:
   ? ? ? ? ? ?self.bit_array[b] = 1
   ? ?def contains(self, url):
   ? ? ? ?# Check if a url is in a collection
   ? ? ? ?point_list = self.get_postions(url)
   ? ? ? ?result = True
   ? ? ? ?for b in point_list:
   ? ? ? ? ? ?result = result and self.bit_array[b]
   ? ? ? ?return result
   ? ?def get_postions(self, url):
   ? ? ? ?# Get points positions in bit vector.
   ? ? ? ?point1 = mmh3.hash(url, 41) % BIT_SIZE
   ? ? ? ?point2 = mmh3.hash(url, 42) % BIT_SIZE
   ? ? ? ?point3 = mmh3.hash(url, 43) % BIT_SIZE
   ? ? ? ?point4 = mmh3.hash(url, 44) % BIT_SIZE
   ? ? ? ?point5 = mmh3.hash(url, 45) % BIT_SIZE
   ? ? ? ?point6 = mmh3.hash(url, 46) % BIT_SIZE
   ? ? ? ?point7 = mmh3.hash(url, 47) % BIT_SIZE
   ? ? ? ?return [point1, point2, point3, point4, point5, point6, point7]</p>
  BF 詳細的原理參考我之前寫(xiě)的文章:布隆過(guò)濾器(Bloom Filter) 的原理和實(shí)現
  建表
  用戶(hù)有價(jià)值的信息包括用戶(hù)名、簡(jiǎn)介、行業(yè)、院校、專(zhuān)業(yè)及在平臺上活動(dòng)的數據比如回答數、文章數、提問(wèn)數、粉絲數等等。
  用戶(hù)信息存儲的表結構如下:
  <p>CREATE DATABASE `zhihu_user` /*!40100 DEFAULT CHARACTER SET utf8 */;
  -- User base information table
  CREATE TABLE `t_user` (
   ?`uid` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
   ?`username` varchar(50) NOT NULL COMMENT '用戶(hù)名', ? ? ? ? ? ? ? ? ? ? ?
   ?`brief_info` varchar(400) ?COMMENT '個(gè)人簡(jiǎn)介',
   ?`industry` varchar(50) COMMENT '所處行業(yè)', ? ? ? ? ? ?
   ?`education` varchar(50) COMMENT '畢業(yè)院校', ? ? ? ? ? ?
   ?`major` varchar(50) COMMENT '主修專(zhuān)業(yè)',
   ?`answer_count` int(10) unsigned DEFAULT 0 COMMENT '回答數',
   ?`article_count` int(10) unsigned DEFAULT 0 COMMENT '文章數',
   ?`ask_question_count` int(10) unsigned DEFAULT 0 COMMENT '提問(wèn)數',
   ?`collection_count` int(10) unsigned DEFAULT 0 COMMENT '收藏數',
   ?`follower_count` int(10) unsigned DEFAULT 0 COMMENT '被關(guān)注數',
   ?`followed_count` int(10) unsigned DEFAULT 0 COMMENT '關(guān)注數',
   ?`follow_live_count` int(10) unsigned DEFAULT 0 COMMENT '關(guān)注直播數',
   ?`follow_topic_count` int(10) unsigned DEFAULT 0 COMMENT '關(guān)注話(huà)題數',
   ?`follow_column_count` int(10) unsigned DEFAULT 0 COMMENT '關(guān)注專(zhuān)欄數',
   ?`follow_question_count` int(10) unsigned DEFAULT 0 COMMENT '關(guān)注問(wèn)題數',
   ?`follow_collection_count` int(10) unsigned DEFAULT 0 COMMENT '關(guān)注收藏夾數',
   ?`gmt_create` datetime NOT NULL COMMENT '創(chuàng )建時(shí)間', ?
   ?`gmt_modify` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '最后一次編輯', ? ? ? ? ? ?
   ?PRIMARY KEY (`uid`)
  ) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='用戶(hù)基本信息表';</p>
  網(wǎng)頁(yè)下載后通過(guò) XPath 進(jìn)行解析,提取用戶(hù)各個(gè)維度的數據,最后保存到數據庫中。
  反爬蟲(chóng)策略應對-Headers
  一般網(wǎng)站會(huì )從幾個(gè)維度來(lái)反爬蟲(chóng):用戶(hù)請求的 Headers,用戶(hù)行為,網(wǎng)站和數據加載的方式。從用戶(hù)請求的 Headers 反爬蟲(chóng)是最常見(jiàn)的策略,很多網(wǎng)站都會(huì )對 Headers 的 User-Agent 進(jìn)行檢測,還有一部分網(wǎng)站會(huì )對 Referer 進(jìn)行檢測(一些資源網(wǎng)站的防盜鏈就是檢測 Referer)。
  如果遇到了這類(lèi)反爬蟲(chóng)機制,可以直接在爬蟲(chóng)中添加 Headers,將瀏覽器的 User-Agent 復制到爬蟲(chóng)的 Headers 中;或者將 Referer 值修改為目標網(wǎng)站域名。對于檢測 Headers 的反爬蟲(chóng),在爬蟲(chóng)中修改或者添加 Headers 就能很好的繞過(guò)。
  <p>cookies = {
   ? ?"d_c0": "AECA7v-aPwqPTiIbemmIQ8abhJy7bdD2VgE=|1468847182",
   ? ?"login": "NzM5ZDc2M2JkYzYwNDZlOGJlYWQ1YmI4OTg5NDhmMTY=|1480901173|9c296f424b32f241d1471203244eaf30729420f0",
   ? ?"n_c": "1",
   ? ?"q_c1": "395b12e529e541cbb400e9718395e346|1479808003000|1468847182000",
   ? ?"l_cap_id": "NzI0MTQwZGY2NjQyNDQ1NThmYTY0MjJhYmU2NmExMGY=|1480901160|2e7a7faee3b3e8d0afb550e8e7b38d86c15a31bc",
   ? ?"d_c0": "AECA7v-aPwqPTiIbemmIQ8abhJy7bdD2VgE=|1468847182",
   ? ?"cap_id": "N2U1NmQwODQ1NjFiNGI2Yzg2YTE2NzJkOTU5N2E0NjI=|1480901160|fd59e2ed79faacc2be1010687d27dd559ec1552a"
  }
  headers = {
   ? ?"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.98 Safari/537.3",
   ? ?"Referer": "https://www.zhihu.com/"
  }
  r = requests.get(url, cookies = cookies, headers = headers)</p>
  反爬蟲(chóng)策略應對-代理 IP 池
  還有一部分網(wǎng)站是通過(guò)檢測用戶(hù)行為,例如同一 IP 短時(shí)間內多次訪(fǎng)問(wèn)同一頁(yè)面,或者同一賬戶(hù)短時(shí)間內多次進(jìn)行相同操作。
  大多數網(wǎng)站都是前一種情況,對于這種情況,使用 IP 代理就可以解決。這樣的代理 ip 爬蟲(chóng)經(jīng)常會(huì )用到,最好自己準備一個(gè)。有了大量代理 ip 后可以每請求幾次更換一個(gè) ip,這在 requests 或者 urllib2 中很容易做到,這樣就能很容易的繞過(guò)第一種反爬蟲(chóng)。目前知乎已經(jīng)對爬蟲(chóng)做了限制,如果是單個(gè) IP 的話(huà),一段時(shí)間系統便會(huì )提示異常流量,無(wú)法繼續爬取了。因此代理 IP 池非常關(guān)鍵。網(wǎng)上有個(gè)免費的代理 IP API:
  <p>import requests
  import random
  class Proxy:
   ? ?def __init__(self):
   ? ? ? ?self.cache_ip_list = []
   ? ?# Get random ip from free proxy api url.
   ? ?def get_random_ip(self):
   ? ? ? ?if not len(self.cache_ip_list):
   ? ? ? ? ? ?api_url = 'http://api.xicidaili.com/free2016.txt'
   ? ? ? ? ? ?try:
   ? ? ? ? ? ? ? ?r = requests.get(api_url)
   ? ? ? ? ? ? ? ?ip_list = r.text.split('rn')
   ? ? ? ? ? ? ? ?self.cache_ip_list = ip_list
   ? ? ? ? ? ?except Exception as e:
   ? ? ? ? ? ? ? ?# Return null list when caught exception.
   ? ? ? ? ? ? ? ?# In this case, crawler will not use proxy ip.
   ? ? ? ? ? ? ? ?print e
   ? ? ? ? ? ? ? ?return {}
   ? ? ? ?proxy_ip = random.choice(self.cache_ip_list)
   ? ? ? ?proxies = {'http': 'http://' ? proxy_ip}
   ? ? ? ?return proxies</p>
  后續
  爬蟲(chóng)源代碼:zhihu-crawler下載之后通過(guò) pip 安裝相關(guān)三方包后,運行$ python crawler.py 即可(喜歡的幫忙點(diǎn)個(gè) star 哈,同時(shí)也方便看到后續功能的更新)
  運行截圖:
   查看全部

  一只知乎爬蟲(chóng)
  本文經(jīng)作者授權發(fā)布。
  文 | 程柳鋒@Tencent
  爬蟲(chóng)的基本流程
  
  網(wǎng)絡(luò )爬蟲(chóng)的基本工作流程如下:
  爬蟲(chóng)的抓取策略
  在爬蟲(chóng)系統中,待抓取 URL 隊列是很重要的一部分。待抓取 URL 隊列中的 URL 以什么樣的順序排列也是一個(gè)很重要的問(wèn)題,因為這涉及到先抓取那個(gè)頁(yè)面,后抓取哪個(gè)頁(yè)面。而決定這些 URL 排列順序的方法,叫做抓取策略。下面重點(diǎn)介紹幾種常見(jiàn)的抓取策略:
  
  了解了爬蟲(chóng)的工作流程和爬取策略后,就可以動(dòng)手實(shí)現一個(gè)爬蟲(chóng)了!那么在 python 里怎么實(shí)現呢?
  技術(shù)?;緦?shí)現
  下面是一個(gè)偽代碼
  <p>import Queue
  initial_page = "https://www.zhihu.com/people/gaoming623"
  url_queue = Queue.Queue()
  seen = set()
  seen.insert(initial_page)
  url_queue.put(initial_page)
  while(True): #一直進(jìn)行
   ? ?if url_queue.size()>0:
   ? ? ? ?current_url = url_queue.get() ? ? ? ? ? ? ?#拿出隊例中第一個(gè)的 url
   ? ? ? ?store(current_url) ? ? ? ? ? ? ? ? ? ? ? ? #把這個(gè) url 代表的網(wǎng)頁(yè)存儲好
   ? ? ? ?for next_url in extract_urls(current_url): #提取把這個(gè) url 里鏈向的 url
   ? ? ? ? ? ?if next_url not in seen: ? ? ?
   ? ? ? ? ? ? ? ?seen.put(next_url)
   ? ? ? ? ? ? ? ?url_queue.put(next_url)
   ? ?else:
   ? ? ? ?break</p>
  如果你直接加工一下上面的代碼直接運行的話(huà),你需要很長(cháng)的時(shí)間才能爬下整個(gè)知乎用戶(hù)的信息,畢竟知乎有 6000 萬(wàn)月活躍用戶(hù)。更別說(shuō) Google 這樣的搜索引擎需要爬下全網(wǎng)的內容了。那么問(wèn)題出現在哪里?
  布隆過(guò)濾器
  需要爬的網(wǎng)頁(yè)實(shí)在太多太多了,而上面的代碼太慢太慢了。設想全網(wǎng)有 N 個(gè)網(wǎng)站,那么分析一下判重的復雜度就是 N*log(N),因為所有網(wǎng)頁(yè)要遍歷一次,而每次判重用 set 的話(huà)需要 log(N) 的復雜度。OK,我知道 python 的 set 實(shí)現是 hash——不過(guò)這樣還是太慢了,至少內存使用效率不高。
  通常的判重做法是怎樣呢?Bloom Filter. 簡(jiǎn)單講它仍然是一種 hash 的方法,但是它的特點(diǎn)是,它可以使用固定的內存(不隨 url 的數量而增長(cháng))以 O(1) 的效率判定 url 是否已經(jīng)在 set 中??上煜聸](méi)有白吃的午餐,它的唯一問(wèn)題在于,如果這個(gè) url 不在 set 中,BF 可以 100%確定這個(gè) url 沒(méi)有看過(guò)。但是如果這個(gè) url 在 set 中,它會(huì )告訴你:這個(gè) url 應該已經(jīng)出現過(guò),不過(guò)我有 2%的不確定性。注意這里的不確定性在你分配的內存足夠大的時(shí)候,可以變得很小很少。
  <p># bloom_filter.py
  BIT_SIZE = 5000000
  class BloomFilter:
   ? ?def __init__(self):
   ? ? ? ?# Initialize bloom filter, set size and all bits to 0
   ? ? ? ?bit_array = bitarray(BIT_SIZE)
   ? ? ? ?bit_array.setall(0)
   ? ? ? ?self.bit_array = bit_array
   ? ?def add(self, url):
   ? ? ? ?# Add a url, and set points in bitarray to 1 (Points count is equal to hash funcs count.)
   ? ? ? ?# Here use 7 hash functions.
   ? ? ? ?point_list = self.get_postions(url)
   ? ? ? ?for b in point_list:
   ? ? ? ? ? ?self.bit_array[b] = 1
   ? ?def contains(self, url):
   ? ? ? ?# Check if a url is in a collection
   ? ? ? ?point_list = self.get_postions(url)
   ? ? ? ?result = True
   ? ? ? ?for b in point_list:
   ? ? ? ? ? ?result = result and self.bit_array[b]
   ? ? ? ?return result
   ? ?def get_postions(self, url):
   ? ? ? ?# Get points positions in bit vector.
   ? ? ? ?point1 = mmh3.hash(url, 41) % BIT_SIZE
   ? ? ? ?point2 = mmh3.hash(url, 42) % BIT_SIZE
   ? ? ? ?point3 = mmh3.hash(url, 43) % BIT_SIZE
   ? ? ? ?point4 = mmh3.hash(url, 44) % BIT_SIZE
   ? ? ? ?point5 = mmh3.hash(url, 45) % BIT_SIZE
   ? ? ? ?point6 = mmh3.hash(url, 46) % BIT_SIZE
   ? ? ? ?point7 = mmh3.hash(url, 47) % BIT_SIZE
   ? ? ? ?return [point1, point2, point3, point4, point5, point6, point7]</p>
  BF 詳細的原理參考我之前寫(xiě)的文章:布隆過(guò)濾器(Bloom Filter) 的原理和實(shí)現
  建表
  用戶(hù)有價(jià)值的信息包括用戶(hù)名、簡(jiǎn)介、行業(yè)、院校、專(zhuān)業(yè)及在平臺上活動(dòng)的數據比如回答數、文章數、提問(wèn)數、粉絲數等等。
  用戶(hù)信息存儲的表結構如下:
  <p>CREATE DATABASE `zhihu_user` /*!40100 DEFAULT CHARACTER SET utf8 */;
  -- User base information table
  CREATE TABLE `t_user` (
   ?`uid` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
   ?`username` varchar(50) NOT NULL COMMENT '用戶(hù)名', ? ? ? ? ? ? ? ? ? ? ?
   ?`brief_info` varchar(400) ?COMMENT '個(gè)人簡(jiǎn)介',
   ?`industry` varchar(50) COMMENT '所處行業(yè)', ? ? ? ? ? ?
   ?`education` varchar(50) COMMENT '畢業(yè)院校', ? ? ? ? ? ?
   ?`major` varchar(50) COMMENT '主修專(zhuān)業(yè)',
   ?`answer_count` int(10) unsigned DEFAULT 0 COMMENT '回答數',
   ?`article_count` int(10) unsigned DEFAULT 0 COMMENT '文章數',
   ?`ask_question_count` int(10) unsigned DEFAULT 0 COMMENT '提問(wèn)數',
   ?`collection_count` int(10) unsigned DEFAULT 0 COMMENT '收藏數',
   ?`follower_count` int(10) unsigned DEFAULT 0 COMMENT '被關(guān)注數',
   ?`followed_count` int(10) unsigned DEFAULT 0 COMMENT '關(guān)注數',
   ?`follow_live_count` int(10) unsigned DEFAULT 0 COMMENT '關(guān)注直播數',
   ?`follow_topic_count` int(10) unsigned DEFAULT 0 COMMENT '關(guān)注話(huà)題數',
   ?`follow_column_count` int(10) unsigned DEFAULT 0 COMMENT '關(guān)注專(zhuān)欄數',
   ?`follow_question_count` int(10) unsigned DEFAULT 0 COMMENT '關(guān)注問(wèn)題數',
   ?`follow_collection_count` int(10) unsigned DEFAULT 0 COMMENT '關(guān)注收藏夾數',
   ?`gmt_create` datetime NOT NULL COMMENT '創(chuàng )建時(shí)間', ?
   ?`gmt_modify` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '最后一次編輯', ? ? ? ? ? ?
   ?PRIMARY KEY (`uid`)
  ) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='用戶(hù)基本信息表';</p>
  網(wǎng)頁(yè)下載后通過(guò) XPath 進(jìn)行解析,提取用戶(hù)各個(gè)維度的數據,最后保存到數據庫中。
  反爬蟲(chóng)策略應對-Headers
  一般網(wǎng)站會(huì )從幾個(gè)維度來(lái)反爬蟲(chóng):用戶(hù)請求的 Headers,用戶(hù)行為,網(wǎng)站和數據加載的方式。從用戶(hù)請求的 Headers 反爬蟲(chóng)是最常見(jiàn)的策略,很多網(wǎng)站都會(huì )對 Headers 的 User-Agent 進(jìn)行檢測,還有一部分網(wǎng)站會(huì )對 Referer 進(jìn)行檢測(一些資源網(wǎng)站的防盜鏈就是檢測 Referer)。
  如果遇到了這類(lèi)反爬蟲(chóng)機制,可以直接在爬蟲(chóng)中添加 Headers,將瀏覽器的 User-Agent 復制到爬蟲(chóng)的 Headers 中;或者將 Referer 值修改為目標網(wǎng)站域名。對于檢測 Headers 的反爬蟲(chóng),在爬蟲(chóng)中修改或者添加 Headers 就能很好的繞過(guò)。
  <p>cookies = {
   ? ?"d_c0": "AECA7v-aPwqPTiIbemmIQ8abhJy7bdD2VgE=|1468847182",
   ? ?"login": "NzM5ZDc2M2JkYzYwNDZlOGJlYWQ1YmI4OTg5NDhmMTY=|1480901173|9c296f424b32f241d1471203244eaf30729420f0",
   ? ?"n_c": "1",
   ? ?"q_c1": "395b12e529e541cbb400e9718395e346|1479808003000|1468847182000",
   ? ?"l_cap_id": "NzI0MTQwZGY2NjQyNDQ1NThmYTY0MjJhYmU2NmExMGY=|1480901160|2e7a7faee3b3e8d0afb550e8e7b38d86c15a31bc",
   ? ?"d_c0": "AECA7v-aPwqPTiIbemmIQ8abhJy7bdD2VgE=|1468847182",
   ? ?"cap_id": "N2U1NmQwODQ1NjFiNGI2Yzg2YTE2NzJkOTU5N2E0NjI=|1480901160|fd59e2ed79faacc2be1010687d27dd559ec1552a"
  }
  headers = {
   ? ?"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.98 Safari/537.3",
   ? ?"Referer": "https://www.zhihu.com/"
  }
  r = requests.get(url, cookies = cookies, headers = headers)</p>
  反爬蟲(chóng)策略應對-代理 IP 池
  還有一部分網(wǎng)站是通過(guò)檢測用戶(hù)行為,例如同一 IP 短時(shí)間內多次訪(fǎng)問(wèn)同一頁(yè)面,或者同一賬戶(hù)短時(shí)間內多次進(jìn)行相同操作。
  大多數網(wǎng)站都是前一種情況,對于這種情況,使用 IP 代理就可以解決。這樣的代理 ip 爬蟲(chóng)經(jīng)常會(huì )用到,最好自己準備一個(gè)。有了大量代理 ip 后可以每請求幾次更換一個(gè) ip,這在 requests 或者 urllib2 中很容易做到,這樣就能很容易的繞過(guò)第一種反爬蟲(chóng)。目前知乎已經(jīng)對爬蟲(chóng)做了限制,如果是單個(gè) IP 的話(huà),一段時(shí)間系統便會(huì )提示異常流量,無(wú)法繼續爬取了。因此代理 IP 池非常關(guān)鍵。網(wǎng)上有個(gè)免費的代理 IP API:
  <p>import requests
  import random
  class Proxy:
   ? ?def __init__(self):
   ? ? ? ?self.cache_ip_list = []
   ? ?# Get random ip from free proxy api url.
   ? ?def get_random_ip(self):
   ? ? ? ?if not len(self.cache_ip_list):
   ? ? ? ? ? ?api_url = 'http://api.xicidaili.com/free2016.txt'
   ? ? ? ? ? ?try:
   ? ? ? ? ? ? ? ?r = requests.get(api_url)
   ? ? ? ? ? ? ? ?ip_list = r.text.split('rn')
   ? ? ? ? ? ? ? ?self.cache_ip_list = ip_list
   ? ? ? ? ? ?except Exception as e:
   ? ? ? ? ? ? ? ?# Return null list when caught exception.
   ? ? ? ? ? ? ? ?# In this case, crawler will not use proxy ip.
   ? ? ? ? ? ? ? ?print e
   ? ? ? ? ? ? ? ?return {}
   ? ? ? ?proxy_ip = random.choice(self.cache_ip_list)
   ? ? ? ?proxies = {'http': 'http://' ? proxy_ip}
   ? ? ? ?return proxies</p>
  后續
  爬蟲(chóng)源代碼:zhihu-crawler下載之后通過(guò) pip 安裝相關(guān)三方包后,運行$ python crawler.py 即可(喜歡的幫忙點(diǎn)個(gè) star 哈,同時(shí)也方便看到后續功能的更新)
  運行截圖:
  

官方客服QQ群

微信人工客服

QQ人工客服


線(xiàn)

亚洲国产精品无码久久大片,亚洲AV无码乱码麻豆精品国产,亚洲品质自拍网站,少妇伦子伦精品无码STYLES,国产精久久久久久久