如何用 Python 实现 Web 抓取?
【編者按】本文作者為 Blog Bowl 聯(lián)合創(chuàng)始人 Shaumik Daityari,主要介紹 Web 抓取技術(shù)的基本實(shí)現(xiàn)原理和方法。文章系國內(nèi) ITOM 管理平臺(tái) OneAPM 編譯呈現(xiàn),以下為正文。
隨著電子商務(wù)的蓬勃發(fā)展,筆者近年越來越著迷于比價(jià)應(yīng)用。我在網(wǎng)絡(luò)上(甚至線下)的每次購買,都是在各大電商網(wǎng)站深入調(diào)研后的結(jié)果。
筆者常用的比價(jià)應(yīng)用包括:RedLaser, ShopSavvy 以及 BuyHatke。這些應(yīng)用有效提高了價(jià)格透明度,進(jìn)而為消費(fèi)者節(jié)省了可觀的時(shí)間。
但是,你是否想過,這些應(yīng)用如何得到那些重要數(shù)據(jù)?通常,它們會(huì)借助 Web 抓取技術(shù)來完成該任務(wù)。
Web 抓取的定義
Web 抓取是抽取網(wǎng)絡(luò)數(shù)據(jù)的過程。只要借助合適的工具,任何你能看到的數(shù)據(jù)都可以進(jìn)行抽取。在本文中,我們將重點(diǎn)介紹自動(dòng)化抽取過程的程序,幫助你在較短時(shí)間內(nèi)收集大量數(shù)據(jù)。除了筆者前文提到的用例,抓取技術(shù)的用途還包括:SEO 追蹤、工作追蹤、新聞分析以及筆者的最愛——社交媒體的情感分析!
一點(diǎn)提醒
在開啟 Web 抓取的探險(xiǎn)之前,請(qǐng)確保自己了解相關(guān)的法律問題。許多網(wǎng)站在其服務(wù)條款中明確禁止對(duì)其內(nèi)容進(jìn)行抓取。例如,Medium 網(wǎng)站就寫道:“遵照網(wǎng)站 robots.txt 文件中的規(guī)定進(jìn)行的爬取操作(Crawling)是可接受的,但是我們禁止抓取(Scraping)操作。”對(duì)不允許抓取的網(wǎng)站進(jìn)行抓取可能會(huì)使你進(jìn)入他們的黑名單!與任何工具一樣,Web 抓取也可能用于復(fù)制網(wǎng)站內(nèi)容之類的不良目的。此外,由 Web 抓取引起的法律訴訟也不在少數(shù)。
設(shè)置代碼
在充分了解小心行事的必要之后,讓我們開始學(xué)習(xí) Web 抓取。其實(shí),Web 抓取可以通過任何編程語言實(shí)現(xiàn),在不久之前,我們使用 Node 實(shí)現(xiàn)過。在本文中,考慮到其簡潔性與豐富的包支持,我們將使用 Python 實(shí)現(xiàn)抓取程序。
Web 抓取的基本過程
當(dāng)你打開網(wǎng)絡(luò)中的某個(gè)站點(diǎn)時(shí),就會(huì)下載其 HTML 代碼,由你的 web 瀏覽器對(duì)其進(jìn)行分析與展示。該 HTML 代碼包含了你所看到的所有信息。因此,通過分析 HTML 代碼就能得到所需信息(比如價(jià)格)。你可以使用正則表達(dá)式在數(shù)據(jù)海洋中搜索你需要的信息,也可以使用函數(shù)庫來解釋 HTML,同樣也能得到需要數(shù)據(jù)。
在 Python 中,我們將使用一個(gè)名為靚湯(Beautiful Soup)的模塊對(duì) HTML 數(shù)據(jù)進(jìn)行分析。你可以借助 pip 之類的安裝程序安裝之,運(yùn)行如下代碼即可:
pip install beautifulsoup4或者,你也可以根據(jù)源碼進(jìn)行構(gòu)建。在該模塊的文檔說明頁,可以看到詳細(xì)的安裝步驟。
安裝完成之后,我們大致會(huì)遵循以下步驟實(shí)現(xiàn) web 抓取:
- 向 URL 發(fā)送請(qǐng)求
- 接收響應(yīng)
- 分析響應(yīng)以尋找所需數(shù)據(jù)
作為演示,我們將使用筆者的博客 http://dada.theblogbowl.in/. 作為目標(biāo) URL。
前兩個(gè)步驟相對(duì)簡單,可以這樣完成:
from urllib import urlopen#Sending the http requestwebpage = urlopen('http://my_website.com/').read()接下來,將響應(yīng)傳給之前安裝的模塊:
from bs4 import BeautifulSoup#making the soup! yummy ;)soup = BeautifulSoup(webpage, "html5lib")請(qǐng)注意,此處我們選擇了 html5lib 作為解析器。根據(jù) BeautifulSoup 的文檔,你也可以為其選擇不同的解析器。
解析 HTML
在將 HTML 傳給 BeautifulSoup 之后,我們可以嘗試一些指令。譬如,檢查 HTML 標(biāo)記代碼是否正確,可以驗(yàn)證該頁面的標(biāo)題(在 Python 解釋器中):
>>> soup.title<title>Transcendental Tech Talk</title>>>> soup.title.text u'Transcendental Tech Talk' >>>接下來,開始抽取頁面中的特定元素。譬如,我想抽取博客中文章標(biāo)題的列表。為此,我需要分析 HTML 的結(jié)構(gòu),這一點(diǎn)可以借助 Chrome 檢查器完成。其他瀏覽器也提供了類似的工具。
使用 Chrome 檢查器檢查某個(gè)頁面的 HTML 結(jié)構(gòu)
如你所見,所有文章標(biāo)題都帶有 h3 標(biāo)簽與兩個(gè)類屬性:post-title 與 entry-title 類。因此,用 post-title 類搜索所有 h3 元素就能得到該頁的文章標(biāo)題列表。在此例中,我們使用 BeautifulSoup 提供的 find_all 函數(shù),并通過 class_ 參數(shù)確定所需的類:
>>> titles = soup.find_all('h3', class_ = 'post-title') #Getting all titles>>> titles[0].textu'\nKolkata #BergerXP IndiBlogger meet, Marketing Insights, and some Blogging Tips\n'>>>只通過 post-title 類進(jìn)行條目搜索應(yīng)該可以得到相同的結(jié)果:
>>> titles = soup.find_all(class_ = 'post-title') #Getting all items with class post-title>>> titles[0].textu'\nKolkata #BergerXPIndiBlogger meet, Marketing Insights, and some Blogging Tips\n'>>>如果你想進(jìn)一步了解條目所指的鏈接,可以運(yùn)行下面的代碼:
>>> for title in titles:... # Each title is in the form of <h3 ...><a href=...>Post Title<a/></h3>... print title.find("a").get("href")...http://dada.theblogbowl.in/2015/09/kolkata-bergerxp-indiblogger-meet.html http://dada.theblogbowl.in/2015/09/i-got-published.html http://dada.theblogbowl.in/2014/12/how-to-use-requestput-or-requestdelete.html http://dada.theblogbowl.in/2014/12/zico-isl-and-atk.html...>>>BeautifulSoup 內(nèi)置了許多方法,可以幫助你玩轉(zhuǎn) HTML。其中一些方法列舉如下:
>>> titles[0].contents [u'\n', <a href="http://dada.theblogbowl.in/2015/09/kolkata-bergerxp-indiblogger-meet.html">Kolkata #BergerXP IndiBlogger meet, Marketing Insights, and some Blogging Tips</a>, u'\n']>>>請(qǐng)注意,你也可以使用 children 屬性,不過它有點(diǎn)像生成器:
>>> titles[0].parent<div class="post hentry uncustomized-post-template">\n<a name="6501973351448547458"></a>\n<h3 class="post-title entry-title">\n<a href="http://dada.theblogbowl.in/2015/09/kolkata-bergerxp-indiblogger-meet.html">Kolkata #BergerXP IndiBlogger ... >>>你也可以使用正則表達(dá)式搜索 CSS 類,對(duì)此,本文檔有詳細(xì)的介紹。
使用 Mechanize 模擬登錄
目前為止,我們做的只是下載一個(gè)頁面進(jìn)而分析其內(nèi)容。然而,web 開發(fā)者可能屏蔽了非瀏覽器發(fā)出的請(qǐng)求,或者有些網(wǎng)站內(nèi)容只能在登錄之后讀取。那么,我們?cè)撊绾翁幚磉@些情況呢?
對(duì)于第一種情況,我們需要在向頁面發(fā)送請(qǐng)求時(shí)模擬一個(gè)瀏覽器。每個(gè) HTTP 請(qǐng)求都包含一些相關(guān)的數(shù)據(jù)頭(header),其中包含了訪客瀏覽器、操作系統(tǒng)以及屏幕大小之類的信息。我們可以改變這些數(shù)據(jù)頭,偽裝為瀏覽器發(fā)送請(qǐng)求。
至于第二種情況,為了訪問帶有訪客限制的內(nèi)容,我們需要登錄該網(wǎng)站,使用 cookie 保持會(huì)話。下面,讓我們來看看在偽裝成瀏覽器的同時(shí),如何完成這一點(diǎn)。
我們將借助 cookielib 模塊使用 cookie 管理會(huì)話。此外,我們還將用到 mechanize,后者可以使用 pip 之類的安裝程序進(jìn)行安裝。
我們會(huì)通過 Blog Bowl 這個(gè)頁面進(jìn)行登錄,并訪問通知頁面。下面的代碼通過行內(nèi)注釋進(jìn)行了解釋:
import mechanize import cookielibfrom urllib import urlopen from bs4 import BeautifulSoup# Cookie Jarcj = cookielib.LWPCookieJar()browser = mechanize.Browser() browser.set_cookiejar(cj) browser.set_handle_robots(False) browser.set_handle_redirect(True)# Solving issue #1 by emulating a browser by adding HTTP headersbrowser.addheaders = [('User-agent', 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.1) Gecko/2008071615 Fedora/3.0.1-1.fc9 Firefox/3.0.1')]# Open Login Pagebrowser.open("http://theblogbowl.in/login/")# Select Login form (1st form of the page)browser.select_form(nr = 0)# Alternate syntax - browser.select_form(name = "form_name")# The first <input> tag of the form is a CSRF token# Setting the 2nd and 3rd tags to email and passwordbrowser.form.set_value("email@example.com", nr=1) browser.form.set_value("password", nr=2)# Logging inresponse = browser.submit()# Opening new page after loginsoup = BeautifulSoup(browser.open('http://theblogbowl.in/notifications/').read(), "html5lib")
通知頁面的結(jié)構(gòu)
登錄進(jìn)通知頁面后的結(jié)果
結(jié)語
許多開發(fā)者會(huì)告訴你:你在網(wǎng)絡(luò)上看到的任何信息都可以被抓取。通過這篇文章,你學(xué)會(huì)了如何輕松抽取登錄后才能看到的內(nèi)容。此外,如果你的 IP 遭到了屏蔽,你可以掩蓋自己的 IP 地址(或選用其他地址)。同時(shí),為了看起來像是人類在訪問,你應(yīng)該在請(qǐng)求之間保留一定的時(shí)間間隔。
隨著人們對(duì)數(shù)據(jù)的需求不斷增長,web 抓取(不論原因好壞)技術(shù)在未來的應(yīng)用只會(huì)更加廣泛。也因此,理解其原理是相當(dāng)重要的,不管你是為了有效利用該技術(shù),還是為了免受其坑害。
OneAPM 能幫您查看 Python 應(yīng)用程序的方方面面,不僅能夠監(jiān)控終端的用戶體驗(yàn),還能監(jiān)控服務(wù)器性能,同時(shí)還支持追蹤數(shù)據(jù)庫、第三方 API 和 Web 服務(wù)器的各種問題。想技術(shù)文章,請(qǐng)?jiān)L問 OneAPM 官方技術(shù)博客。
本文轉(zhuǎn)自 OneAPM 官方博客
原文地址:https://www.sitepoint.com/web-scraping-for-beginners/
總結(jié)
以上是生活随笔為你收集整理的如何用 Python 实现 Web 抓取?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 奶奶梦到孙女丢了是什么征兆
- 下一篇: 梦到大蟾蜍预示着什么