官术网_书友最值得收藏!

1.3 網(wǎng)頁上的數(shù)據(jù)

互聯(lián)網(wǎng)是最大的數(shù)據(jù)庫(kù),大大小小各種網(wǎng)站的網(wǎng)頁上每天發(fā)布著海量信息,這些信息都可以作為數(shù)據(jù)。但是,如果這些數(shù)據(jù)存在網(wǎng)頁上,通常不能直接用于數(shù)據(jù)科學(xué)項(xiàng)目,必須通過某種技術(shù)手段將它們保存到指定數(shù)據(jù)庫(kù)或文件中。實(shí)現(xiàn)這種操作的技術(shù)就是“網(wǎng)絡(luò)爬蟲”。當(dāng)然,如果某網(wǎng)站為用戶提供了讀取有關(guān)信息的接口,那就不需要網(wǎng)絡(luò)爬蟲,直接通過接口讀取有關(guān)內(nèi)容即可。但是,接口提供的信息若不能滿足需要,則必須使用網(wǎng)絡(luò)爬蟲技術(shù)從網(wǎng)頁上獲取必需的數(shù)據(jù)。

基礎(chǔ)知識(shí)

網(wǎng)絡(luò)爬蟲(Web crawler),也叫網(wǎng)絡(luò)蜘蛛(Spider),是一種用來自動(dòng)瀏覽網(wǎng)頁的網(wǎng)絡(luò)機(jī)器人,它可以將自己所訪問的頁面保存下來。

請(qǐng)讀者注意,并不是所有網(wǎng)站都能夠使用網(wǎng)絡(luò)爬蟲得到其頁面內(nèi)容。使用爬蟲技術(shù),務(wù)必遵守法律法規(guī)和有關(guān)道德要求。

在Python語言生態(tài)中,有很多實(shí)現(xiàn)網(wǎng)絡(luò)爬蟲的工具。這里演示一種比較簡(jiǎn)單、常用的第三方模塊requests(官方網(wǎng)站:https://2.python-requests.org/en/master/),其安裝方法如下:

提示:要正確、合理地使用網(wǎng)絡(luò)爬蟲技術(shù)。

下面以獲取頁面https://2.python-requests.org/en/master/community/support/的有關(guān)數(shù)據(jù)為例演示requests的基本應(yīng)用。

圖1-3-1是上述網(wǎng)址的頁面,最終目標(biāo)是要獲取方框中的文檔內(nèi)容。

圖1-3-1 用網(wǎng)絡(luò)爬蟲技術(shù)獲取的內(nèi)容

執(zhí)行In[1]的代碼,獲得了所訪問URL頁面的全部?jī)?nèi)容,①為請(qǐng)求該URL,可以用In[2]中演示的方式判斷該請(qǐng)求是否成功。

返回值為200,說明請(qǐng)求成功。In[1]的②得到了返回的頁面中的所有信息。如果讀者在瀏覽器中打開了①中的URL,可以查看該頁面的源碼(例如Firefox瀏覽器,按F12鍵即可查看,其他瀏覽器也有類似操作)。

②所返回的內(nèi)容和圖1-3-2中的網(wǎng)頁源碼內(nèi)容一致。那么,如何才能得到圖1-3-1方框中的文本呢?此處需要另外一個(gè)工具:

圖1-3-2 網(wǎng)頁源碼

200是服務(wù)器header返回狀態(tài)碼。常見的還有:400(請(qǐng)求無效)、403(禁止訪問)、404(無法找到文件)、500(內(nèi)部服務(wù)器錯(cuò)誤)等。

Beautiful Soup是一個(gè)可以從HTML或XML文件中提取數(shù)據(jù)的Python庫(kù)(官方網(wǎng)站:https://www.crummy.com/software/BeautifulSoup/bs4/doc/)。

在使用這個(gè)工具之前,先要分析如圖1-3-2所示的網(wǎng)頁源碼,找到所要的文本在源碼中的位置和相關(guān)的網(wǎng)頁標(biāo)記符。以圖1-3-1中的第一段Stack Overflow為例,其部分相關(guān)源碼樣式如圖1-3-3所示。

圖1-3-3 部分相關(guān)源碼樣式

通常網(wǎng)站的網(wǎng)頁由HTML編寫,HTML(超文本標(biāo)記語言,HyperText Markup Language)是一種標(biāo)記語言。

從如圖1-3-3所示的源碼可以看出,該段內(nèi)容在<div id="stack-overflow" class="section">標(biāo)簽之內(nèi),并且以<h2>標(biāo)簽標(biāo)示了大標(biāo)題(Stack Overflow),以<p>標(biāo)簽標(biāo)示了其下的文本說明。

以后三段內(nèi)容與此類似。

根據(jù)上述規(guī)律,可以編寫如下代碼,以獲取相應(yīng)文本內(nèi)容。

循環(huán)得到每個(gè)<div>中的id值。

輸出內(nèi)容中的“亂碼”系爬蟲所得內(nèi)容的一部分。

In[1]的②所得到的是一個(gè)包含了所有源碼的字符串,In[3]的③則是通過BeautifulSoup模塊將其轉(zhuǎn)化為純粹的HTML代碼,如In[4]所示——其實(shí)是bs4.BeautifulSoup類型對(duì)象。

從對(duì)源碼的分析可知,所要的內(nèi)容在<div>標(biāo)簽內(nèi),其id值分別是"stack-overflow"、"send-a-tweet"、"file-an-issue"、"e-mail"和"irc"。

函數(shù)extract_text中的⑤使用find方法依據(jù)id值查詢到相應(yīng)<div>標(biāo)簽中的文本,此文本也由HTML源碼組成。再?gòu)闹蟹謩e讀取到標(biāo)題和內(nèi)容,⑥獲取<h2>標(biāo)簽內(nèi)的文本,⑦獲取<p>標(biāo)簽內(nèi)的文本。

然后用循環(huán)語句,依次向函數(shù)傳入<div>標(biāo)簽的id值,獲取相應(yīng)文本內(nèi)容(如⑧所示)。

為了顯示更清晰,⑨使用了標(biāo)準(zhǔn)庫(kù)中的pprint模塊的函數(shù)。

利用In[3]代碼得到的文本內(nèi)容,可以保存到文件或者數(shù)據(jù)庫(kù)中。

項(xiàng)目案例

1.項(xiàng)目描述

爬取“豆瓣電影”中即將上映電影的信息,網(wǎng)址是https://movie.douban.com/coming,具體要求如下:

●獲得網(wǎng)頁中所列出的“即將上映電影”信息。

●網(wǎng)頁中的“片名”都是超鏈接對(duì)象,顯示了每部電影的詳細(xì)信息,要求以該超鏈接為入口,通過每部電影的詳細(xì)信息,得知其導(dǎo)演、主演。

●將上述兩部分?jǐn)?shù)據(jù)合并為一個(gè)Pandas的DataFrame對(duì)象,并保存成本地的CSV文件。

出于網(wǎng)站的原因,讀者閱讀此內(nèi)容時(shí),要先確認(rèn)該網(wǎng)址是否有效。網(wǎng)站修改URL是正常且經(jīng)常發(fā)生的行為。

2.實(shí)現(xiàn)過程

(1)分析網(wǎng)頁源碼。

在瀏覽器中打開頁面并顯示源碼,如圖1-3-4所示(注意,隨著時(shí)間的推移,讀者訪問該頁面的時(shí)候,所顯示的電影信息會(huì)有所差異)。單擊圖中①指向的選擇工具,用它在頁面上單擊任何一個(gè)元素,就會(huì)在下半部分的源碼中標(biāo)記出與該元素對(duì)應(yīng)的源碼。反之,如果單擊下面的源碼,也可以在上面的網(wǎng)頁中標(biāo)記出相應(yīng)的元素,如圖中②所示。

圖1-3-4所使用的瀏覽器是Firefox。

圖1-3-4 <table>標(biāo)簽與網(wǎng)頁內(nèi)容

如此,就知道了頁面中的列表內(nèi)容在<table>標(biāo)簽內(nèi),并且每一行是一個(gè)<tr>標(biāo)簽,每個(gè)單元格中的內(nèi)容則對(duì)應(yīng)著一個(gè)<td>標(biāo)簽。<td>標(biāo)簽與網(wǎng)頁內(nèi)容如圖1-3-5所示。

圖1-3-5 <td>標(biāo)簽與網(wǎng)頁內(nèi)容

在HTML中使用<table>標(biāo)簽來定義表格。每個(gè)表格均有若干行(由<tr>標(biāo)簽定義),每行被分割為若干單元格(由<td>標(biāo)簽定義)。字母td指表格數(shù)據(jù)(table data),即數(shù)據(jù)單元格的內(nèi)容。

用同樣的方式,分析出每部電影詳細(xì)信息的HTML源碼結(jié)構(gòu),如圖1-3-6所示。

圖1-3-6 電影詳細(xì)信息的HTML源碼結(jié)構(gòu)

(2)獲取列表內(nèi)容。

注意區(qū)分find_all和find。兩者都返回符合條件的所有標(biāo)簽,find_all返回的值是列表;find直接返回結(jié)果。

從執(zhí)行結(jié)果來看,應(yīng)該還比較令人滿意,初步達(dá)到了項(xiàng)目的要求,將網(wǎng)頁上的電影信息都保存到了列表里面。

上面的代碼還沒有得到每部電影名稱的超鏈接。從圖1-3-5的源碼中可以看出,電影名稱的超鏈接用<a>標(biāo)簽標(biāo)示。如果分析不同電影的超鏈接,會(huì)發(fā)現(xiàn)它們的區(qū)別在于最后的那個(gè)數(shù)字,如圖1-3-7所示。

圖1-3-7 不同電影的超鏈接的差別

可以認(rèn)為,圖1-3-7中不同的值是每部電影的網(wǎng)頁在該網(wǎng)站的唯一標(biāo)示——稱為id值,因此只要得到了它,就能寫出每部電影詳細(xì)信息頁面的URL。

依照上述思路,優(yōu)化In[5]的代碼。

In[6]的⑩和?是新增代碼,⑩的功能就是得到圖1-3-7中所標(biāo)示的id值。

以上所得到的data是列表,可以將其轉(zhuǎn)換為Pandas中的DataFrame對(duì)象,并將內(nèi)容保存到CSV文件中。

(3)獲取影片詳情。

此處省略了顯示的部分內(nèi)容,請(qǐng)讀者觀察調(diào)試結(jié)果。

在前面的基礎(chǔ)上,理解In[8]相對(duì)容易一些。?的參數(shù)與以往有所不同,這是因?yàn)樵陔娪霸斍榈捻撁嬷校瑢?duì)不同項(xiàng)目并沒有設(shè)置不同的id或者class值,如圖1-3-8所示。從此源碼中可以看出,如果要得到導(dǎo)演的名稱(即<span>標(biāo)簽中的文本)是比較麻煩的,因?yàn)槎鄠€(gè)<span>標(biāo)簽中的class值都相同。但是,觀察發(fā)現(xiàn),在相應(yīng)的<span>標(biāo)簽中還有“rel="v:directedBy"”以區(qū)別于其他項(xiàng)目,于是在?中使用了它。?的解決方法類似。

圖1-3-8 電影詳情的頁面中的源碼分析

網(wǎng)絡(luò)爬蟲技術(shù)的關(guān)鍵在于認(rèn)真分析網(wǎng)頁源碼特點(diǎn)。

請(qǐng)注意,因?yàn)榫W(wǎng)站頁面可能會(huì)被開發(fā)者隨時(shí)修改,當(dāng)讀者調(diào)試上述代碼的時(shí)候,一定要對(duì)照網(wǎng)站源碼,并根據(jù)當(dāng)下的源碼結(jié)構(gòu)進(jìn)行適當(dāng)調(diào)整。

(4)保存數(shù)據(jù)。

根據(jù)項(xiàng)目要求,最后要合并In[7]和In[8]得到的數(shù)據(jù),并保存到本地的CSV文件中。

?將前述兩個(gè)DataFrame對(duì)象合并,因?yàn)閮蓴?shù)據(jù)中都有名為“ID”的列,于是以它為合并依據(jù)(即on='ID'的含義)。

對(duì)網(wǎng)站而言,修改網(wǎng)頁結(jié)構(gòu)是常見的操作,因此爬蟲技術(shù)鮮有一勞永逸,需要根據(jù)網(wǎng)站的技術(shù)調(diào)整而進(jìn)行相應(yīng)變化。

動(dòng)手練習(xí)

(對(duì)于以下兩個(gè)練習(xí),可以二選一。)

1.利用爬蟲技術(shù),從電子商務(wù)網(wǎng)站上獲取某類商品的用戶評(píng)論信息。

2.利用爬蟲技術(shù),從電子商務(wù)網(wǎng)站上獲取部分商品的名稱、價(jià)格、已銷售數(shù)量等信息。

擴(kuò)展探究

1.Scrapy是一款開源的網(wǎng)絡(luò)爬蟲框架,官方網(wǎng)站:https://scrapy.org/。建議讀者學(xué)習(xí)和應(yīng)用此工具。

2.除了通用的網(wǎng)絡(luò)爬蟲工具,還有一些專門針對(duì)某網(wǎng)站的工具,例如https://github.com/SpiderClub/weibospider是一款針對(duì)微博網(wǎng)站的專用工具。

主站蜘蛛池模板: 香河县| 乡城县| 太谷县| 桃园市| 策勒县| 汉阴县| 龙陵县| 年辖:市辖区| 九江县| 文登市| 高碑店市| 马鞍山市| 绥滨县| 龙江县| 白河县| 嘉鱼县| 平邑县| 精河县| 新竹市| 彰化县| 黑龙江省| 东兴市| 驻马店市| 惠来县| 望城县| 辽宁省| 绵阳市| 如东县| 嘉禾县| 安多县| 辽源市| 大关县| 海淀区| 高要市| 景谷| 霍林郭勒市| 炉霍县| 陇南市| 启东市| 闽清县| 烟台市|