關於爬蟲的案例和方法,咱們已講過許多。不過在以往的文章中,大可能是關注在如何把網頁上的內容抓取下來。今天咱們來分享下,當你已經把內容爬下來以後,如何提取出其中你須要的具體信息。html
網頁被抓取下來,一般就是str 字符串類型的對象,要從裏面尋找信息,最直接的想法就是直接經過字符串的 find 方法和切片操做:前端
s = '<p>價格:15.7 元</p>'
start = s.find('價格:')
end = s.find(' 元')
print(s[start+3:end])
# 15.7
這能應付一些極簡單的狀況,但只要稍稍複雜一點,這麼寫就會累死人。更通用的作法是使用正則表達式:html5
import re
s = '<p>價格:15.7 元</p>'
r = re.search('[\d.]+', s)
print(r.group())
# 15.7
正則表達式是處理文本解析的萬金油,什麼狀況均可以應對。但惋惜掌握它須要必定的學習成本,本來咱們有一個網頁提取的問題,用了正則表達式,如今咱們有了兩個問題。python
HTML 文檔自己是結構化的文本,有必定的規則,經過它的結構能夠簡化信息提取。因而,就有了lxml、pyquery、BeautifulSoup等網頁信息提取庫。通常咱們會用這些庫來提取網頁信息。其中,lxml 有很高的解析效率,支持 xPath 語法(一種能夠在 HTML 中查找信息的規則語法);pyquery 得名於 jQuery(知名的前端 js 庫),能夠用相似 jQuery 的語法解析網頁。但咱們今天要說的,是剩下的這個:正則表達式
BeautifulSoup(下文簡稱 bs)翻譯成中文就是「美麗的湯」,這個奇特的名字來源於《愛麗絲夢遊仙境》(這也是爲什麼在其官網會配上奇怪的插圖,以及用《愛麗絲》的片斷做爲測試文本)。編程
bs 最大的特色我以爲是簡單易用,不像正則和 xPath 須要刻意去記住不少特定語法,儘管那樣會效率更高更直接。對大多數 python 使用者來講,好用會比高效更重要。這也是我本身使用並推薦 bs 的主要緣由。工具
接下來介紹點 bs 的基本方法,讓你看完就能用起來。考慮到「只收藏不看黨」的閱讀體驗,先給出一個「嫌長不看版」的總結:性能
推薦使用pip進行安裝(關於 pip 見前文《Crossin:如何安裝 Python 的第三方模塊》):學習
pip install beautifulsoup4
要注意,包名是beautifulsoup4,若是不加上 4,會是老版本也就是 bs3,它是爲了兼容性而存在,目前已不推薦。咱們這裏說 bs,都是指 bs4。測試
bs4 也能夠直接經過安裝 anaconda 得到(介紹見前文《Crossin:Python數據科學環境:Anaconda 瞭解一下》)。
bs 在使用時須要指定一個「解析器」:
這裏的 lxml 和 html5lib 都須要額外安裝,不過若是你用的是 anaconda,都是一併安裝好的。
咱們就用官網上的文檔做例子:
html_doc = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""
使用 bs 的初始化操做,是用文本建立一個 BeautifulSoup 對象,建議手動指定解析器:
from bs4 import BeautifulSoup
soup = BeautifulSoup(html_doc, 'html.parser')
獲取其中的某個結構化元素及其屬性:
soup.title # title 元素
# <title>The Dormouse's story</title>
soup.p # 第一個 p 元素
# <p class="title"><b>The Dormouse's story</b></p>
soup.p['class'] # p 元素的 class 屬性
# ['title']
soup.p.b # p 元素下的 b 元素
# <b>The Dormouse's story</b>
soup.p.parent.name # p 元素的父節點的標籤
# body
並非全部信息均可以簡單地經過結構化獲取,一般使用 find 和 find_all 方法進行查找:
soup.find_all('a') # 全部 a 元素
# [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
# <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
# <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
soup.find(id='link3') # id 爲 link3 的元素
# <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a
輸出:
x = soup.find(class_='story')
x.get_text() # 僅可見文本內容
# 'Once upon a time there were three little sisters; and their names were\nElsie,\nLacie and\nTillie;\nand they lived at the bottom of a well.'
x.prettify() # 元素完整內容
# '<p class="story">\n Once upon a time there were three little sisters; and their names were\n <a class="sister" href="http://example.com/elsie" id="link1">\n Elsie\n </a>\n ,\n <a class="sister" href="http://example.com/lacie" id="link2">\n Lacie\n </a>\n and\n <a class="sister" href="http://example.com/tillie" id="link3">\n Tillie\n </a>\n ;\nand they lived at the bottom of a well.\n</p>\n'
若是你有前端開發經驗,對 CSS 選擇器很熟悉,bs 也爲你提供了相應的方法:
soup.select('html head title')
# [<title>The Dormouse's story</title>]
soup.select('p > #link1')
# [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>]
以上就是 BeautifulSoup 的一個極簡上手介紹,對於 bs 能作什麼,想必你已有了一個初步認識。若是你要在開發中使用,建議再看下它的官方文檔。文檔寫得很清楚,也有中文版,你只要看了最初的一小部分,就能夠在代碼中派上用場了。更多的細節能夠在使用時進一步搜索具體方法和參數設置。
中文版文檔地址:
Beautiful Soup 4.2.0 文檔www.crummy.com對於爬蟲的其餘方面,推薦閱讀咱們以前的相關文章:
════
其餘文章及回答:
學編程:如何自學Python | 新手引導 | 一圖學Python
歡迎搜索及關注:Crossin的編程教室