1. 程式人生 > >一個月帶你入門Python爬蟲,輕鬆爬取大規模資料

一個月帶你入門Python爬蟲,輕鬆爬取大規模資料

640?wx_fmt=jpeg&wxfrom=5&wx_lazy=1

Python爬蟲為什麼受歡迎

如果你仔細觀察,就不難發現,懂爬蟲、學習爬蟲的人越來越多,一方面,網際網路可以獲取的資料越來越多,另一方面,像 Python這樣的程式語言提供越來越多的優秀工具,讓爬蟲變得簡單、容易上手。

利用爬蟲我們可以獲取大量的價值資料,從而獲得感性認識中不能得到的資訊,比如:

知乎:爬取優質答案,為你篩選出各話題下最優質的內容。

淘寶、京東:抓取商品、評論及銷量資料,對各種商品及使用者的消費場景進行分析。

安居客、鏈家:抓取房產買賣及租售資訊,分析房價變化趨勢、做不同區域的房價分析。

拉勾網、智聯:爬取各類職位資訊,分析各行業人才需求情況及薪資水平。

雪球網:抓取雪球高回報使用者的行為,對股票市場進行分析和預測。

對於小白來說,爬蟲可能是一件非常複雜、技術門檻很高的事情。比如有人認為學爬蟲必須精通 Python,然後哼哧哼哧系統學習 Python 的每個知識點,很久之後發現仍然爬不了資料;有的人則認為先要掌握網頁的知識,遂開始 HTMLCSS,結果入了前端的坑,瘁……

但掌握正確的方法,在短時間內做到能夠爬取主流網站的資料,其實非常容易實現,但建議你從一開始就要有一個具體的目標。

在目標的驅動下,你的學習才會更加精準和高效。那些所有你認為必須的前置知識,都是可以在完成目標的過程中學到的。這裡給你一條平滑的、零基礎快速入門的學習路徑。

1.學習 Python 包並實現基本的爬蟲過程

2.瞭解非結構化資料的儲存

3.學習scrapy,搭建工程化爬蟲

4.學習資料庫知識,應對大規模資料儲存與提取

5.掌握各種技巧,應對特殊網站的反爬措施

6.分散式爬蟲,實現大規模併發採集,提升效率

- ❶ -

學習 Python 包並實現基本的爬蟲過程

大部分爬蟲都是按“傳送請求——獲得頁面——解析頁面——抽取並儲存內容”這樣的流程來進行,這其實也是模擬了我們使用瀏覽器獲取網頁資訊的過程。

Python中爬蟲相關的包很多:urllib、requests、bs4、scrapy、pyspider 等,建議從requests+Xpath 開始,requests 負責連線網站,返回網頁,Xpath 用於解析網頁,便於抽取資料。

如果你用過 BeautifulSoup,會發現 Xpath 要省事不少,一層一層檢查元素程式碼的工作,全都省略了。這樣下來基本套路都差不多,一般的靜態網站根本不在話下,豆瓣、糗事百科、騰訊新聞等基本上都可以上手了

當然如果你需要爬取非同步載入的網站,可以學習瀏覽器抓包分析真實請求或者學習Selenium來實現自動化,這樣,知乎、時光網、貓途鷹這些動態的網站也可以迎刃而解

- ❷ -

瞭解非結構化資料的儲存

爬回來的資料可以直接用文件形式存在本地,也可以存入資料庫中。

開始資料量不大的時候,你可以直接通過 Python 的語法或 pandas 的方法將資料存為csv這樣的檔案

當然你可能發現爬回來的資料並不是乾淨的,可能會有缺失、錯誤等等,你還需要對資料進行清洗,可以學習 pandas 包的基本用法來做資料的預處理,得到更乾淨的資料。

- ❸ -

學習 scrapy,搭建工程化的爬蟲

掌握前面的技術一般量級的資料和程式碼基本沒有問題了,但是在遇到非常複雜的情況,可能仍然會力不從心,這個時候,強大的 scrapy 框架就非常有用了。

scrapy 是一個功能非常強大的爬蟲框架,它不僅能便捷地構建request,還有強大的 selector 能夠方便地解析 response,然而它最讓人驚喜的還是它超高的效能,讓你可以將爬蟲工程化、模組化。

學會 scrapy,你可以自己去搭建一些爬蟲框架,你就基本具備爬蟲工程師的思維了。

- ❹ -

學習資料庫基礎,應對大規模資料儲存

爬回來的資料量小的時候,你可以用文件的形式來儲存,一旦資料量大了,這就有點行不通了。所以掌握一種資料庫是必須的,學習目前比較主流的 MongoDB 就OK。

MongoDB 可以方便你去儲存一些非結構化的資料,比如各種評論的文字,圖片的連結等等。你也可以利用PyMongo,更方便地在Python中操作MongoDB。

因為這裡要用到的資料庫知識其實非常簡單,主要是資料如何入庫、如何進行提取,在需要的時候再學習就行。

- ❺ -

掌握各種技巧,應對特殊網站的反爬措施

當然,爬蟲過程中也會經歷一些絕望啊,比如被網站封IP、比如各種奇怪的驗證碼、userAgent訪問限制、各種動態載入等等。

遇到這些反爬蟲的手段,當然還需要一些高階的技巧來應對,常規的比如訪問頻率控制、使用代理IP池、抓包、驗證碼的OCR處理等等

往往網站在高效開發和反爬蟲之間會偏向前者,這也為爬蟲提供了空間,掌握這些應對反爬蟲的技巧,絕大部分的網站已經難不到你了

- ❻ -

分散式爬蟲,實現大規模併發採集

爬取基本資料已經不是問題了,你的瓶頸會集中到爬取海量資料的效率。這個時候,相信你會很自然地接觸到一個很厲害的名字:分散式爬蟲

分散式這個東西,聽起來很恐怖,但其實就是利用多執行緒的原理讓多個爬蟲同時工作,需要你掌握 Scrapy + MongoDB + Redis 這三種工具

Scrapy 前面我們說過了,用於做基本的頁面爬取,MongoDB 用於儲存爬取的資料,Redis 則用來儲存要爬取的網頁佇列,也就是任務佇列。

所以有些東西看起來很嚇人,但其實分解開來,也不過如此。當你能夠寫分散式的爬蟲的時候,那麼你可以去嘗試打造一些基本的爬蟲架構了,實現一些更加自動化的資料獲取。

你看,這一條學習路徑下來,你已然可以成為老司機了,非常的順暢。所以在一開始的時候,儘量不要系統地去啃一些東西,找一個實際的專案(開始可以從豆瓣、小豬這種簡單的入手),直接開始就好

因為爬蟲這種技術,既不需要你係統地精通一門語言,也不需要多麼高深的資料庫技術,高效的姿勢就是從實際的專案中去學習這些零散的知識點,你能保證每次學到的都是最需要的那部分。

當然唯一麻煩的是,在具體的問題中,如何找到具體需要的那部分學習資源、如何篩選和甄別,是很多初學者面臨的一個大問題。

最後還是要推薦下小編的Python學習群: 639584010,不管你是小白還是大牛,小編我都歡迎,不定期分享乾貨,包括小編自己整理的一份2017最新的Python資料和0基礎入門教程,歡迎初學和進階中的小夥伴。

每天晚上20:30我都會開直播給大家分享Python學習知識和路線方法,群裡會不定期更新最新的教程和學習方法(進群送2017Python學習教程),大家都是學習Python的,或是轉行,或是大學生,還有工作中想提升自己能力的Python黨,如果你是正在學習Python的小夥伴可以加入學習。最後祝所有程式設計師都能夠走上人生巔峰,讓程式碼將夢想照進現實,非常適合新手學習,有不懂的問題可以隨時問我,工作不忙的時候希望可以給大家解惑。

前面幾節給大家分享了Python的類,今天繼續更新,也是關於Python類的最後分享。

關於類的知識點裡面,有一塊是關於多重繼承,跟其他主流語言一樣,Python也支援多重繼承,多重繼承雖然有一些好處,但是坑很多,我們今天就來聊一聊Python多重繼承裡面的坑.

先來看一下語法,Python多重繼承的語法很簡單:

class subClass(Base1,Base2)

這相當於你建立了一個subClass的類,讓它同時繼承Base1,Base2,一旦你在subClass的例項上有任何隱式動作,Python會回到類的層級結構中去檢查Base1,Base2,而且必須要用固定的次序去檢查,為了搞定這一點Python用了一個MRO去搜索

要點:

  • 多重繼承的初始化順序

  • 菱形多重繼承的初始化順序

  • 迷一樣的MRO

  • 經典類和新式類的MRO區別

1坑1-多重繼承內的初始化順序

先看一個簡單的例子,有一個子類subClass,繼承3個父類BaseClass,TimesTwo,PlusFive.看看這樣的結構內的類的初始化順序是怎麼樣的

0?wx_fmt=jpeg

0?wx_fmt=jpeg

>>

Init BaseClass

value is :1

Init TimesTwo

value is :2

Init PlusFive

value is :7

7

那麼我們把子類裡面多重繼承的父類的順序換一下:繼承3個父類BaseClass,PlusFive,TimesTwo.

0?wx_fmt=jpeg

>>

Init BaseClass

value is :1

Init TimesTwo

value is :2

Init PlusFive

value is :7

7

我們發現雖然我們多重繼承的順序是BaseClass,PlusFive,TimesTwo,但是實際執行的結果:卻還是是BaseClass,TimesTwo,PlusFive,奇怪為啥會這樣呢,我們接著往下看~~

2坑2.菱形多重繼承中初始化問題

當一個子類繼承2個父類,而2個父類又都繼承一個基類,構成了一個菱形.

0?wx_fmt=jpeg

0?wx_fmt=jpeg

>>

Init BaseClass

value is :1

Init TimesTwo

value is :2

Init BaseClass

value is :1

Init PlusFive

value is :6

6

正確的結果我們是想1*2+5=7,但是實際是6,為啥呢

因為菱形繼承的問題,在呼叫第二個超類的構造器PlusFive.__init__()的時候, 它會再度去呼叫BaseClass.__init__(),從而導致self.value重新變成1.

那麼用內建函式super()是不是可以解決這個問題

0?wx_fmt=jpeg

>>

Init BaseClass

value is :1

Init PlusFive

value is :6

Init TimesTwo

value is :12

12

super()確實可以保證菱形頂部的公共基類的__init__()方法只會執行一次,但是執行的結果好像不是我們期望的.我們期望的是1*2+5=7,但是實際執行卻是(1+5)*2=12了,奇怪為啥會這樣呢

3迷一樣的MRO

  • 上面兩個問題的根源都跟MRO有關,MRO(Method Resolution Order)也叫方法解析順序,主要用於在多重繼承時判斷調的屬性的路徑(來自於哪個類)

  • 那麼我們現在來看一下上面的例子,到底是怎麼個搜素的呢~~

  • 我們引入Python內建模組pprint(這個Python的一個列印資料結構的模組)

0?wx_fmt=jpeg

  • 我們呼叫SubClass的時候,它會呼叫TimesTwo.__init__(),而TimesTwo.__init__()又會呼叫PlusFive.__init__(),PlusFive.__init__()再去調BaseClass.__init__(),到達菱形體系的頂部

  • 注意關鍵的地方來了,所有的初始化方法會按照跟那些__init__()相反的順序來執行.

也就是如下的初始化順序:

1)BaseClass__init__()會把value設為1

2)PlusFive.__init__()會把value加5,然後value變成6

3)TimesTwo.__init__()會把value乘以2,然後value變成12

4經典類和新式類的MRO區別

  • 因為Python的類中有兩種:一種經典類,一種新式類(什麼你不知道什麼叫新式類,看我歷史文章:Python的類,複雜嗎

  • 在經典類中MRO搜尋採用簡單的從左到右的深度優先順序,而新式類是廣度優先,不信我給你舉個例子

0?wx_fmt=jpeg

#先看經典類

0?wx_fmt=jpeg

>>

I can show the information of A

return value of B

當用經典類實現的時候,我們發現呼叫的A類中的show()方法和B類的getValue()方法

#再看新式類

0?wx_fmt=jpeg

>>

I can show the information of C

return value of B

變成新式類的時候,結果變成了呼叫C類的show()方法和B類的getValue()方法.

差別的根源就是上面時候的經典類和新式類採用的MRO差異.

結論:

  • 不惜一切代價地避免多重繼承,它帶來的麻煩比能解決的問題都多。如果你非要用,那你得準備好專研類的層次結構,以及花時間去找各種東西的來龍去脈吧

  • 只有在程式碼之間有清楚的關聯,可以通過一個單獨的共性聯絡起來的時候使用繼承,或者你受現有程式碼所限非用不可的話,那也用吧

  • 或者可以試試組合,組合則是利用模組和別的類中的函式呼叫實現了相同的目的

好了Python多重繼承就講到這裡啦,希望能給初學者一些啟發,若有什麼不懂的,也可以留言跟我探討交流.

最後說一下,原創真的不易,希望大家能夠給點支援,歡迎轉發轉發轉發,留言留言留言,重要的事情說三遍,也是對我的一點鼓勵和動力.

下面是我的Python學習交流群,歡迎大家一起進來一起學習交流。

0?wx_fmt=jpeg