使用 Beautiful Soup 的 Python 網頁抓取指南

已發表: 2020-06-23
目錄顯示
使用 Python 進行網頁抓取簡介:
BeautifulSoup 是如何工作的?
如何使用 BeautifulSoup 從網頁中抓取數據?
網頁抓取過程:
結論:

使用 Python 進行網頁抓取簡介:

在網絡抓取方面,某些編程語言比其他編程語言更受歡迎。 其中最受歡迎的之一是 Python。 除了由於其更溫和的學習曲線而成為最容易學習的語言之一之外,它還具有作為具有大量開發人員支持的語言的優勢 - 這導致了許多第三方軟件包。 這些包可用於多種功能,這可能難以使用核心 Python 執行。 一些常見的例子是——對於圖像處理或計算機視覺,我們使用 OpenCV,對於機器學習,我們使用 TensorFlow,對於繪圖,我們使用 MatplotLib。 說到網頁抓取,最常用的庫之一是 BeautifulSoup。 該庫並不專門從互聯網上抓取數據,但如果您可以獲取網頁的 HTML 文件,它可以幫助從中提取特定的數據點。 通常,該庫用於從 XML 和 HTML 文檔中提取數據點。

BeautifulSoup 是如何工作的?

在繼續用 Python 編寫代碼之前,您必須了解 BeautifulSoup 的工作原理。 一旦你提取了網頁的 HTML 內容並將其存儲在一個變量中,比如 html_obj,你就可以只用一行代碼將它轉換成一個 BeautifulSoup 對象——

soup_obj = BeautifulSoup(html_obj, 'html.parser')

其中 html_obj 是 HTML 數據,soup_obj 是已獲取的 bs 對象,“html.parser”是用於進行轉換的解析器。 一旦有了bs 對象,稱為soup_obj,遍歷它就非常容易,而且由於遍歷它很簡單,數據提取也變得簡單。 讓我們舉個例子。 假設您需要獲取一個名為產品標題的數據點,該數據點出現在電子商務網站的每個頁面上。 現在,您從該網站下載了一個 HTML 產品頁面,並意識到每個頁面都有一個類型為 span 的元素中提到的產品名稱,其 id 為 productTitle。 那麼你將如何從 1000 個產品頁面中獲取這些數據呢? 好吧,您將獲取每個頁面的 HTML 數據,並以這種方式獲取數據點 -

對於 soup.findAll('span', attrs={'id': 'productTitle'}) 中的跨度:
name_of_product = spans.text.strip()

雖然這是一種獲取某個標籤元素之間存在的文本數據的方法,但您也可以從標籤的屬性中獲取數據。

網頁抓取

如何使用 BeautifulSoup 從網頁中抓取數據?

現在我們對如何遍歷 bs 對像有了一些基本的了解,讓我們編寫一些代碼,看看它是如何工作的。 使用下面的代碼片段,您可以非常輕鬆地從美國領先的房地產市場 Zillow 中抓取數據。 您可以運行此代碼並輸入列表的 URL,以獲取 JSON 格式的輸出數據。 讓我們逐行理解代碼。 首先,確保您的機器上安裝了 Python 3.7 或更高版本。 使用 pip 安裝 BeautifulSoup。 所有其他軟件包都與 Python 預先捆綁在一起,因此您無需安裝任何軟件包。 完成後,安裝 Atom 或 VS Code 之類的代碼編輯器,即可開始使用。 理解代碼很重要,因此我們將從第一行開始。 您需要四個導入語句來實現特定功能。 接下來,您有三行以“ctx”開頭。 這些專門用於忽略您在通過代碼訪問網站時可能遇到的 SSL 證書錯誤。 接下來,我們將網站 URL 作為用戶的輸入。 在這裡,您也可以對 URL 進行硬編碼,甚至可以擁有多個 URL 的數組。

網頁抓取過程:

接下來,我們使用urllib的Request函數訪問網頁。 確保在標題中添加 User-Agent 以使網站相信您正在使用瀏覽器。 這樣做的原因是網站是由瀏覽器而不是代碼訪問的,因此如果他們抓住你,他們可能會阻止你的 IP。 完成後,我們完成了所有基本步驟,接下來,我們將 HTML 對象轉換為 bs 對象,然後將其美化為 utf-8 格式,以處理網頁中的特殊字符和符號。 完成後,我們通過解析 bs 對象來提取標題、簡短細節和其他屬性。 可以看到,在屬性type = application/ld+json的script標籤中,有多個數據點都以JSON格式存儲。 此外,您可以看到我們使用了 i==0 和 i==1 檢查。 這是因為在一個頁面中有兩個這樣的腳本標籤(具有相同的屬性)。 第一個標籤給了我們一些數據點,而第二個給了我們剩下的。 一旦我們提取了所有數據點,您就可以將其存儲在 JSON 文件中並按原樣保存。 如果需要,您還可以保存、將其上傳到站點,甚至可以使用數據訪問 API。

導入json
導入 ssl
from urllib.request 導入請求,urlopen
從 bs4 導入 BeautifulSoup

# 忽略 SSL 證書錯誤
ctx = ssl.create_default_context()
ctx.check_hostname = 假
ctx.verify_mode = ssl.CERT_NONE

# 將 Zillow 列表 URL 作為輸入
url = input('輸入 Zillow 房屋列表 URL-')

# 讓網站相信你正在使用瀏覽器
req = Request(url, headers={'User-Agent': 'Mozilla/5.0'})
網頁 = urlopen(req).read()

# HTML 頁面 -> BeautifulSoup 對象湯 = BeautifulSoup(webpage, 'html.parser')
html = soup.prettify('utf-8')
property_details = {'details_long':{},'地址':{}}

# 提取屬性列表的不同數據點
對於 soup.findAll('title') 中的標題:
property_details['Title'] = title.text.strip()
休息

對於 soup.findAll('meta', attrs={'name': 'description'}) 中的元數據:
property_details['details_short'] = meta['content'].strip()

對於soup.findAll('div',attrs = {'class':'character-count-truncated'})中的div:
property_details['details_long']['Description'] = div.text.strip()

for (i, script) in enumerate(soup.findAll('script',
attrs={'type': 'application/ld+json'})):
如果我 == 0:
json_data = json.loads(script.text)
property_details['details_long']['no_of_rooms'] = json_data['numberOfRooms']
property_details['details_long']['floor_size_in_sqrft'] = json_data['floorSize']['value']
property_details['address']['street'] = json_data['address']['streetAddress']
property_details['address']['locality'] = json_data['address']['addressLocality']
property_details['address']['region'] = json_data['address']['addressRegion']
property_details['address']['postal_code'] = json_data['address']['postalCode']
如果我 == 1:
json_data = json.loads(script.text)
property_details['price_in_dollars'] = json_data['offers']['price']
property_details['inage'] = json_data['image']
休息

使用 open('house_listing_data.json', 'w') 作為輸出文件:
json.dump(property_details, outfile, indent=4)

使用 open('house_listing_data.html', 'wb') 作為文件:
文件.write(html)

print('———-數據提取完成。檢查json文件。———-')

輸出 JSON 應該看起來像這樣 -

{
“details_long”:{
“no_of_rooms”:3,
“floor_size_in_sqrft”:“1,392”
},
“地址”: {
“街”:“22516 瓊博士”,
“地點”:“加利福尼亞”,
“地區”:“MD”,
“郵政編碼”:“20619”
},
“標題”:“22516 Joan Dr, California, MD 20619 | MLS #MDSM167670”,
“details_short”:“22516 Joan Dr , California, MD 20619-3175 是一棟掛牌出售的單戶住宅,售價 150,000 美元。 這座 1,392 平方英尺的住宅是一個 3 床、2.0 浴室的房產。 在 Zillow 上查找 22516 Joan Dr 家的 40 張照片。 在 Zillow 上查看更多房產詳情、銷售歷史和 Zestimate 數據。 MLS # MDSM167670”,
“price_in_dollars”:150000,
“inage”:“https://photos.zillowstatic.com/p_h/ISn2oi3glpvdv10000000000.jpg”
}

結論:

只要您首先可以手動分析 HTML 頁面並確定需要定位的標籤,就可以輕鬆地使用 BeautifulSoup 來滿足您的網絡抓取需求。 它可以在沒有任何動態內容且不位於登錄頁面後面的頁面上工作。 對於更複雜的網頁,您將需要更複雜的工具。 我們在 PromptCloud 的團隊幫助那些希望利用數據並做出數據支持決策的公司。 我們不僅幫助建立在雲端頻繁運行的全自動網絡抓取引擎,還幫助公司分析數據以提取趨勢和其他有用信息。