天天看點

Beautiful Soup庫 - Python爬蟲(二)

​​Beautiful Soup 4.4.0 中文文檔​​
import requests
from bs4 import BeautifulSoup

url = 'http://python123.io/ws/demo.html'
r = requests.get(url)
demo = r.text
soup = BeautifulSoup(demo, "html.parser")      

1.Beautiful Soup類的基本元素

基本元素 說明
Tag 标簽,最基本的資訊阻止單元, 分别用<>和</>标明開頭和結尾
Name 标簽的名字, <p>…</p>的名字是’p’, 格式:<tag>.name
Attributes 标簽的屬性, 字典形式組織, 格式: <tag>.attrs
NavigableString 标簽内非屬性字元串, <>…</>中字元串, 格式: <tag>.string
Comment 标簽内字元串的注釋部分, 一種特殊的Comment類型
# Tag
# 擷取網頁的标題
print(soup.title)
# <title>This is a python demo page</title>
# 擷取html的a标簽的内容
# 預設擷取第一個标簽
print(soup.a)

# Name
# 擷取标簽的名字
print('标簽名字:', soup.a.name)

# Attributes
# 擷取屬性資訊
tag = soup.a
print(tag.attrs)

# NavigableString
# 擷取a标簽的字元串資訊
print(soup.a.string)

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

print(new_soup.b.string)
# This is a comment
print(type(new_soup.b.string))
# <class 'bs4.element.Comment'>
print(new_soup.p.string)
# This is not a comment
print(type(new_soup.p.string))
# <class 'bs4.element.NavigableString'>      

2.标簽數的下行周遊

屬性 說明
.contents 子節點的清單, 将<tag>所有兒子節點存入清單
.children 子節點的疊代類型, 與.contents類似, 用于循環周遊兒子節點
.descendants 子孫節點的疊代類型, 包含所有子孫節點, 用于循環周遊
import requests
from bs4 import BeautifulSoup

r = requests.get("http://python123.io/ws/demo.html")
demo = r.text
soup = BeautifulSoup(demo, "html.parser")

# 擷取body标簽下的所有節點并存入清單中
print(soup.body.contents)
print(type(soup.body.contents))
# <class 'list'>

# 周遊兒子節點
for child in soup.body.children:
    print(child)

# 周遊子孫節點
for desc in soup.body.descendants:
    print(desc)      

3.标簽樹的上行周遊

屬性 說明
.parent 節點的父親标簽
.parents 節點先輩标簽的疊代類型, 用于循環周遊先輩節點
# 标簽數的上行周遊
# 周遊a标簽的所有父節點
for parent in soup.a.parents:
    if parent is None:
        print(parent)
    else:
        print(parent.name)

# title的父标簽
print(soup.title.parent)      

4.标簽樹的平行周遊

屬性 說明
.next_sibling 傳回按照HTML文本順序的下一個平行節點标簽
.previous_sibling 傳回按照HTML文本順序的上一個平行節點标簽
.next_siblings 疊代類型, 傳回按照HTML文本順序的後續所有平行節點标簽
.previous_siblings 疊代類型, 傳回按照HTML文本順序的前續所有平行節點标簽
# 周遊後續節點
for sibling in soup.a.next_siblings:
  print(sibling)

# 周遊前續節點
for sibling in soup.a.previous_siblings:
  print(sibling)      

總結:

Beautiful Soup庫 - Python爬蟲(二)

5.bs4庫的prettify()方法

對HTML文本或 部分标簽内容進行格式化(每個标簽後面都會加上換行)
import requests
from bs4 import BeautifulSoup

r = requests.get("http://python123.io/ws/demo.html")
demo = r.text
soup = BeautifulSoup(demo, "html.parser")

print(soup.prettify())
print(soup.a.prettify())      

6.查找方法

​find_all(name, attrs, recursive, string, **kwargs)​

​​ :

傳回一個清單類型, 存儲查找的結果.

  • name: 對标簽名稱的檢索字元串
  • attrs : 對标簽屬性值的檢索字元串, 可标注屬性檢索
  • recursive : 是否對子孫全部檢索, 預設True
  • string : <>…</>中字元串區域的檢索字元串
import requests
import re
from bs4 import BeautifulSoup

r = requests.get("http://python123.io/ws/demo.html")
soup = BeautifulSoup(r.text, "html.parser")

# 查找所有a标簽
print(soup.find_all('a'))
print(type(soup.find_all('a')))
# <class 'bs4.element.ResultSet'>

for tag in soup.find_all('a'):
    print(tag.string)
# 顯示a 和 b 标簽
print(soup.find_all(['a', 'b']))

# 顯示soup的所有标簽資訊
for tag in soup.find_all(True):
    print(tag.name)

# 使用正規表達式來查找含有b的标簽
for tag in soup.find_all(re.compile('b')):
    print(tag.name)

# 查找p标簽含有course的内容
print(soup.find_all('p', 'course'))

# 查找id屬性為link1的内容
print(soup.find_all(id='link1'))

# 查找id屬性為link的内容 沒有則傳回[]
print(soup.find_all(id='link'))

# 使用re子產品來查找id屬性包含link的内容
print(soup.find_all(id=re.compile('link')))

# 設定recursive參數為False, 這時從soup的子節點進行檢索, 而不會去檢索子孫節點的内容
print(soup.find_all('a', recursive=False))

# 檢索字元串是否存在
print(soup.find_all(string="Basic Python"))

# 檢索字元串是否含有python, 通過re
print(soup.find_all(string=re.compile('Python')))      

Tip :

<tag>(…)等價于<tag>.find_all(…)

soup(…) 等價于soup.find_all(…)

擴充方法

方法 說明
<>.find() 搜尋且隻傳回一個結果, 字元串類型, 同.find_all()參數
<>.find_parents() 在先輩節點中搜尋, 傳回清單類型, 同.find_all()參數
<>.find_parent() 在先輩節點中傳回一個結果, 字元串類型, 同.find()參數
<>.find_next_siblings() 在後序平行節點中搜尋, 傳回清單類型, 同.find_all()參數
<>.find_next_sibling() 在後序平行節點中傳回一個結果, 字元串類型, 同.find()參數
<>.find_previous_siblings() 在前序平行節點中搜尋, 傳回清單類型, 同.find_all()參數
<>.find_previous_sibling()