PythonのBeautifulSoup入門
前幾天寫的股票數據爬取中使用到了BeautifulSoup庫,這個庫的中文文檔已經很完善了,有興趣可以直接去了解(BeautifulSoup4.2 中文文檔)。
我在這裡主要寫的是BeautifulSoup的入門內容,包括BeautifulSoup基本的元素和文檔樹的遍歷,關於BeautifulSoup的安裝,可以直接去看文檔,或者建議使用Jupyter Notebook。
BeautifulSoup將HTML轉成樹形結構,樹的每個節點都是Python的對象。
我們知道HTML是標記類的語言,代碼通過標籤對開始,標籤對結束來實現,而BeautifulSoup就是基於這樣的標籤,來構建一個「標籤樹」,從而可以便利地解析、遍歷、維護「標籤樹」的功能庫。
在BeautifulSoup提供了多種解析器,原理都是通過構建標籤樹來實現對標記類語言的解析、遍歷和維護,只要Python安裝對應的庫就可以使用了。
再來看看BeautifulSoup提供的基本元素,理解這些之後,我們就能用BeautifulSoup來操作HTML的內容啦,這裡的comment是一個特殊的NavigableString對象,只是輸出的部分不包括注釋符號。
接下來我們用代碼來實踐一下:
我們用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 |