手把手教你用 Python 搞定網(wǎng)頁(yè)爬蟲(chóng)
作為數(shù)據(jù)科學(xué)家的第一個(gè)任務(wù),就是做網(wǎng)頁(yè)爬取。那時(shí)候,我對(duì)使用代碼從網(wǎng)站上獲取數(shù)據(jù)這項(xiàng)技術(shù)完全一無(wú)所知,它偏偏又是最有邏輯性并且最容易獲得的數(shù)據(jù)來(lái)源。在幾次嘗試之后,網(wǎng)頁(yè)爬取對(duì)我來(lái)說(shuō)就幾乎是種本能行為了。如今,它更成為了我?guī)缀趺刻於家玫降纳贁?shù)幾個(gè)技術(shù)之一。
在今天的文章中,我將會(huì)用幾個(gè)簡(jiǎn)單的例子,向大家展示如何爬取一個(gè)網(wǎng)站——比如從?Fast Track?上獲取 2018 年 100 強(qiáng)企業(yè)的信息。用腳本將獲取信息的過(guò)程自動(dòng)化,不但能節(jié)省手動(dòng)整理的時(shí)間,還能將所有企業(yè)數(shù)據(jù)整理在一個(gè)結(jié)構(gòu)化的文件里,方便進(jìn)一步分析查詢(xún)。
太長(zhǎng)不看版:如果你只是想要一個(gè)最基本的 Python 爬蟲(chóng)程序的示例代碼,本文中所用到的全部代碼都放在?GitHub?(https://github.com/kaparker/tutorials/blob/master/pythonscraper/websitescrapefasttrack.py),歡迎自取。
準(zhǔn)備工作
每一次打算用 Python 搞點(diǎn)什么的時(shí)候,你問(wèn)的第一個(gè)問(wèn)題應(yīng)該是:“我需要用到什么庫(kù)”。
網(wǎng)頁(yè)爬取方面,有好幾個(gè)不同的庫(kù)可以用,包括:
Beautiful Soup
Requests
Scrapy
Selenium
今天我們打算用 Beautiful Soup 庫(kù)。你只需要用?pip(Python包管理工具)就能很方便地將它裝到電腦上:

安裝完畢之后,我們就可以開(kāi)始啦!
檢查網(wǎng)頁(yè)
為了明確要抓取網(wǎng)頁(yè)中的什么元素,你需要先檢查一下網(wǎng)頁(yè)的結(jié)構(gòu)。
以?Tech Track 100強(qiáng)企業(yè)(https://link.zhihu.com/?target=http%3A//www.fasttrack.co.uk/league-tables/tech-track-100/league-table/)?這個(gè)頁(yè)面為例,你在表格上點(diǎn)右鍵,選擇“檢查”。在彈出的“開(kāi)發(fā)者工具”中,我們就能看到頁(yè)面中的每個(gè)元素,以及其中包含的內(nèi)容。


右鍵點(diǎn)擊你想要查看的網(wǎng)頁(yè)元素,選擇“檢查”,就能看到具體的 HTML 元素內(nèi)容
既然數(shù)據(jù)都保存在表格里,那么只需要簡(jiǎn)單的幾行代碼就能直接獲取到完整信息。如果你希望自己練習(xí)爬網(wǎng)頁(yè)內(nèi)容,這就是一個(gè)挺不錯(cuò)的范例。但請(qǐng)記住,實(shí)際情況往往不會(huì)這么簡(jiǎn)單。
這個(gè)例子里,所有的100個(gè)結(jié)果都包含在同一個(gè)頁(yè)面中,還被? 在表格頁(yè)面上,你可以看到一個(gè)包含了所有100條數(shù)據(jù)的表格,右鍵點(diǎn)擊它,選擇“檢查”,你就能很容易地看到這個(gè) HTML 表格的結(jié)構(gòu)。包含內(nèi)容的表格本體是在這樣的標(biāo)簽里: 每一行都是在一個(gè)? 用 Beautiful Soup 庫(kù)處理網(wǎng)頁(yè)的 HTML 內(nèi)容 在熟悉了網(wǎng)頁(yè)的結(jié)構(gòu),了解了需要抓取的內(nèi)容之后,我們終于要拿起代碼開(kāi)工啦~ 首先要做的是導(dǎo)入代碼中需要用到的各種模塊。上面我們已經(jīng)提到過(guò)? 下一步我們需要準(zhǔn)備好需要爬取的目標(biāo)網(wǎng)址。正如上面討論過(guò)的,這個(gè)網(wǎng)頁(yè)上已經(jīng)包含了所有我們需要的內(nèi)容,所以我們只需要把完整的網(wǎng)址復(fù)制下來(lái),賦值給變量就行了: 接下來(lái),我們就可以用? 這時(shí)候,你可以試著把? 如果變量?jī)?nèi)容是空的,或者返回了什么錯(cuò)誤信息,則說(shuō)明可能沒(méi)有正確獲取到網(wǎng)頁(yè)數(shù)據(jù)。你也許需要用一些錯(cuò)誤捕獲代碼,配合?urllib.error?(https://docs.python.org/3/library/urllib.error.html)模塊,來(lái)發(fā)現(xiàn)可能存在的問(wèn)題。 既然所有的內(nèi)容都在表格里( 如果你試著打印出所有的行,那應(yīng)該會(huì)有 101 行 —— 100 行內(nèi)容,加上一行表頭。 看看打印出來(lái)的內(nèi)容,如果沒(méi)問(wèn)題的話(huà),我們就可以用一個(gè)循環(huán)來(lái)獲取所有數(shù)據(jù)啦。 如果你打印出 soup 對(duì)象的前 2 行,你可以看到,每一行的結(jié)構(gòu)是這樣的: 可以看到,表格中總共有 8 列,分別是 Rank(排名)、Company(公司)、Location(地址)、Year End(財(cái)年結(jié)束)、Annual Sales Rise(年度銷(xiāo)售增長(zhǎng))、Latest Sales(本年度銷(xiāo)售額)、Staff(員工數(shù))和 Comments(備注)。 這些都是我們所需要的數(shù)據(jù)。 這樣的結(jié)構(gòu)在整個(gè)網(wǎng)頁(yè)中都保持一致(不過(guò)在其他網(wǎng)站上可能就沒(méi)這么簡(jiǎn)單了!),所以我們可以再次使用? 循環(huán)遍歷所有的元素并存儲(chǔ)在變量中 在 Python 里,如果要處理大量數(shù)據(jù),還需要寫(xiě)入文件,那列表對(duì)象是很有用的。我們可以先聲明一個(gè)空列表,填入最初的表頭(方便以后CSV文件使用),而之后的數(shù)據(jù)只需要調(diào)用列表對(duì)象的? 這樣就將打印出我們剛剛加到列表對(duì)象? 你可能會(huì)注意到,我輸入的表頭中比網(wǎng)頁(yè)上的表格多寫(xiě)了幾個(gè)列名,比如? 下一步,我們遍歷所有100行數(shù)據(jù),提取內(nèi)容,并保存到列表中。 循環(huán)讀取數(shù)據(jù)的方法: 因?yàn)閿?shù)據(jù)的第一行是 html 表格的表頭,所以我們可以跳過(guò)不用讀取它。因?yàn)楸眍^用的是? 接著,我們將 data 的內(nèi)容讀取出來(lái),賦值到變量中: 如上面的代碼所示,我們按順序?qū)?8 個(gè)列里的內(nèi)容,存儲(chǔ)到 8 個(gè)變量中。當(dāng)然,有些數(shù)據(jù)的內(nèi)容還需有額外的清理,去除多余的字符,導(dǎo)出所需的數(shù)據(jù)。 數(shù)據(jù)清理 如果我們打印出? 我們希望把? 為了區(qū)分公司名稱(chēng)和描述兩個(gè)字段,我們?cè)儆? 要?jiǎng)h除? 最后我們要保存的是公司網(wǎng)站的鏈接。就像上面說(shuō)的,第二列中有一個(gè)指向該公司詳情頁(yè)面的鏈接。每一個(gè)公司的詳情頁(yè)都有一個(gè)表格,大部分情況下,表格里都有一個(gè)公司網(wǎng)站的鏈接。 檢查公司詳情頁(yè)里,表格中的鏈接 為了抓取每個(gè)表格中的網(wǎng)址,并保存到變量里,我們需要執(zhí)行以下幾個(gè)步驟: 在最初的 fast track 網(wǎng)頁(yè)上,找到需要訪(fǎng)問(wèn)的公司詳情頁(yè)的鏈接。 發(fā)起一個(gè)對(duì)公司詳情頁(yè)鏈接的請(qǐng)求 用 Beautifulsoup 處理一下獲得的 html 數(shù)據(jù) 找到需要的鏈接元素 正如上面的截圖那樣,看過(guò)幾個(gè)公司詳情頁(yè)之后,你就會(huì)發(fā)現(xiàn),公司的網(wǎng)址基本上就在表格的最后一行。所以我們可以在表格的最后一行里找? 同樣,有可能出現(xiàn)最后一行沒(méi)有鏈接的情況。所以我們?cè)黾恿? 上面代碼的最后,我們?cè)诮Y(jié)束循環(huán)體之后打印了一下 rows 的內(nèi)容,這樣你可以在把數(shù)據(jù)寫(xiě)入文件前,再檢查一下。 寫(xiě)入外部文件 最后我們來(lái)運(yùn)行一下這個(gè) python 代碼,如果一切順利,你就會(huì)發(fā)現(xiàn)一個(gè)包含了 100 行數(shù)據(jù)的 csv 文件出現(xiàn)在了目錄中,你可以很容易地用 python 讀取和處理它。 總結(jié) 這篇簡(jiǎn)單的 Python 教程中,我們一共采取了下面幾個(gè)步驟,來(lái)爬取網(wǎng)頁(yè)內(nèi)容: 連接并獲取一個(gè)網(wǎng)頁(yè)的內(nèi)容 用 BeautifulSoup 處理獲得的 html 數(shù)據(jù) 在 soup 對(duì)象里循環(huán)搜索需要的 html 元素 進(jìn)行簡(jiǎn)單的數(shù)據(jù)清理 把數(shù)據(jù)寫(xiě)入 csv 文件中 如果有什么沒(méi)說(shuō)清楚的,歡迎大家在下面留言,我會(huì)盡可能給大家解答的! 附:?本文全部代碼(https://github.com/kaparker/tutorials/blob/master/pythonscraper/websitescrapefasttrack.py) 祝你的爬蟲(chóng)之旅有一個(gè)美好的開(kāi)始! 編譯來(lái)源:?towardsdatascience.com (完) ?標(biāo)簽分隔成行。但實(shí)際抓取過(guò)程中,許多數(shù)據(jù)往往分布在多個(gè)不同的頁(yè)面上,你需要調(diào)整每頁(yè)顯示的結(jié)果總數(shù),或者遍歷所有的頁(yè)面,才能抓取到完整的數(shù)據(jù)。 
?標(biāo)簽里,也就是我們不需要太復(fù)雜的代碼,只需要一個(gè)循環(huán),就能讀取到所有的表格數(shù)據(jù),并保存到文件里。 附注:你還可以通過(guò)檢查當(dāng)前頁(yè)面是否發(fā)送了 HTTP GET 請(qǐng)求,并獲取這個(gè)請(qǐng)求的返回值,來(lái)獲取顯示在頁(yè)面上的信息。因?yàn)?HTTP GET 請(qǐng)求經(jīng)常能返回已經(jīng)結(jié)構(gòu)化的數(shù)據(jù),比如 JSON 或者 XML 格式的數(shù)據(jù),方便后續(xù)處理。你可以在開(kāi)發(fā)者工具里點(diǎn)擊 Network 分類(lèi)(有必要的話(huà)可以?xún)H查看其中的 XHR 標(biāo)簽的內(nèi)容)。這時(shí)你可以刷新一下頁(yè)面,于是所有在頁(yè)面上載入的請(qǐng)求和返回的內(nèi)容都會(huì)在 Network 中列出。此外,你還可以用某種 REST 客戶(hù)端(比如?Insomnia)來(lái)發(fā)起請(qǐng)求,并輸出返回值。

BeautifulSoup,這個(gè)模塊可以幫我們處理 HTML 結(jié)構(gòu)。接下來(lái)要導(dǎo)入的模塊還有?urllib,它負(fù)責(zé)連接到目標(biāo)地址,并獲取網(wǎng)頁(yè)內(nèi)容。最后,我們需要能把數(shù)據(jù)寫(xiě)入 CSV 文件,保存在本地硬盤(pán)上的功能,所以我們要導(dǎo)入?csv庫(kù)。當(dāng)然這不是唯一的選擇,如果你想要把數(shù)據(jù)保存成 json 文件,那相應(yīng)的就需要導(dǎo)入?json?庫(kù)。

urllib?連上這個(gè)URL,把內(nèi)容保存在?page?變量里,然后用 BeautifulSoup 來(lái)處理頁(yè)面,把處理結(jié)果存在?soup?變量里:
soup?變量打印出來(lái),看看里面已經(jīng)處理過(guò)的 html 數(shù)據(jù)長(zhǎng)什么樣:
查找 HTML 元素
?標(biāo)簽),我們可以在?
soup?對(duì)象里搜索需要的表格,然后再用?find_all?方法,遍歷表格中的每一行數(shù)據(jù)。

find_all?方法,通過(guò)搜索??元素,逐行提取出數(shù)據(jù),存儲(chǔ)在變量中,方便之后寫(xiě)入 csv 或 json 文件。 append?方法即可。
rows?中的第一行表頭。Webpage(網(wǎng)頁(yè))和?Description(描述),請(qǐng)仔細(xì)看看上面打印出的 soup 變量數(shù)據(jù)——第二行第二列的數(shù)據(jù)里,可不只有公司名字,還有公司的網(wǎng)址和簡(jiǎn)單描述。所以我們需要這些額外的列來(lái)存儲(chǔ)這些數(shù)據(jù)。
?標(biāo)簽,沒(méi)有用? ?標(biāo)簽,所以我們只要簡(jiǎn)單地查詢(xún)? 標(biāo)簽內(nèi)的數(shù)據(jù),并且拋棄空值即可。 
company?變量的內(nèi)容,就能發(fā)現(xiàn),它不但包含了公司名稱(chēng),還包括和描述。如果我們打印出?sales?變量的內(nèi)容,就能發(fā)現(xiàn)它還包括一些備注符號(hào)等需要清除的字符。
company?變量的內(nèi)容分割成公司名稱(chēng)和描述兩部分。這用幾行代碼就能搞定。再看看對(duì)應(yīng)的 html 代碼,你會(huì)發(fā)現(xiàn)這個(gè)單元格里還有一個(gè)??元素,這個(gè)元素里只有公司名稱(chēng)。另外,還有一個(gè)??鏈接元素,包含一個(gè)指向該公司詳情頁(yè)面的鏈接。我們一會(huì)也會(huì)用到它!
find?方法把??元素里的內(nèi)容讀取出來(lái),然后刪掉或替換?company?變量中的對(duì)應(yīng)內(nèi)容,這樣變量里就只會(huì)留下描述了。sales?變量中的多余字符,我們用一次?strip?方法即可。

?元素。
try... except?語(yǔ)句,如果沒(méi)有發(fā)現(xiàn)網(wǎng)址,則將變量設(shè)置成?None。當(dāng)我們把所有需要的數(shù)據(jù)都存在變量中的以后(還在循環(huán)體內(nèi)部),我們可以把所有變量整合成一個(gè)列表,再把這個(gè)列表?append?到上面我們初始化的 rows 對(duì)象的末尾。
最后,我們把上面獲取的數(shù)據(jù)寫(xiě)入外部文件,方便之后的分析處理。在 Python 里,我們只需要簡(jiǎn)單的幾行代碼,就可以把列表對(duì)象保存成文件。

【提高】40多個(gè)項(xiàng)目實(shí)戰(zhàn),老手可以從真實(shí)場(chǎng)景中學(xué)習(xí)python;
【直播】不定期直播項(xiàng)目案例講解,手把手教你如何分析項(xiàng)目;
【分享】?jī)?yōu)質(zhì)python學(xué)習(xí)資料分享,讓你在最短時(shí)間獲得有價(jià)值的學(xué)習(xí)資源;圈友優(yōu)質(zhì)資料或?qū)W習(xí)分享,會(huì)不時(shí)給予贊賞支持,希望每個(gè)優(yōu)質(zhì)圈友既能賺回加入費(fèi)用,也能快速成長(zhǎng),并享受分享與幫助他人的樂(lè)趣。
【人脈】收獲一群志同道合的朋友,并且都是python從業(yè)者
【價(jià)格】本著布道思想,只需 69元 加入一個(gè)能保證學(xué)習(xí)效果的良心圈子。
国产精品秘 swag
|
久久99国产精品一区二区
|
成人在线免费观看视频
|
四虎成人精品永久免费AV
|
色偷偷网站
|

