[譯] 如何使用 Python 和 BeautifulSoup 爬取網站內容

互聯網上的信息量比任何一我的究其一輩子所能掌握的信息量都要大的多。因此咱們要作的不是在互聯網上逐個訪問信息,而是須要有一種靈活的方式來收集,整理和分析這些信息。html

咱們須要爬取網頁數據。前端

網頁爬蟲能夠自動提取出數據並將數據以一種你能夠容易理解的形式呈現出來。在本教程中,咱們將重點關注爬蟲技術在金融市場中的應用,但實際上網絡內容爬取可用於多個領域。python

若是你是一個狂熱的投資者,天天獲知收盤價可能會是一件很痛苦的事,特別是當你須要的信息分散在多個網頁的時候。咱們將經過構建一個網絡爬蟲來自動從網上檢索股票指數,從而簡化數據的爬取。mysql

入門

咱們將使用 Python 做爲咱們的爬蟲語言,還會用到一個簡單但很強大的庫,BeautifulSoup。android

  • 對於 Mac 用戶,OS X 已經預裝了 Python。打開終端並輸入 python --version。你的 Python 的版本應該是 2.7.x。
  • 對於 Windows 用戶,請經過 官方網站 安裝 Python。

接下來,咱們須要使用 Python 的包管理工具 pip 來安裝 BeautifulSoup 庫。ios

在終端中輸入:git

easy_install pip  
pip install BeautifulSoup4
複製代碼

注意:若是你執行上面的命令發生了錯誤,請嘗試在每一個命令前面添加 sudogithub

基礎知識

在咱們真正開始編寫代碼以前,讓咱們先了解下 HTML 的基礎知識和一些網頁爬蟲的規則。web

HTML 標籤
若是你已經理解了 HTML 的標籤,請跳過這部分。sql

<!DOCTYPE html>  
<html>  
    <head>
    </head>
    <body>
        <h1> First Scraping </h1>
        <p> Hello World </p>
    <body>
</html>
複製代碼

下面是一個 HTML 網頁的基本語法。網頁上的每一個標籤都定義了一個內容塊:

  1. <!DOCTYPE html>:HTML 文檔的開頭必須有的類型聲明。
  2. HTML 的文檔包含在標籤 <html> 內。
  3. <head> 標籤裏面是元數據和 HTML 文檔的腳本聲明。
  4. <body> 標籤裏面是 HTML 文檔的可視部分。
  5. 標題經過 <h1><h6> 的標籤訂義。
  6. 段落內容被定義在 <p> 標籤裏。

其餘經常使用的標籤還有,用於超連接的 <a> 標籤,用於顯示錶格的 <table> 標籤,以及用於顯示錶格行的 <tr> 標籤,用於顯示錶格列的 <td> 標籤。

另外,HTML 標籤時常會有 id 或者 class 屬性。id 屬性定義了標籤的惟一標識,而且這個值在當前文檔中必須是惟一的。class 屬性用來給具備相同類屬性的 HTML 標籤訂義相同的樣式。咱們可使用這些 id 和 class 來幫助咱們定位咱們要爬取的數據。

須要更多關於 HTML 標籤idclass 的相關內容,請參考 W3Schools 網站的 教程

爬取規則

  1. 你應該在爬取以前先檢查一下網站使用條款。仔細的閱讀其中關於合法使用數據的聲明。通常來講,你爬取的數據不能用於商業用途。
  2. 你的爬取程序不要太有攻擊性地從網站請求數據(就像衆所周知的垃圾郵件攻擊同樣),那可能會對網站形成破壞。確保你的爬蟲程序以合理的方式運行(如同一我的在操做網站那樣)。一個網頁每秒請求一次是個很好的作法。
  3. 網站的佈局時不時的會有變化,因此要確保常常訪問網站而且必要時及時重寫你的代碼。

檢查網頁

讓咱們以 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 的 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 是一個簡單且強大的小規模的網頁爬蟲工具。可是若是你對更大規模的網絡數據爬蟲感興趣,那麼你應該考慮使用其餘的替代工具。

  1. Scrapy,一個強大的 Python 爬蟲框架
  2. 嘗試將你的代碼與一些公共 API 集成。數據檢索的效率要遠遠高於網頁爬蟲的效率。好比,看一下 Facebook Graph API,它能夠幫助你獲取未在 Facebook 網頁上顯示的隱藏數據。
  3. 若是爬取數據過大,請考慮使用一個後臺數據庫來存儲你的數據,好比 MySQL

採用 DRY 方法

DRY(Don't Repeat Yourself)表明「不要重複本身的工做」,嘗試把你每日工做都自動化,像 這我的 作的那樣。能夠考慮一些有趣的項目,多是跟蹤你的 Facebook 好友的活躍時間(須要得到他們的贊成),或者是獲取論壇的演講列表並嘗試進行天然語言處理(這是當前人工智能的一個熱門話題)!

若是你有任何問題,能夠隨時在下面留言。

參考:

這篇文章最初發表在 Altitude Labs博客上,做者是咱們的軟件工程師 Leonard MokAltitude Labs 是一家專門從事 React 移動應用定製開發的軟件代理商。

若是發現譯文存在錯誤或其餘須要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可得到相應獎勵積分。文章開頭的 本文永久連接 即爲本文在 GitHub 上的 MarkDown 連接。


掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章
相關標籤/搜索