PythonのBeautifulSoup入門

前幾天寫的股票數據爬取中使用到了BeautifulSoup庫,這個庫的中文文檔已經很完善了,有興趣可以直接去了解(BeautifulSoup4.2 中文文檔)。

我在這裡主要寫的是BeautifulSoup的入門內容,包括BeautifulSoup基本的元素文檔樹的遍歷,關於BeautifulSoup的安裝,可以直接去看文檔,或者建議使用Jupyter Notebook。


BeautifulSoup將HTML轉成樹形結構,樹的每個節點都是Python的對象。

我們知道HTML是標記類的語言,代碼通過標籤對開始,標籤對結束來實現,而BeautifulSoup就是基於這樣的標籤,來構建一個「標籤樹」,從而可以便利地解析、遍歷、維護「標籤樹」的功能庫。

html標籤樹

在BeautifulSoup提供了多種解析器,原理都是通過構建標籤樹來實現對標記類語言的解析、遍歷和維護,只要Python安裝對應的庫就可以使用了。

BeautifulSoup提供的解析器

再來看看BeautifulSoup提供的基本元素,理解這些之後,我們就能用BeautifulSoup來操作HTML的內容啦,這裡的comment是一個特殊的NavigableString對象,只是輸出的部分不包括注釋符號。

BeautifulSoup提供的基本元素

接下來我們用代碼來實踐一下:

我們用requests庫將某個網址的html代碼保存到demo中。

import requestsfrom bs4 import BeautifulSoupr = requests.get("http://python123.io/ws/demo.html")demo = r.text

現在demo的值是:

<html><head><title>This is a python demo page</title></head>
<body>
<p class="title"><b>The demo python introduces several python courses.</b></p>
<p class="course">Python is a wonderful general-purpose programming language. You can learn Python from novice to professional by tracking the following courses:
<a href="http://www.icourse163.org/course/BIT-268001" class="py1" id="link1">Basic Python</a> and <a href="http://www.icourse163.org/course/BIT-1001870001" class="py2" id="link2">Advanced Python</a>.</p>
</body></html>

用BeautifulSoup煮一鍋html粥:

soup = BeautifulSoup(demo, "html.parser")

那這鍋粥呢,只要用prettify()這個方法就能列印出HTML的標準格式,現在來測試一下:

print(soup.prettify())

那列印的結果是:

<html> <head> <title> This is a python demo page </title> </head> <body> <p class="title"> <b> The demo python introduces several python courses. </b> </p> <p class="course"> Python is a wonderful general-purpose programming language. You can learn Python from novice to professional by tracking the following courses: <a class="py1" href="http://www.icourse163.org/course/BIT-268001" id="link1"> Basic Python </a> and <a class="py2" href="http://www.icourse163.org/course/BIT-1001870001" id="link2"> Advanced Python </a> . </p> </body></html>

BeautifulSoup操作文檔樹的方法也很簡單,你只要告訴它你目標tag的name,例如,你要獲得<title>的內容,你可以這樣:

soup.title

輸出是:

<title>This is a python demo page</title>

如果要獲得<a>標籤的內容,我們只需要這樣:

soup.a

輸出是:

<a class="py1" href="http://www.icourse163.org/course/BIT-268001" id="link1">Basic Python</a>

在這裡,直接使用.a這個tag,我們只能獲得第一個<a>標籤,如果要獲得所有的<a>標籤,我們需要用soup.find_all(a)這個方法。如果要獲得標籤的內容,我們可以調用string方法,如:

soup.a.string

輸出是:

Basic Python

當然,我們也可以直接調用attrs這個屬性來查看.a的內容,如下:

soup.a.attrs

裡面的值是:

{class: [py1], href: http://www.icourse163.org/course/BIT-268001, id: link1}

所以我們可以看到attrs是一個字典,那麼我們就可以用字典的方法,直接用key值來獲得對應的value,如獲得href的值:

tag.attrs[href]

那麼輸出結果會是:

http://www.icourse163.org/course/BIT-268001

這部分值得注意的是comment元素的使用,如果要列印的是標籤對內的注釋,那麼輸出的內容會去掉注釋符號,來舉個栗子:

先煮一鍋新的湯,裡面有兩個string,<b>標籤的是被注釋的string,<p>標籤的是一般的string:

newSoup = BeautifulSoup("<b><!-- This is a comment--></b><p>This is not a comment</p>", html.parser)

直接列印<b>和<p>標籤的內容:

newSoup.b.stringnewSoup.p.string

我們會發現輸出的結果都是一樣的:

This is a comment

所以,要分清哪些是注釋,哪些是內容的話,我們可以在輸出前對tag的type進行判斷。


接下來講講BeautifulSoup中HTML內容的基本遍歷方法:

我們先來看HTML標籤樹及其基本的遍歷方法,其中包括:下行遍歷上行遍歷平行遍歷,我們可以從下圖中理解三種遍歷的基本思想。

我們先來看看下行遍歷的基本元屬性,其中.contents和.children只獲得當前節點的下一層節點的信息,而.descendants可以獲得一個節點後續的所有節點的信息。

我們還是用上面的那個soup,現在用代碼來實踐一下:

soup.head

輸出結果是:

<head><title>This is a python demo page</title></head>

再來看看<head>標籤的子節點內容:

soup.head.contents

輸出結果是:

[<title>This is a python demo page</title>]

我們會發現返回結果被保存到了一個列表裡,而.children和.descendants用於遍歷則不會保存到列表中,請多加註意,所以,我們可以用for in來循環其中的值,如:

for i in soup.head.descendants: print(i)

輸出是:

<title>This is a python demo page</title>This is a python demo page

我們可以發現字元內容也被當做一個子節點。

接下來我們講講上行遍歷,上行遍歷包括以下的屬性,其基本的內容和上行遍歷一致:

我們可以用以下代碼進行簡單的測試:

for parent in soup.a.parents: if parent is None: print(parent) else: print(parent.name)

輸出結果是:

pbodyhtml[document]

這裡值得注意的是,當遍歷到最上層的parent,而這個parent本身沒有parent,這時候則要進行一個判斷:parent是否為空。

最後來看看平行遍歷:

其基本的使用與上行下行思想基本一致,但值得注意的是,平行遍歷是要求在同一個父節點的各個節點之間的遍歷。

這裡主要展示用for in來遍歷後續節點,如下:

for sibling in soup.a.next_siblings: print(sibling)

輸出結果是:

and <a class="py2" href="http://www.icourse163.org/course/BIT-1001870001" id="link2">Advanced Python</a>.

這裡我們知道,平行遍歷的節點也可能是string。


好啦,以上就是BeautifulSoup的基本內容啦,當然還包括搜索文檔樹等的方法沒介紹,等之後有空再補上啦。

參考內容:北京理工大學,Python網路爬蟲與信息提取,蒿天


推薦閱讀:

python用select 找到需要標籤後,無法使用.get_text()?
python 3.5 使用 BeautifulSoup 解析中文網頁的中文全是亂碼?

TAG:Python | 爬蟲計算機網路 | beautifulsoup |