- 原文地址:How to scrape websites with Python and BeautifulSoup
- 原文做者:Justin Yek
- 譯文出自:掘金翻譯計劃
- 本文永久連接:github.com/xitu/gold-m…
- 譯者:geniusq1981
- 校對者:Park-ma、coolseaman
互聯網上的信息量比任何一我的究其一輩子所能掌握的信息量都要大的多。因此咱們要作的不是在互聯網上逐個訪問信息,而是須要有一種靈活的方式來收集,整理和分析這些信息。html
咱們須要爬取網頁數據。前端
網頁爬蟲能夠自動提取出數據並將數據以一種你能夠容易理解的形式呈現出來。在本教程中,咱們將重點關注爬蟲技術在金融市場中的應用,但實際上網絡內容爬取可用於多個領域。python
若是你是一個狂熱的投資者,天天獲知收盤價可能會是一件很痛苦的事,特別是當你須要的信息分散在多個網頁的時候。咱們將經過構建一個網絡爬蟲來自動從網上檢索股票指數,從而簡化數據的爬取。mysql
咱們將使用 Python 做爲咱們的爬蟲語言,還會用到一個簡單但很強大的庫,BeautifulSoup。android
python --version
。你的 Python 的版本應該是 2.7.x。接下來,咱們須要使用 Python 的包管理工具 pip
來安裝 BeautifulSoup 庫。ios
在終端中輸入:git
easy_install pip
pip install BeautifulSoup4
複製代碼
注意:若是你執行上面的命令發生了錯誤,請嘗試在每一個命令前面添加 sudo
。github
在咱們真正開始編寫代碼以前,讓咱們先了解下 HTML 的基礎知識和一些網頁爬蟲的規則。web
HTML 標籤
若是你已經理解了 HTML 的標籤,請跳過這部分。sql
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<h1> First Scraping </h1>
<p> Hello World </p>
<body>
</html>
複製代碼
下面是一個 HTML 網頁的基本語法。網頁上的每一個標籤都定義了一個內容塊:
<!DOCTYPE html>
:HTML 文檔的開頭必須有的類型聲明。<html>
內。<head>
標籤裏面是元數據和 HTML 文檔的腳本聲明。<body>
標籤裏面是 HTML 文檔的可視部分。<h1>
到 <h6>
的標籤訂義。<p>
標籤裏。其餘經常使用的標籤還有,用於超連接的 <a>
標籤,用於顯示錶格的 <table>
標籤,以及用於顯示錶格行的 <tr>
標籤,用於顯示錶格列的 <td>
標籤。
另外,HTML 標籤時常會有 id
或者 class
屬性。id
屬性定義了標籤的惟一標識,而且這個值在當前文檔中必須是惟一的。class
屬性用來給具備相同類屬性的 HTML 標籤訂義相同的樣式。咱們可使用這些 id 和 class 來幫助咱們定位咱們要爬取的數據。
須要更多關於 HTML 標籤、 id 和 class 的相關內容,請參考 W3Schools 網站的 教程。
爬取規則
讓咱們以 Bloomberg Quote 網站的一個頁面爲例。
由於有些人會關注股市,那麼咱們就從這個頁面上獲取指數名稱(標準普爾 500 指數)和它的價格。首先,從鼠標右鍵菜單中點擊 Inspect 選項來查看頁面。
試着把鼠標指針懸浮在價格上,你應該能夠看到出現了一個藍色方形區域包裹住了價格。若是你點擊,在瀏覽器的控制檯上,這段 HTML 內容就被選定了。
經過結果,你能夠看到價格被好幾層 HTML 標籤包裹着,<div class="basic-quote">
→ <div class="price-container up">
→ <div class="price">
。
相似的,若是你懸浮而且點擊「標準普爾 500 指數」,它被包裹在 <div class="basic-quote">
和 <h1 class="name">
裏面。
如今咱們經過 class
標籤的幫助,知道了所需數據的確切位置。
既然咱們知道數據在哪兒了,咱們就能夠編寫網頁爬蟲了。如今打開你的文本編輯器。
首先,須要導入全部咱們須要用到的庫。
# import libraries
import urllib2
from bs4 import BeautifulSoup
複製代碼
接下來,聲明一個網址連接變量。
# specify the url
quote_page = ‘http://www.bloomberg.com/quote/SPX:IND'
複製代碼
而後,使用 Python 的 urllib2 來請求聲明的 url 指向的 HTML 網頁。
# query the website and return the html to the variable ‘page’
page = urllib2.urlopen(quote_page)
複製代碼
最後,把頁面內容解析成 BeatifulSoup 的格式,以便咱們可以使用 BeautifulSoup 去處理。。
# parse the html using beautiful soup and store in variable `soup`
soup = BeautifulSoup(page, ‘html.parser’)
複製代碼
如今咱們有一個變量 soup
,它包含了頁面的 HTML 內容。這裏咱們就能夠編寫爬取數據的代碼了。
還記得數據的獨特的層級結構嗎?BeautifulSoup 的 find()
方法能夠幫助咱們找到這些層級結構,而後提取內容。在這個例子中,由於這段 HTML 的 class 名稱是惟一的,全部咱們很容易找到 <div class="name">
。
# Take out the <div> of name and get its value
name_box = soup.find(‘h1’, attrs={‘class’: ‘name’})
複製代碼
咱們能夠經過獲取標籤的 text 屬性來獲取數據。
name = name_box.text.strip() # strip() is used to remove starting and trailing
print name
複製代碼
相似地,咱們也能夠獲取價格。
# get the index price
price_box = soup.find(‘div’, attrs={‘class’:’price’})
price = price_box.text
print price
複製代碼
當你運行這個程序,你能夠看到標準普爾 500 指數的當前價格被打印了出來。
既然咱們有了數據,是時候去保存它了。Excel 的 csv 格式是一個很好的選擇。它能夠經過 Excel 打開,因此你能夠很輕鬆的打開並處理數據。
可是,首先,咱們必須把 Python csv 模塊導入進來,還要導入 datetime 模塊來獲取記錄的日期。在 import 部分,加入下面這幾行代碼。
import csv
from datetime import datetime
複製代碼
在你的代碼底部,添加保存數據到 csv 文件的代碼。
# open a csv file with append, so old data will not be erased
with open(‘index.csv’, ‘a’) as csv_file:
writer = csv.writer(csv_file)
writer.writerow([name, price, datetime.now()])
複製代碼
若是你如今運行你的程序,你應該能夠導出一個index.csv文件,而後你能夠用 Excel 打開它,在裏面能夠看到一行數據。
若是你天天運行這個程序,你就能夠很簡單地獲取標準普爾 500 指數,而不用重複地經過網頁查找。
多個指數
對你來講,只獲取一個指數遠遠不夠,對不對?咱們能夠同時提取多個指數。
首先,將 quote_page
變量修改成一個 URL 的數組。
quote_page = [‘http://www.bloomberg.com/quote/SPX:IND', ‘http://www.bloomberg.com/quote/CCMP:IND']
複製代碼
而後咱們把數據提取代碼變成 for
循環,這樣能夠一個接一個地處理 URL,而後把全部的數據都存到元組 data
中。
# for loop
data = []
for pg in quote_page:
# query the website and return the html to the variable ‘page’
page = urllib2.urlopen(pg)
# parse the html using beautiful soap and store in variable `soup`
soup = BeautifulSoup(page, ‘html.parser’)
# Take out the <div> of name and get its value
name_box = soup.find(‘h1’, attrs={‘class’: ‘name’})
name = name_box.text.strip() # strip() is used to remove starting and trailing
# get the index price
price_box = soup.find(‘div’, attrs={‘class’:’price’})
price = price_box.text
# save the data in tuple
data.append((name, price))
複製代碼
而後,修改「保存部分」的代碼以逐行保存數據。
# open a csv file with append, so old data will not be erased
with open(‘index.csv’, ‘a’) as csv_file:
writer = csv.writer(csv_file)
# The for loop
for name, price in data:
writer.writerow([name, price, datetime.now()])
複製代碼
從新運行代碼,你應該能夠同時提取到兩個指數了。
BeautifulSoup 是一個簡單且強大的小規模的網頁爬蟲工具。可是若是你對更大規模的網絡數據爬蟲感興趣,那麼你應該考慮使用其餘的替代工具。
DRY(Don't Repeat Yourself)表明「不要重複本身的工做」,嘗試把你每日工做都自動化,像 這我的 作的那樣。能夠考慮一些有趣的項目,多是跟蹤你的 Facebook 好友的活躍時間(須要得到他們的贊成),或者是獲取論壇的演講列表並嘗試進行天然語言處理(這是當前人工智能的一個熱門話題)!
若是你有任何問題,能夠隨時在下面留言。
參考:
這篇文章最初發表在 Altitude Labs 的 博客上,做者是咱們的軟件工程師 Leonard Mok。Altitude Labs 是一家專門從事 React 移動應用定製開發的軟件代理商。
若是發現譯文存在錯誤或其餘須要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可得到相應獎勵積分。文章開頭的 本文永久連接 即爲本文在 GitHub 上的 MarkDown 連接。
掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 Android、iOS、前端、後端、區塊鏈、產品、設計、人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。