Python爬蟲入門——Beautiful Soup庫的使用

1. 概念

  Beautiful Soup是一個可以從HTML或XML文件中提取數據(解析)的Python庫,簡單來說,它能將HTML的標籤文件解析成樹形結構,然後方便地獲取到指定標籤的對應屬性。
  HTML文檔,是由一組尖括號構成的標籤組織起來的,每對尖括號形成了一對標籤,而標籤之間存在上下級關係,形成了一個標籤樹。

<html>
    <body>
    	<p class="title"...</p>
    </body>
</html>

  Beautiful Soup庫是解析、遍歷、維護“標籤樹‘的功能庫。

2. 標籤的具體形式

  這裏的話,建議猿友們去了解下HTML格式,不需要了解多深,大概能看懂組織形式即可。舉例:P標籤
在這裏插入圖片描述

3. Beautiful Soup 對象初始化

安裝bs4庫:

pip install beautifulsoup4

導入Beautiful Soup 庫

from bs4 import BeautifulSoup 

  將一段文檔(HTML文檔)傳入 BeautifulSoup 的構造方法(最後一行代碼),就能得到一個文檔對象soup。如下代碼所示,文檔通過請求url獲取:

import requests
from bs4 import BeautifulSoup      #BeautifulSoup是一個類
r=requests.get("http://python123.io/ws/demo.html")
r.raise_for_status()
r.encoding=r.apparent_encoding
demo=r.text

soup=BeautifulSoup(demo,"html.parser")    #兩個參數,第一個是要解析的文檔對象,第二個是“html的解析器”

Beautiful Soup庫解析器

解析器 使用方法 條件
bs4的HTML解析器 BeautifulSoup(mk,'html.parser') 安裝bs4庫
lxml的HTML解析器 BeautifulSoup(mk,'lxml') pip install lxml
lxml的XML解析器 BeautifulSoup(mk,'xml') pip install lxml
html5lib的解析器 BeautifulSoup(mk,'html5lib') pip install html5lib

4. Beautiful Soup類的基本元素

基本元素 說明
Tag 標籤,最基本的信息組織單元,分別用<>和</>標明開頭和結尾
Name 標籤的名字,< p>…</ p>的名字是‘p’,格式:< tag>.name
Attributes 標籤的屬性,字典形式組織,格式:< tag>.attrs
NaviableString 標籤內非屬性字符串,<>…</>中字符串,格式:< tag>.string
Comment 標籤內字符串的註釋部分,一種特殊的Comment類型

這裏先給出一個標籤樹的代碼:

import requests
from bs4 import BeautifulSoup     
r=requests.get("http://python123.io/ws/demo.html")
r.encoding=r.apparent_encoding
demo=r.text
soup=BeautifulSoup(demo,"html.parser")   
print(soup.prettify())    #重新排版,增強可讀性,運行結果就是HTML文檔的標籤樹形式

運行結果是一個標籤樹(如下,也可以說是HTML文檔的一種清晰的表現形式),下面的所有實例都用這個標籤樹實現。

<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>

對於每個基本元素,都用幾個典型的實例來講解,加深印象。(注意和上邊的標籤樹比對着看,這樣纔有效果~~)多看註釋,註釋裏面講解了比較重要的點。

  • 標籤、標籤的名字——Tag、Name
>>> import requests
>>> from bs4 import BeautifulSoup
>>> r=requests.get("http://python123.io/ws/demo.html")
>>> r.encoding=r.apparent_encoding
>>> demo=r.text
>>> soup=BeautifulSoup(demo,"html.parser")
>>> soup.title  #頁面的標題
<title>This is a python demo page</title>
>>> soup.a      #實際上我們知道a標籤有兩個,這樣寫,默認打印第一個出現的a標籤。
<a class="py1" href="http://www.icourse163.org/course/BIT-268001" id="link1">Basic Python</a>
>>> soup.a.name   #a標籤的名字
'a'
>>> soup.a.parent.name   #a標籤父親標籤的名字,也就是包含a標籤的上一層標籤
'p'
>>> soup.a.parent.parent.name  #a標籤爺爺標籤的名字
'body'
  • 標籤的屬性——Attributes
>>> tag=soup.a
>>> tag.attrs      #a標籤的屬性,返回的是字典類型
{'href': 'http://www.icourse163.org/course/BIT-268001', 'class': ['py1'], 'id': 'link1'}
>>> tag.attrs['class']  #a標籤的屬性中,class所對應的值,列表類型
['py1']
>>> tag.attrs['href']   #a標籤的屬性中,href所對應的值
'http://www.icourse163.org/course/BIT-268001'
>>> type(tag.attrs)      #a標籤屬性的類型,是字典
<class 'dict'>
>>> type(tag)   #a標籤的標籤類型
<class 'bs4.element.Tag'>
  • 標籤內非屬性的字符串——NaviableString
>>> soup.a
<a class="py1" href="http://www.icourse163.org/course/BIT-268001" id="link1">Basic Python</a>
>>> soup.a.string
'Basic Python'
>>> soup.p
<p class="title"><b>The demo python introduces several python courses.</b></p>
>>> soup.p.string    #p標籤中實際還包含了b標籤,但打印的卻並不包含b標籤。說明NavigableString是可以跨越多個標籤層次的
'The demo python introduces several python courses.'
>>> type(soup.p.string)
<class 'bs4.element.NavigableString'>  #bs4庫定義的類型
  • 標籤內字符串的註釋部分——Comment
    在HTML頁面表達中, '<! ’ 表示一個註釋的開始。
>>> newsoup=BeautifulSoup("<b><!--This is a comment--></b><p>This is not a comment</p>","html.parser")
>>> newsoup.b.string    #註釋和字符串都可以用.string來打印
'This is a comment'
>>> type(newsoup.b.string)
<class 'bs4.element.Comment'>
>>> newsoup.p.string   #有的時候我們需要對標籤內字符串進行類型判斷,因爲他可能是註釋
'This is not a comment'   
>>> type(newsoup.p.string)
<class 'bs4.element.NavigableString'>  #bs4庫定義的類型

在這裏插入圖片描述

5. Beautiful Soup HTML遍歷方法

將上面的HTML標籤樹進行簡化,把他變成更像樹的樣子。,如下(並不完整,只是一個例子,爲了理解而已):
在這裏插入圖片描述
由於Beautiful Soup庫是對標籤樹功能遍歷的集合,遍歷可以分爲上行遍歷、下行遍歷、平行遍歷。下面分別介紹一下。
在這裏插入圖片描述

  • 標籤樹的下行遍歷
屬性 說明
.contents 子節點的列表,將< tag>所有兒子結點存入列表
.children 子節點的迭代類型,與.contents類似,用於循環遍歷兒子結點
.descendants 子孫結點的迭代類型,包含所有子孫結點,用於循環遍歷

代碼實例:

>>> soup.head   #head標籤
<head><title>This is a python demo page</title></head>
>>> soup.head.contents
[<title>This is a python demo page</title>]
>>> soup.body.contents  #對一個標籤的兒子節點,並不僅僅包括標籤節點,也包括字符串節點。比如像’\n‘
['\n', <p class="title"><b>The demo python introduces several python courses.</b></p>, '\n', <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>, '\n']
>>> len(soup.body.contents)
5
>>> soup.body.contents[1]
<p class="title"><b>The demo python introduces several python courses.</b></p>
#遍歷兒子節點
for child in soup.body.children:
	print(child)
#遍歷子孫節點
for child in soup.body.descendants:
	print(child)

  • 標籤樹的上行遍歷
屬性 說明
.parent 子節點的父親標籤
.parents 節點先輩標籤的迭代類型,用於循環遍歷先輩節點

代碼實例:

>>> soup.title.parent
<head><title>This is a python demo page</title></head>
>>> soup.html.parent   #因爲html標籤是根節點,所以他的父親節點是他自己
<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>
>>> soup.parent  #soup的父親爲None
  • 標籤樹的平行遍歷
屬性 說明
.next_silbling 返回按照HTML文本順序的下一個平行節點
.previous_silbling 返回按照HTML文本順序的上一個平行節點
.next_silblings 迭代類型,返回按照HTML文本順序的後續所有平行節點
.previous_silblings 迭代類型,返回按照HTML文本順序的前續所有平行節點

代碼實例:

>>> soup.a.next_sibling  #平行遍歷發生在同一父節點下的各節點之間。標籤之間的NavigableString也構成標籤樹平行的節點。
' and '
>>> soup.a.next_sibling.next_sibling
<a class="py2" href="http://www.icourse163.org/course/BIT-1001870001" id="link2">Advanced Python</a>
>>> soup.a.previous_sibling
'Python is a wonderful general-purpose programming language. You can learn Python from novice to professional by tracking the following courses:\r\n'
>>> soup.a.previous_sibling.previous_sibling   #爲空
>>> soup.a.parent
<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>
#遍歷後續節點
for sibling in soup.a.next_siblings:
	print(sibling)
#遍歷前續節點
for sibling in soup.a.previous_siblings:
	print(sibling)

6. 基於bs4庫的HTML格式化

  這裏主要介紹,bs4庫的prettify()方法。你可以認爲這個方法是讓輸出顯得更加有條理,更容易被程序識別。你可以試試,使用prettify()方法和不使用prettify()方法的區別,一看便知。最後一句便是方法的實現。

import requests
from bs4 import BeautifulSoup     
r=requests.get("http://python123.io/ws/demo.html")
r.encoding=r.apparent_encoding
demo=r.text
soup=BeautifulSoup(demo,"html.parser")   
print(soup.prettify())    #重新排版,增強可讀性,運行結果就是HTML文檔的標籤樹形式

7. 總結

  文章總結了Beautiful Soup庫的一些基本使用方法。對於做一些簡單的HTML解析已經足夠用了。是非常好的爬蟲入門~
  如果說有什麼建議的話,就是實踐!一點點的敲,一點點的試,當你敲完所有代碼的時候,你就會發現,東西已經在你的腦子裏了~~
  本寶才疏學淺,文章如有不當之處,還請多多指教~~ (●′ω`●)

發佈了15 篇原創文章 · 獲贊 36 · 訪問量 6621
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章