如何用Python爬數(shù)據(jù)?(一)網(wǎng)頁(yè)抓取
你期待已久的Python網(wǎng)絡(luò)數(shù)據(jù)爬蟲教程來(lái)了。本文為你演示如何從網(wǎng)頁(yè)里找到感興趣的鏈接和說(shuō)明文字,抓取并存儲(chǔ)到Excel。
需求
我在公眾號(hào)后臺(tái),經(jīng)常可以收到讀者的留言。
很多留言,是讀者的疑問(wèn)。只要有時(shí)間,我都會(huì)抽空嘗試解答。
但是有的留言,乍看起來(lái)就不明所以了。
例如下面這個(gè):
一分鐘后,他可能覺(jué)得不妥(大概因?yàn)橄肫饋?lái),我用簡(jiǎn)體字寫文章),于是又用簡(jiǎn)體發(fā)了一遍。
我恍然大悟。
這位讀者以為我的公眾號(hào)設(shè)置了關(guān)鍵詞推送對(duì)應(yīng)文章功能。所以看了我的其他數(shù)據(jù)科學(xué)教程后,想看“爬蟲”專題。
不好意思,當(dāng)時(shí)我還沒(méi)有寫爬蟲文章。
而且,我的公眾號(hào)暫時(shí)也沒(méi)有設(shè)置這種關(guān)鍵詞推送。
主要是因?yàn)槲覒小?/p>
這樣的消息接收得多了,我也能體察到讀者的需求。不止一個(gè)讀者表達(dá)出對(duì)爬蟲教程的興趣。
之前提過(guò),目前主流而合法的網(wǎng)絡(luò)數(shù)據(jù)收集方法,主要分為3類:
- 開放數(shù)據(jù)集下載;
- API讀?。?/li>
- 爬蟲。
前兩種方法,我都已經(jīng)做過(guò)一些介紹,這次說(shuō)說(shuō)爬蟲。
概念
許多讀者對(duì)爬蟲的定義,有些混淆。咱們有必要辨析一下。
維基百科是這么說(shuō)的:
網(wǎng)絡(luò)爬蟲(英語(yǔ):web crawler),也叫網(wǎng)絡(luò)蜘蛛(spider),是一種用來(lái)自動(dòng)瀏覽萬(wàn)維網(wǎng)的網(wǎng)絡(luò)機(jī)器人。其目的一般為編纂網(wǎng)絡(luò)索引。
這問(wèn)題就來(lái)了,你又不打算做搜索引擎,為什么對(duì)網(wǎng)絡(luò)爬蟲那么熱心呢?
其實(shí),許多人口中所說(shuō)的爬蟲(web crawler),跟另外一種功能“網(wǎng)頁(yè)抓取”(web scraping)搞混了。
維基百科上,對(duì)于后者這樣解釋:
Web scraping, web harvesting, or web data extraction is data scraping used for extracting data from websites. Web scraping software may access the World Wide Web directly using the Hypertext Transfer Protocol, or through a web browser.
看到?jīng)]有,即便你用瀏覽器手動(dòng)拷貝數(shù)據(jù)下來(lái),也叫做網(wǎng)頁(yè)抓取(web scraping)。是不是立刻覺(jué)得自己強(qiáng)大了很多?
但是,這定義還沒(méi)完:
While web scraping can be done manually by a software user, the term typically refers to automate processes implemented using a bot or web crawler.
也就是說(shuō),用爬蟲(或者機(jī)器人)自動(dòng)替你完成網(wǎng)頁(yè)抓取工作,才是你真正想要的。
數(shù)據(jù)抓下來(lái)干什么呢?
一般是先存儲(chǔ)起來(lái),放到數(shù)據(jù)庫(kù)或者電子表格中,以備檢索或者進(jìn)一步分析使用。
所以,你真正想要的功能是這樣的:
找到鏈接,獲得Web頁(yè)面,抓取指定信息,存儲(chǔ)。
這個(gè)過(guò)程有可能會(huì)往復(fù)循環(huán),甚至是滾雪球。
你希望用自動(dòng)化的方式來(lái)完成它。
了解了這一點(diǎn),你就不要老盯著爬蟲不放了。爬蟲研制出來(lái),其實(shí)是為了給搜索引擎編制索引數(shù)據(jù)庫(kù)使用的。你為了抓取點(diǎn)兒數(shù)據(jù)拿來(lái)使用,已經(jīng)是大炮轟蚊子了。
要真正掌握爬蟲,你需要具備不少基礎(chǔ)知識(shí)。例如HTML, CSS, Javascript, 數(shù)據(jù)結(jié)構(gòu)……
這也是為什么我一直猶豫著沒(méi)有寫爬蟲教程的原因。
不過(guò)這兩天,看到王爍主編的一段話,很有啟發(fā):
我喜歡講一個(gè)另類二八定律,就是付出兩成努力,了解一件事的八成。
既然我們的目標(biāo)很明確,就是要從網(wǎng)頁(yè)抓取數(shù)據(jù)。那么你需要掌握的最重要能力,是拿到一個(gè)網(wǎng)頁(yè)鏈接后,如何從中快捷有效地抓取自己想要的信息。
掌握了它,你還不能說(shuō)自己已經(jīng)學(xué)會(huì)了爬蟲。
但有了這個(gè)基礎(chǔ),你就能比之前更輕松獲取數(shù)據(jù)了。特別是對(duì)“文科生”的很多應(yīng)用場(chǎng)景來(lái)說(shuō),非常有用。這就是賦能。
而且,再進(jìn)一步深入理解爬蟲的工作原理,也變得輕松許多。
這也算“另類二八定律”的一個(gè)應(yīng)用吧。
Python語(yǔ)言的重要特色之一,就是可以利用強(qiáng)大的軟件工具包(許多都是第三方提供)。你只需要編寫簡(jiǎn)單的程序,就能自動(dòng)解析網(wǎng)頁(yè),抓取數(shù)據(jù)。
本文給你演示這一過(guò)程。
目標(biāo)
要抓取網(wǎng)頁(yè)數(shù)據(jù),我們先制訂一個(gè)小目標(biāo)。
目標(biāo)不能太復(fù)雜。但是完成它,應(yīng)該對(duì)你理解抓?。╓eb Scraping)有幫助。
就選擇我最近發(fā)布的一篇簡(jiǎn)書文章作為抓取對(duì)象好了。題目叫做《如何用《玉樹芝蘭》入門數(shù)據(jù)科學(xué)?》。
這篇文章里,我把之前的發(fā)布的數(shù)據(jù)科學(xué)系列文章做了重新組織和串講。
文中包含很多之前教程的標(biāo)題和對(duì)應(yīng)鏈接。例如下圖紅色邊框圈起來(lái)的部分。
假設(shè)你對(duì)文中提到教程都很感興趣,希望獲得這些文章的鏈接,并且存儲(chǔ)到Excel里,就像下面這個(gè)樣子:
你需要把非結(jié)構(gòu)化的分散信息(自然語(yǔ)言文本中的鏈接),專門提取整理,并且存儲(chǔ)下來(lái)。
該怎么辦呢?
即便不會(huì)編程,你也可以全文通讀,逐個(gè)去找這些文章鏈接,手動(dòng)把文章標(biāo)題、鏈接都分別拷貝下來(lái),存到Excel表里面。
但是,這種手工采集方法沒(méi)有效率。
我們用Python。
環(huán)境
要裝Python,比較省事的辦法是安裝Anaconda套裝。
請(qǐng)到這個(gè)網(wǎng)址下載Anaconda的最新版本。
請(qǐng)選擇左側(cè)的 Python 3.6 版本下載安裝。
如果你需要具體的步驟指導(dǎo),或者想知道Windows平臺(tái)如何安裝并運(yùn)行Anaconda命令,請(qǐng)參考我為你準(zhǔn)備的視頻教程。
安裝好Anaconda之后,請(qǐng)到這個(gè)網(wǎng)址下載本教程配套的壓縮包。
下載后解壓,你會(huì)在生成的目錄(下稱“演示目錄”)里面看到以下三個(gè)文件。
打開終端,用cd命令進(jìn)入該演示目錄。如果你不了解具體使用方法,也可以參考視頻教程。
我們需要安裝一些環(huán)境依賴包。
首先執(zhí)行:
pip install pipenv
這里安裝的,是一個(gè)優(yōu)秀的 Python 軟件包管理工具 pipenv 。
安裝后,請(qǐng)執(zhí)行:
pipenv install
看到演示目錄下兩個(gè)Pipfile開頭的文件了嗎?它們就是 pipenv 的設(shè)置文檔。
pipenv 工具會(huì)依照它們,自動(dòng)為我們安裝所需要的全部依賴軟件包。
上圖里面有個(gè)綠色的進(jìn)度條,提示所需安裝軟件數(shù)量和實(shí)際進(jìn)度。
裝好后,根據(jù)提示我們執(zhí)行:
pipenv shell
此處請(qǐng)確認(rèn)你的電腦上已經(jīng)安裝了 Google Chrome 瀏覽器。
我們執(zhí)行:
jupyter notebook
默認(rèn)瀏覽器(Google Chrome)會(huì)開啟,并啟動(dòng) Jupyter 筆記本界面:
你可以直接點(diǎn)擊文件列表中的第一項(xiàng)ipynb文件,可以看到本教程的全部示例代碼。
你可以一邊看教程的講解,一邊依次執(zhí)行這些代碼。
但是,我建議的方法,是回到主界面下,新建一個(gè)新的空白 Python 3 筆記本。
請(qǐng)跟著教程,一個(gè)個(gè)字符輸入相應(yīng)的內(nèi)容。這可以幫助你更為深刻地理解代碼的含義,更高效地把技能內(nèi)化。
準(zhǔn)備工作結(jié)束,下面我們開始正式輸入代碼。
代碼
讀入網(wǎng)頁(yè)加以解析抓取,需要用到的軟件包是 requests_html 。我們此處并不需要這個(gè)軟件包的全部功能,只讀入其中的 HTMLSession 就可以。
from requests_html import HTMLSession
然后,我們建立一個(gè)會(huì)話(session),即讓Python作為一個(gè)客戶端,和遠(yuǎn)端服務(wù)器交談。
session = HTMLSession()
前面說(shuō)了,我們打算采集信息的網(wǎng)頁(yè),是《如何用《玉樹芝蘭》入門數(shù)據(jù)科學(xué)?》一文。
我們找到它的網(wǎng)址,存儲(chǔ)到url變量名中。
url = 'http://www.itdecent.cn/p/85f4624485b9'
下面的語(yǔ)句,利用 session 的 get 功能,把這個(gè)鏈接對(duì)應(yīng)的網(wǎng)頁(yè)整個(gè)兒取回來(lái)。
r = session.get(url)
網(wǎng)頁(yè)里面都有什么內(nèi)容呢?
我們告訴Python,請(qǐng)把服務(wù)器傳回來(lái)的內(nèi)容當(dāng)作HTML文件類型處理。我不想要看HTML里面那些亂七八糟的格式描述符,只看文字部分。
于是我們執(zhí)行:
print(r.html.text)
這就是獲得的結(jié)果了:
我們心里有數(shù)了。取回來(lái)的網(wǎng)頁(yè)信息是正確的,內(nèi)容是完整的。
好了,我們來(lái)看看怎么趨近自己的目標(biāo)吧。
我們先用簡(jiǎn)單粗暴的方法,嘗試獲得網(wǎng)頁(yè)中包含的全部鏈接。
把返回的內(nèi)容作為HTML文件類型,我們查看 links 屬性:
r.html.links
這是返回的結(jié)果:
這么多鏈接??!
很興奮吧?
不過(guò),你發(fā)現(xiàn)沒(méi)有?這里許多鏈接,看似都不完全。例如第一條結(jié)果,只有:
'/'
這是什么東西?是不是鏈接抓取錯(cuò)誤???
不是,這種看著不像鏈接的東西,叫做相對(duì)鏈接。它是某個(gè)鏈接,相對(duì)于我們采集的網(wǎng)頁(yè)所在域名(http://www.itdecent.cn)的路徑。
這就好像我們?cè)趪?guó)內(nèi)郵寄快遞包裹,填單子的時(shí)候一般會(huì)寫“XX省XX市……”,前面不需要加上國(guó)家名稱。只有國(guó)際快遞,才需要寫上國(guó)名。
但是如果我們希望獲得全部可以直接訪問(wèn)的鏈接,怎么辦呢?
很容易,也只需要一條 Python 語(yǔ)句。
r.html.absolute_links
這里,我們要的是“絕對(duì)”鏈接,于是我們就會(huì)獲得下面的結(jié)果:
這回看著是不是就舒服多了?
我們的任務(wù)已經(jīng)完成了吧?鏈接不是都在這里嗎?
鏈接確實(shí)都在這里了,可是跟我們的目標(biāo)是不是有區(qū)別呢?
檢查一下,確實(shí)有。
我們不光要找到鏈接,還得找到鏈接對(duì)應(yīng)的描述文字呢,結(jié)果里包含嗎?
沒(méi)有。
結(jié)果列表中的鏈接,都是我們需要的嗎?
不是??撮L(zhǎng)度,我們就能感覺(jué)出許多鏈接并不是文中描述其他數(shù)據(jù)科學(xué)文章的網(wǎng)址。
這種簡(jiǎn)單粗暴直接羅列HTML文件中所有鏈接的方法,對(duì)本任務(wù)行不通。
那么我們?cè)撛趺崔k?
我們得學(xué)會(huì)跟 Python 說(shuō)清楚我們要找的東西。這是網(wǎng)頁(yè)抓取的關(guān)鍵。
想想看,如果你想讓助手(人類)幫你做這事兒,怎么辦?
你會(huì)告訴他:
“尋找正文中全部可以點(diǎn)擊的藍(lán)色文字鏈接,拷貝文字到Excel表格,然后右鍵復(fù)制對(duì)應(yīng)的鏈接,也拷貝到Excel表格。每個(gè)鏈接在Excel占一行,文字和鏈接各占一個(gè)單元格?!?/p>
雖然這個(gè)操作執(zhí)行起來(lái)麻煩,但是助手聽懂后,就能幫你執(zhí)行。
同樣的描述,你試試說(shuō)給電腦聽……不好意思,它不理解。
因?yàn)槟愫椭挚吹降木W(wǎng)頁(yè),是這個(gè)樣子的。
電腦看到的網(wǎng)頁(yè),是這個(gè)樣子的。
為了讓你看得清楚源代碼,瀏覽器還特意對(duì)不同類型的數(shù)據(jù)用了顏色區(qū)分,對(duì)行做了編號(hào)。
數(shù)據(jù)顯示給電腦時(shí),上述輔助可視功能是沒(méi)有的。它只能看見(jiàn)一串串字符。
那可怎么辦?
仔細(xì)觀察,你會(huì)發(fā)現(xiàn)這些HTML源代碼里面,文字、圖片鏈接內(nèi)容前后,都會(huì)有一些被尖括號(hào)括起來(lái)的部分,這就叫做“標(biāo)記”。
所謂HTML,就是一種標(biāo)記語(yǔ)言(超文本標(biāo)記語(yǔ)言,HyperText Markup Language)。
標(biāo)記的作用是什么?它可以把整個(gè)的文件分解出層次來(lái)。
(圖片來(lái)源:https://goo.gl/kWCqS6)
如同你要發(fā)送包裹給某個(gè)人,可以按照“省-市-區(qū)-街道-小區(qū)-門牌”這樣的結(jié)構(gòu)來(lái)寫地址,快遞員也可以根據(jù)這個(gè)地址找到收件人。
同樣,我們對(duì)網(wǎng)頁(yè)中某些特定內(nèi)容感興趣,可以依據(jù)這些標(biāo)記的結(jié)構(gòu),順藤摸瓜找出來(lái)。
這是不是意味著,你必須先學(xué)會(huì)HTML和CSS,才能進(jìn)行網(wǎng)頁(yè)內(nèi)容抓取呢?
不是的,我們可以借助工具,幫你顯著簡(jiǎn)化任務(wù)復(fù)雜度。
這個(gè)工具,Google Chrome瀏覽器自帶。
我們?cè)跇永恼马?yè)面上,點(diǎn)擊鼠標(biāo)右鍵,在出現(xiàn)的菜單里面選擇“檢查”。
這時(shí),屏幕下方就會(huì)出現(xiàn)一個(gè)分欄。
我們點(diǎn)擊這個(gè)分欄左上角(上圖紅色標(biāo)出)的按鈕。然后把鼠標(biāo)懸停在第一個(gè)文內(nèi)鏈接(《玉樹芝蘭》)上面,點(diǎn)擊一下。
此時(shí),你會(huì)發(fā)現(xiàn)下方分欄里面,內(nèi)容也發(fā)生了變化。這個(gè)鏈接對(duì)應(yīng)的源代碼被放在分欄區(qū)域正中,高亮顯示。
確認(rèn)該區(qū)域就是我們要找的鏈接和文字描述后,我們鼠標(biāo)右鍵選擇高亮區(qū)域,并且在彈出的菜單中,選擇 Copy -> Copy selector。
找一個(gè)文本編輯器,執(zhí)行粘貼,就可以看見(jiàn)我們究竟復(fù)制下來(lái)了什么內(nèi)容。
body > div.note > div.post > div.article > div.show-content > div > p:nth-child(4) > a
這一長(zhǎng)串的標(biāo)記,為電腦指出了:請(qǐng)你先找到 body 標(biāo)記,進(jìn)入它管轄的這個(gè)區(qū)域后去找 div.note 標(biāo)記,然后找……最后找到 a 標(biāo)記,這里就是要找的內(nèi)容了。
回到咱們的 Jupyter Notebook 中,用剛才獲得的標(biāo)記路徑,定義變量sel。
sel = 'body > div.note > div.post > div.article > div.show-content > div > p:nth-child(4) > a'
我們讓 Python 從返回內(nèi)容中,查找 sel 對(duì)應(yīng)的位置,把結(jié)果存到 results 變量中。
results = r.html.find(sel)
我們看看 results 里面都有什么。
results
這是結(jié)果:
[<Element 'a' href='http://www.itdecent.cn/nb/130182' target='_blank'>]
results 是個(gè)列表,只包含一項(xiàng)。這一項(xiàng)包含一個(gè)網(wǎng)址,就是我們要找的第一個(gè)鏈接(《玉樹芝蘭》)對(duì)應(yīng)的網(wǎng)址。
可是文字描述“《玉樹芝蘭》”哪里去了?
別著急,我們讓 Python 顯示 results 結(jié)果數(shù)據(jù)對(duì)應(yīng)的文本。
results[0].text
這是輸出結(jié)果:
'玉樹芝蘭'
我們把鏈接也提取出來(lái):
results[0].absolute_links
顯示的結(jié)果卻是一個(gè)集合。
{'http://www.itdecent.cn/nb/130182'}
我們不想要集合,只想要其中的鏈接字符串。所以我們先把它轉(zhuǎn)換成列表,然后從中提取第一項(xiàng),即網(wǎng)址鏈接。
list(results[0].absolute_links)[0]
這次,終于獲得我們想要的結(jié)果了:
'http://www.itdecent.cn/nb/130182'
有了處理這第一個(gè)鏈接的經(jīng)驗(yàn),你信心大增,是吧?
其他鏈接,也無(wú)非是找到標(biāo)記路徑,然后照貓畫虎嘛。
可是,如果每找一個(gè)鏈接,都需要手動(dòng)輸入上面這若干條語(yǔ)句,那也太麻煩了。
這里就是編程的技巧了。重復(fù)逐條運(yùn)行的語(yǔ)句,如果工作順利,我們就要嘗試把它們歸并起來(lái),做個(gè)簡(jiǎn)單的函數(shù)。
對(duì)這個(gè)函數(shù),只需給定一個(gè)選擇路徑(sel),它就把找到的所有描述文本和鏈接路徑都返回給我們。
def get_text_link_from_sel(sel):
mylist = []
try:
results = r.html.find(sel)
for result in results:
mytext = result.text
mylink = list(result.absolute_links)[0]
mylist.append((mytext, mylink))
return mylist
except:
return None
我們測(cè)試一下這個(gè)函數(shù)。
還是用剛才的標(biāo)記路徑(sel)不變,試試看。
print(get_text_link_from_sel(sel))
輸出結(jié)果如下:
[('玉樹芝蘭', 'http://www.itdecent.cn/nb/130182')]
沒(méi)問(wèn)題,對(duì)吧?
好,我們?cè)囋嚳吹诙€(gè)鏈接。
我們還是用剛才的方法,使用下面分欄左上角的按鈕點(diǎn)擊第二個(gè)鏈接。
下方出現(xiàn)的高亮內(nèi)容就發(fā)生了變化:
我們還是用鼠標(biāo)右鍵點(diǎn)擊高亮部分,拷貝出 selector。
然后我們直接把獲得的標(biāo)記路徑寫到 Jupyter Notebook 里面。
sel = 'body > div.note > div.post > div.article > div.show-content > div > p:nth-child(6) > a'
用我們剛才編制的函數(shù),看看輸出結(jié)果是什么?
print(get_text_link_from_sel(sel))
輸出如下:
[('如何用Python做詞云?', 'http://www.itdecent.cn/p/e4b24a734ccc')]
檢驗(yàn)完畢,函數(shù)沒(méi)有問(wèn)題。
下一步做什么?
你還打算去找第三個(gè)鏈接,仿照剛才的方法做?
那你還不如全文手動(dòng)摘取信息算了,更省事兒一些。
我們要想辦法把這個(gè)過(guò)程自動(dòng)化。
對(duì)比一下剛剛兩次我們找到的標(biāo)記路徑:
body > div.note > div.post > div.article > div.show-content > div > p:nth-child(4) > a
以及:
body > div.note > div.post > div.article > div.show-content > div > p:nth-child(6) > a
發(fā)現(xiàn)什么規(guī)律沒(méi)有?
對(duì),路徑上其他的標(biāo)記全都是一樣的,唯獨(dú)倒數(shù)第二個(gè)標(biāo)記("p")后冒號(hào)后內(nèi)容有區(qū)別。
這就是我們自動(dòng)化的關(guān)鍵了。
上述兩個(gè)標(biāo)記路徑里面,因?yàn)橹付嗽诘趲讉€(gè)“子”(nth-child)文本段(paragraph,也就是"p"代表的含義)去找"a"這個(gè)標(biāo)記,因此只返回來(lái)單一結(jié)果。
如果我們不限定"p"的具體位置信息呢?
我們?cè)囋嚳?,這次保留標(biāo)記路徑里面其他全部信息,只修改"p"這一點(diǎn)。
sel = 'body > div.note > div.post > div.article > div.show-content > div > p > a'
再次運(yùn)行我們的函數(shù):
print(get_text_link_from_sel(sel))
這是輸出結(jié)果:
好了,我們要找的內(nèi)容,全都在這兒了。
但是,我們的工作還沒(méi)完。
我們還得把采集到的信息輸出到Excel中保存起來(lái)。
還記得我們常用的數(shù)據(jù)框工具 Pandas 嗎?又該讓它大顯神通了。
import pandas as pd
只需要這一行命令,我們就能把剛才的列表變成數(shù)據(jù)框:
df = pd.DataFrame(get_text_link_from_sel(sel))
讓我們看看數(shù)據(jù)框內(nèi)容:
df
內(nèi)容沒(méi)問(wèn)題,不過(guò)我們對(duì)表頭不大滿意,得更換為更有意義的列名稱:
df.columns = ['text', 'link']
再看看數(shù)據(jù)框內(nèi)容:
df
好了,下面就可以把抓取的內(nèi)容輸出到Excel中了。
Pandas內(nèi)置的命令,就可以把數(shù)據(jù)框變成csv格式,這種格式可以用Excel直接打開查看。
df.to_csv('output.csv', encoding='gbk', index=False)
注意這里需要指定encoding(編碼)為gbk,否則默認(rèn)的utf-8編碼在Excel中查看的時(shí)候,有可能是亂碼。
我們看看最終生成的csv文件吧。
很有成就感,是不是?
小結(jié)
本文為你展示了用Python自動(dòng)網(wǎng)頁(yè)抓取的基礎(chǔ)技能。希望閱讀并動(dòng)手實(shí)踐后,你能掌握以下知識(shí)點(diǎn):
- 網(wǎng)頁(yè)抓取與網(wǎng)絡(luò)爬蟲之間的聯(lián)系與區(qū)別;
- 如何用 pipenv 快速構(gòu)建指定的 Python 開發(fā)環(huán)境,自動(dòng)安裝好依賴軟件包;
- 如何用 Google Chrome 的內(nèi)置檢查功能,快速定位感興趣內(nèi)容的標(biāo)記路徑;
- 如何用 requests-html 包來(lái)解析網(wǎng)頁(yè),查詢獲得需要的內(nèi)容元素;
- 如何用 Pandas 數(shù)據(jù)框工具整理數(shù)據(jù),并且輸出到 Excel。
或許,你覺(jué)得這篇文章過(guò)于淺白,不能滿足你的要求。
文中只展示了如何從一個(gè)網(wǎng)頁(yè)抓取信息,可你要處理的網(wǎng)頁(yè)成千上萬(wàn)啊。
別著急。
本質(zhì)上說(shuō),抓取一個(gè)網(wǎng)頁(yè),和抓取10000個(gè)網(wǎng)頁(yè),在流程上是一樣的。
而且,從咱們的例子里,你是不是已經(jīng)嘗試了抓取鏈接?
有了鏈接作為基礎(chǔ),你就可以滾雪球,讓Python爬蟲“爬”到解析出來(lái)的鏈接上,做進(jìn)一步的處理。
將來(lái),你可能還要應(yīng)對(duì)實(shí)踐場(chǎng)景中的一些棘手問(wèn)題:
- 如何把抓取的功能擴(kuò)展到某一范內(nèi)內(nèi)的所有網(wǎng)頁(yè)?
- 如何爬取Javascript動(dòng)態(tài)網(wǎng)頁(yè)?
- 假設(shè)你爬取的網(wǎng)站對(duì)每個(gè)IP的訪問(wèn)頻率做出限定,怎么辦?
- ……
這些問(wèn)題的解決辦法,我希望在今后的教程里面,一一和你分享。
需要注意的是,網(wǎng)絡(luò)爬蟲抓取數(shù)據(jù),雖然功能強(qiáng)大,但學(xué)習(xí)與實(shí)踐起來(lái)有一定門檻。
當(dāng)你面臨數(shù)據(jù)獲取任務(wù)時(shí),應(yīng)該先檢查一下這個(gè)清單:
- 有沒(méi)有別人已經(jīng)整理好的數(shù)據(jù)集合可以直接下載?
- 網(wǎng)站有沒(méi)有對(duì)你需要的數(shù)據(jù)提供API訪問(wèn)與獲取方式?
- 有沒(méi)有人針對(duì)你的需求,編好了定制爬蟲,供你直接調(diào)用?
如果答案是都沒(méi)有,才需要你自己編寫腳本,調(diào)動(dòng)爬蟲來(lái)抓取。
為了鞏固學(xué)習(xí)的知識(shí),請(qǐng)你換一個(gè)其他網(wǎng)頁(yè),以咱們的代碼作為基礎(chǔ)修改后,抓取其中你感興趣的內(nèi)容。
如果能把你抓取的過(guò)程記錄下來(lái),在評(píng)論區(qū)將記錄鏈接分享給大家,就更好了。
因?yàn)?strong>刻意練習(xí)是掌握實(shí)踐技能的最好方式,而教是最好的學(xué)。
祝順利!
思考
本文主要內(nèi)容講解完畢。
這里給你提一個(gè)疑問(wèn),供你思考:
我們解析并且存儲(chǔ)的鏈接,其實(shí)是有重復(fù)的:
這并不是我們的代碼有誤,而是在《如何用《玉樹芝蘭》入門數(shù)據(jù)科學(xué)?》一文里,本來(lái)就多次引用過(guò)一些文章,所以重復(fù)的鏈接就都被抓取出來(lái)了。
但是你存儲(chǔ)的時(shí)候,也許不希望保留重復(fù)鏈接。
這種情況下,你該如何修改代碼,才能保證抓取和保存的鏈接沒(méi)有重復(fù)呢?
我把這一部分內(nèi)容,放到了文末的付費(fèi)閱讀區(qū)域。如果你愿意支持我的數(shù)據(jù)科學(xué)系列教程寫作,順便核對(duì)一下你的代碼是不是比我的更高效,只需支付2塊錢(推廣期價(jià)格),閱讀該部分內(nèi)容。
討論
你對(duì)Python爬蟲感興趣嗎?在哪些數(shù)據(jù)采集任務(wù)上使用過(guò)它?有沒(méi)有其他更高效的方式,來(lái)達(dá)成數(shù)據(jù)采集目的?歡迎留言,把你的經(jīng)驗(yàn)和思考分享給大家,我們一起交流討論。
如果你對(duì)我的文章感興趣,歡迎點(diǎn)贊,并且微信關(guān)注和置頂我的公眾號(hào)“玉樹芝蘭”(nkwangshuyi)。
如果本文可能對(duì)你身邊的親友有幫助,也歡迎你把本文通過(guò)微博或朋友圈分享給他們。讓他們一起參與到我們的討論中來(lái)。