日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

Python中BeautifulSoup模塊詳解_python

作者:小麥的小兜 ? 更新時間: 2022-04-12 編程語言

前言

??? BeautifulSoup是主要以解析web網頁的Python模塊,它會提供一些強大的解釋器,以解析網頁,然后提供一些函數,從頁面中提取所需要的數據,目前是Python爬蟲中最常用的模塊之一。

安裝庫

? ? ? ?在使用前需要安裝庫,這里建議安裝bs4,也就是第四版本,因為根據官方文檔第三版的已經停止更新。同時安裝lxml解釋器

pip3 install bs4

pip3 install lxml

導入庫

from bs4 import BeautifulSoup

解析文檔示例

? ? ? ? 這里以官方文檔進行舉例,我把常用的函數都舉出來,實際開發過程中用到的不多,了解就可以。

# 取自《愛麗絲夢游仙境》的一段
html = """
    <html><head><title>The Dormouse's story</title></head>
    <body>
    <p class="title" name="dromouse"><b>The Dormouse's story</b></p>
    <p class="story">Once upon a time there were three little sisters; and their names were
    <a  class="sister" id="link1"><!--Elsie--></a>,
    <a  class="sister" id="link2">Lacie</a> and
    <a  class="sister" id="link3">Tillite</a>;
    and they lived at the bottom of a well.</p>
    <p class="story">...</p>
"""
 
# 解析文檔,建立一個BeautifulSoup對象,各種函數都是針對此對象展開,此函數會自動編碼為Unicode
 
soup = BeautifulSoup(html,'lxml')

此函數有兩個參數:

1、需要解析的文本,可以使字符串,可以使本地文件

2、解釋器,這里有"lxml", "lxml-xml", "html.parser", or "html5lib",4種,可以解析絕大多數網頁,常用lxml解析??? 這里有一個坑,如果網頁中沒有規定編碼格式,解釋器就不能編碼為Unicode,必須先聲明一下編碼格式,只需要到網頁源碼中查找編碼格式然后做個聲明就可以。一般在網頁中查找charset關鍵字。

# 美化文檔,有些網頁書寫不規范,這個函數會補全標簽,使其看起來更規范
print(soup.prettify())

提取數據示例

????????獲取到文本后,接下來需要提取我們所需的數據,這里用到選擇器 有三種選擇器????????

標簽選擇器(tag選擇器)

標準選擇器

CSS選擇器

1、標簽選擇器(tag選擇器)

# 直接用標簽獲取標題
print("title: ", soup.title)
# 獲取標題文本
print(soup.title.text)
# 獲取p標簽
print(soup.p)
# 獲取head標簽
print(soup.head)
# 獲取a標簽
print(soup.a)

輸出:?

標簽中最重要的倆個屬性:name、attributes

# 使用.name函數獲取標簽名
print('標題標簽的名字: ', soup.title.name)
# tag的屬性用法和字典基本一樣,可以用屬性名取屬性,類似字典的鍵值對,也可以用.attrs取屬性:
print('a標簽中屬性為"href"的值: ', soup.a["href"])
# 會返回一個字典,需要何種屬性可自行提取
print('a標簽的所有屬性: ',soup.a.attrs)
dict1 = soup.a.attrs
# 屬性為class的值
print('屬性為class的值: ', dict1['class'])

輸出:

這里的子孫父兄節點,我感覺用起來忒不順手,可能是我學的不太徹底?,我在這里列出來,大家看看。

# 返回子節點的列表
print("p的子節點: ", soup.p.contents)
# 返回子節點的生成器
print('a的子節點: ', soup.a.children)
# 返回子孫結點的生成器
print("a的子孫結點: ", soup.a.descendants)
# 返回父節點
print("a的父節點: ", soup.a.parent)
# 遞歸父節點
print("a的遞歸父節點: ",soup.a.parents)

輸出:?

?????????上述的標簽選擇器如果遇到相同的標簽名,比如說上述的文檔中就有多個a標簽,這時就沒法選擇相同標簽的第二個標簽,也可能是我沒會操作,如果有發現的歡迎評論。

? ? ? ? 所以需要一個遍歷全文的選擇器來提取數據: find_all( name , attrs , recursive , text , **kwargs ) # 可根據標簽名、屬性、內容查找文檔,此函數配合正則表達式可匹配出各種特定的數據。。。

# 遍歷文檔中所有a標簽
print("文檔中所有a標簽: ", soup.find_all('a'))
a_list = soup.find_all('a')
for i, aList in enumerate(a_list):
    print(i, aList)

輸出:可以提取到文本中所有a標簽的內容,再通過遍歷就可以得到每一個的內容

?根據屬性、文本篩選

# 根據屬性篩選
print(soup.find_all(attrs={'class': 'sister'}))
# 根據文本篩選
print(soup.find_all(text="The Dormouse's story"))

正則表達式篩選

#使用正則表達式找出文本中帶有story字符串的內容
print(soup.find_all(text=re.compile('story')))

還有一個find()方法,用法和findall()類似,不同的是返回的只有一個值,而?findall()返回的是列表。

CSS選擇器

? ? ? ? 目前來說,CSS選擇器是最常用的一種,通過標簽及屬性的層層嵌套可以實現各種特定內容的提取。

# 元素選擇器:選擇p標簽
print('標簽為p:', soup.select("p"))
# 類選擇器:類前加'.'
print("文本中所有class類的標簽: \n", soup.select('.sister'))
# id選擇器:id前加'#'
print("id為link2的標簽: \n", soup.select('#link2'))

輸出:?

# 屬性選擇器:
print("屬性為name的標簽: \n", soup.select("p[name]"))
print("選擇所有屬性中有sister的標簽: \n", soup.select("*[href]"))
print("選擇p標簽的后代第三個a標簽 \n", soup.select("p>a")[2])
print("選擇id=link1后的所有兄弟標簽 \n", soup.select("#link1 ~ .sister"))
print('通過屬性為  \n', soup.select('a[))
print("通過href屬性中以http開頭的所有標簽的查找 \n", soup.select('a[href^="http"]'))
print("通過href屬性中以elsie結尾的所有標簽的查找 \n", soup.select('a[href$="elsie"]'))
print("通過href屬性中包含.com的所有標簽的查找 \n", soup.select("a[href*='.com']"))
# 通過標簽層層查找,這里的:nth-child(2)代表第二個p標簽,a#link2表示a標簽的id為link2的標簽
print("通過標簽層層查找 \n", soup.select("body>p:nth-child(2)>a#link2"))

示例輸出:大家可以自行試試?

?以上的CSS選擇器的常用函數已經講完,通過上面的示例基本上可以拿到web文本中絕大多數數據。下面通過一個小栗子試試水。

實例小項目

需求:爬取某代理網站的免費代理IP地址

第一步:請求數據,獲取數據文本第二步:通過BeautifulSoup分析數據 提取數據第三步:保存數據到本地文本

url = "https://www.89ip.cn/"
header = {"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) "
                       "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36"}
# 請求數據
response = requests.get(url, headers=header)
print(response.status_code)
# 判斷是否請求成功
if response.status_code == 200:
    # 獲取web信息的文本模式
    dataText = response.text
    # 使用lxml解析器解析文本
    soup = BeautifulSoup(dataText, 'lxml')
    # 觀察網頁源碼,獲取需求數據,這里使用CSS選擇器層層嵌套獲得最終的ip信息
    ipText = soup.select('body div>div>div>div>table>tbody>tr>td:nth-child(1)')
    # 遍歷列表獲取每一個ip地址
    for i in range(len(ipText)):
        # 獲取ip的文本信息,get_text()是獲取文本,strip()是去掉兩邊空格
        ip = ipText[i].get_text().strip()
        # 保存到本地
        file = open("ipText.txt", 'a+')
        file.write(ip+"\n")
    # 關閉文件
    file.close()

運行結果:?

總結

? ? ? ? BeautifulSoup模塊主要作用是網頁解析、提取數據,主要有三種提取數據的選擇器,最常用的是CSS選擇器,可以根據層層嵌套的方式獲取所需信息。在這里需要一點HTML和CSS基本知識。

原文鏈接:https://blog.csdn.net/m0_64816081/article/details/122790170

欄目分類
最近更新