搜尋
首頁後端開發Python教學Python中使用Beautiful Soup進行網頁抓取:基礎知識探究

Python中使用Beautiful Soup进行网页抓取:基础知识探究

在先前的教學中,我向您展示如何使用 Requests 模組透過 Python 存取網頁。本教學涵蓋了許多主題,例如發出 GET/POST 請求以及以程式設計方式下載圖像或 PDF 等內容。該教程缺少的一件事是如何抓取您使用請求訪問的網頁以提取所需資訊的指南。

在本教學中,您將了解 Beautiful Soup,它是一個用於從 HTML 檔案中提取資料的 Python 庫。本教程的重點是學習該庫的基礎知識,下一個教程將介紹更高級的主題。請注意,本教學的所有範例均使用 Beautiful Soup 4。

安裝

您可以使用 pip 安裝 Beautiful Soup 4。套件名稱為 beautifulsoup4。它應該適用於 Python 2 和 Python 3。

$ pip install beautifulsoup4

如果您的系統上沒有安裝 pip,您可以直接下載 Beautiful Soup 4 原始碼 tarball 並使用 setup.py 進行安裝。

$ python setup.py install

Beautiful Soup 最初打包為 Python 2 程式碼。當您安裝它以與 Python 3 一起使用時,它會自動更新為 Python 3 程式碼。除非您安裝軟體包,否則代碼不會被轉換。以下是您可能會注意到的一些常見錯誤:

  • 當您在 Python 3 下執行 Python 2 版本的程式碼時,會出現「沒有名為 HTMLParser 的模組」ImportError
  • 當您在 Python 2 下執行 Python 3 版本的程式碼時,會出現「沒有名為 html.parser 的模組」ImportError

上述兩個錯誤都可以透過解除安裝並重新安裝 Beautiful Soup 來修正。

安裝解析器

在討論 Beautiful Soup 可以使用的不同解析器之間的差異之前,讓我們先寫程式碼來建立一個 soup。

from bs4 import BeautifulSoup

soup = BeautifulSoup("<html><p>This is <b>invalid HTML</p></html>", "html.parser")

BeautifulSoup 物件可以接受兩個參數。第一個參數是實際標記,第二個參數是您要使用的解析器。不同的解析器是 html.parser、lxml 和 html5lib。 lxml 解析器有兩個版本:HTML 解析器和 XML 解析器。

html.parser 是一個內建解析器,它在舊版的 Python 中運作得不好。您可以使用以下命令安裝其他解析器:

$ pip install lxml
$ pip install html5lib

lxml 解析器非常快,可用於快速解析給定的 HTML。另一方面,html5lib 解析器非常慢,但也非常寬鬆。以下是使用每個解析器的範例:

soup = BeautifulSoup("<html><p>This is <b>invalid HTML</p></html>", "html.parser")
print(soup)
# <html><p>This is <b>invalid HTML</b></p></html>

soup = BeautifulSoup("<html><p>This is <b>invalid HTML</p></html>", "lxml")
print(soup)
# <html><body><p>This is <b>invalid HTML</b></p></body></html>

soup = BeautifulSoup("<html><p>This is <b>invalid HTML</p></html>", "xml")
print(soup)
# <?xml version="1.0" encoding="utf-8"?>
# <html><p>This is <b>invalid HTML</b></p></html>

soup = BeautifulSoup("<html><p>This is <b>invalid HTML</p></html>", "html5lib")
print(soup)
# <html><head></head><body><p>This is <b>invalid HTML</b></p></body></html>

只有當您解析無效的 HTML 時,上面範例中概述的差異才有意義。然而,網路上的大多數 HTML 都是格式錯誤的,了解這些差異將幫助您除錯一些解析錯誤並決定要在專案中使用哪個解析器。一般來說,lxml 解析器是一個非常好的選擇。

美麗湯中的物品

Beautiful Soup 將給定的 HTML 文件解析為 Python 物件樹。您需要了解四個主要的 Python 物件:TagNavigableStringBeautifulSoupComment

Tag 物件指的是文件中的實際 XML 或 HTML 標記。您可以使用 tag.name 存取標籤的名稱。您也可以將標籤的名稱設定為其他名稱。名稱變更將在 Beautiful Soup 產生的標記中可見。

您可以分別使用 tag['class']tag['id'] 存取不同的屬性,例如標籤的類別和 id。您也可以使用 tag.attrs 存取整個屬性字典。您也可以新增、刪除或修改標籤的屬性。像元素的 class 這樣的屬性可以採用多個值,儲存為列表。

標籤內的文字在 Beautiful Soup 中儲存為 NavigableString。它有一些有用的方法,例如 replace_with("string") 來替換標籤內的文字。您也可以使用 unicode()NavigableString 轉換為 unicode 字串。

美麗湯還允許您訪問網頁中的評論。這些註解儲存為 Comment 對象,該物件基本上也是一個 NavigableString

您已經在上一節中了解了 BeautifulSoup 物件。它用於表示整個文件。由於它不是一個實際的對象,因此它沒有任何名稱或屬性。

取得標題、標題和連結

您可以使用 Beautiful Soup 輕鬆提取頁面標題和其他此類資料。讓我們抓取有關 Python 的維基百科頁面。首先,您必須根據請求模組教學使用以下程式碼取得頁面標記才能存取網頁。

import requests
from bs4 import BeautifulSoup

req = requests.get('https://en.wikipedia.org/wiki/Python_(programming_language)')
soup = BeautifulSoup(req.text, "lxml")

現在您已經建立了湯,您可以使用以下程式碼來取得網頁的標題:

soup.title
# <title>Python (programming language) - Wikipedia</title>

soup.title.name
# 'title'

soup.title.string
# 'Python (programming language) - Wikipedia'

您还可以抓取网页以获取其他信息,例如主标题或第一段、它们的类或 id 属性。

soup.h1
# <h1 id="Python-programming-language">Python (programming language)</h1>

soup.h1.string
# 'Python (programming language)'

soup.h1['class']
# ['firstHeading']

soup.h1['id']
# 'firstHeading'

soup.h1.attrs
# {'class': ['firstHeading'], 'id': 'firstHeading', 'lang': 'en'}

soup.h1['class'] = 'firstHeading, mainHeading'
soup.h1.string.replace_with("Python - Programming Language")
del soup.h1['lang']
del soup.h1['id']

soup.h1
# <h1 id="Python-Programming-Language">Python - Programming Language</h1>

同样,您可以使用以下代码遍历文档中的所有链接或副标题:

for sub_heading in soup.find_all('h2'):
    print(sub_heading.text)
    
# all the sub-headings like Contents, History[edit]...

处理多值和重复属性

HTML 文档中的不同元素使用各种属性来实现不同的目的。例如,您可以将 class 或 id 属性添加到样式、组或标识元素。同样,您可以使用数据属性来存储任何附加信息。并非所有属性都可以接受多个值,但有一些可以。 HTML 规范对这些情况有一套明确的规则,Beautiful Soup 试图遵循所有这些规则。但是,它还允许您指定如何处理多值属性返回的数据。该功能是在4.8版本中添加的,因此在使用之前请确保您已经安装了正确的版本。

默认情况下,像 class 这样可以有多个值的属性将返回一个列表,但像 id 这样的属性将返回单个字符串值。您可以在 BeautifulSoup 构造函数中传递名为 multi_valued_attributes 的参数,并将其值设置为 None。这将确保所有属性返回的值都是字符串。

这是一个例子:

from bs4 import BeautifulSoup

markup = '''
<a class="notice light" id="recent-posts" data-links="1 5 20" href="/recent-posts/">Recent Posts</a>
'''

soup = BeautifulSoup(markup, 'html.parser')
print(soup.a['class'])
print(soup.a['id'])
print(soup.a['data-links'] + "\n")
''' 
Output:
['notice', 'light']
recent-posts
1 5 20
'''


soup = BeautifulSoup(markup, 'html.parser', multi_valued_attributes=None)

print(soup.a['class'])
print(soup.a['id'])
print(soup.a['data-links'] + "\n")
'''
Output:
notice light
recent-posts
1 5 20
'''

无法保证您从不同网站获得的 HTML 始终完全有效。它可能存在许多不同的问题,例如重复的属性。从版本 4.9.1 开始,Beautiful Soup 允许您通过为 on_duplicate_attribute 参数设置值来指定在这种情况下应该执行的操作。不同的解析器以不同的方式处理此问题,您将需要使用内置的 html.parser 来强制执行特定行为。

from bs4 import BeautifulSoup

markup = '''
<a class="notice light" href="/recent-posts/" class="important dark">Recent Posts</a>
'''

soup = BeautifulSoup(markup, 'lxml')
print(soup.a['class'])
# ['notice', 'light']

soup = BeautifulSoup(markup, 'html.parser', on_duplicate_attribute='ignore')
print(soup.a['class'])
# ['notice', 'light']

soup = BeautifulSoup(markup, 'html.parser', on_duplicate_attribute='replace')
print(soup.a['class'])
# ['important', 'dark']

浏览 DOM

您可以使用常规标签名称在 DOM 树中导航。链接这些标签名称可以帮助您更深入地导航树。例如,您可以使用 soup.p.a 获取给定维基百科页面第一段中的第一个链接。第一段中的所有链接都可以使用 soup.p.find_all('a') 访问。

您还可以使用 tag.contents 以列表形式访问标记的所有子级。要获取特定索引处的子项,您可以使用 tag.contents[index]。您还可以使用 .children 属性来迭代标记的子级。

仅当您想要访问标记的直接或第一级后代时,.children.contents 才有用。要获取所有后代,您可以使用 .descendants 属性。

print(soup.p.contents)
# [<b>Python</b>, ' is a widely used ',.....the full list]

print(soup.p.contents[10])
# <a href="/wiki/Readability" title="Readability">readability</a>

for child in soup.p.children:
    print(child.name)
# b
# None
# a
# None
# a
# None
# ... and so on.

您还可以使用 .parent 属性访问元素的父元素。同样,您可以使用 .parents 属性访问元素的所有祖先。顶级 标签的父级是 BeautifulSoup 对象本身,其父级为 None。

print(soup.p.parent.name)
# div

for parent in soup.p.parents:
    print(parent.name)
# div
# div
# div
# body
# html
# [document]

您可以使用 .previous_sibling.next_sibling 属性访问元素的上一个和下一个同级元素。

要使两个元素成为兄弟元素,它们应该具有相同的父元素。这意味着元素的第一个子元素不会有前一个同级元素。类似地,元素的最后一个子元素不会有下一个同级元素。在实际的网页中,元素的上一个和下一个同级元素很可能是换行符。

您还可以使用 .previous_siblings.next_siblings 迭代元素的所有同级元素。

soup.head.next_sibling
# '\n'

soup.p.a.next_sibling
# ' for '

soup.p.a.previous_sibling
# ' is a widely used '

print(soup.p.b.previous_sibling)
# None

您可以使用 .next_element 属性转到紧随当前元素之后的元素。要访问紧邻当前元素之前的元素,请使用 .previous_element 属性。

同样,您可以分别使用 .previous_elements.next_elements 迭代当前元素之前和之后的所有元素。

仅解析文档的一部分

假设您在查找特定内容时需要处理大量数据,并且节省一些处理时间或内存对您来说很重要。在这种情况下,您可以利用 Beautiful Soup 中的 SoupStrainer 类。此类允许您仅关注特定元素,而忽略文档的其余部分。例如,您可以通过在 SoupStrainer 构造函数中传递适当的选择器,使用它来忽略网页上除图像之外的所有其他内容。

请记住,汤过滤器不能与 html5lib 解析器一起使用。但是,您可以将其与 lxml 和内置解析器一起使用。下面是一个示例,我们解析美国的维基百科页面并获取类为 thumbimage 的所有图像。

import requests
from bs4 import BeautifulSoup, SoupStrainer

req = requests.get('https://en.wikipedia.org/wiki/United_States')

thumb_images = SoupStrainer(class_="thumbimage")

soup = BeautifulSoup(req.text, "lxml", parse_only=thumb_images)

for image in soup.find_all("img"):
    print(image['src'])
'''
Output:
//upload.wikimedia.org/wikipedia/commons/thumb/7/7b/Mesa_Verde_National_Park_-_Cliff_Palace.jpg/220px-Mesa_Verde_National_Park_-_Cliff_Palace.jpg
//upload.wikimedia.org/wikipedia/commons/thumb/3/38/Map_of_territorial_growth_1775.svg/260px-Map_of_territorial_growth_1775.svg.png
//upload.wikimedia.org/wikipedia/commons/thumb/f/f9/Declaration_of_Independence_%281819%29%2C_by_John_Trumbull.jpg/220px-Declaration_of_Independence_%281819%29%2C_by_John_Trumbull.jpg
//upload.wikimedia.org/wikipedia/commons/thumb/9/94/U.S._Territorial_Acquisitions.png/310px-U.S._Territorial_Acquisitions.png
...and many more images
'''

您应该注意,我使用 class_ 而不是 class 来获取这些元素,因为 class 是 Python 中的保留关键字。

最终想法

完成本教程后,您现在应该能够很好地理解不同 HTML 解析器之间的主要差异。您现在还应该能够浏览网页并提取重要数据。当您想要分析给定网站上的所有标题或链接时,这会很有帮助。

在本系列的下一部分中,您将学习如何使用 Beautiful Soup 库来搜索和修改 DOM。

以上是Python中使用Beautiful Soup進行網頁抓取:基礎知識探究的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
Python的主要目的:靈活性和易用性Python的主要目的:靈活性和易用性Apr 17, 2025 am 12:14 AM

Python的靈活性體現在多範式支持和動態類型系統,易用性則源於語法簡潔和豐富的標準庫。 1.靈活性:支持面向對象、函數式和過程式編程,動態類型系統提高開發效率。 2.易用性:語法接近自然語言,標準庫涵蓋廣泛功能,簡化開發過程。

Python:多功能編程的力量Python:多功能編程的力量Apr 17, 2025 am 12:09 AM

Python因其簡潔與強大而備受青睞,適用於從初學者到高級開發者的各種需求。其多功能性體現在:1)易學易用,語法簡單;2)豐富的庫和框架,如NumPy、Pandas等;3)跨平台支持,可在多種操作系統上運行;4)適合腳本和自動化任務,提升工作效率。

每天2小時學習Python:實用指南每天2小時學習Python:實用指南Apr 17, 2025 am 12:05 AM

可以,在每天花費兩個小時的時間內學會Python。 1.制定合理的學習計劃,2.選擇合適的學習資源,3.通過實踐鞏固所學知識,這些步驟能幫助你在短時間內掌握Python。

Python與C:開發人員的利弊Python與C:開發人員的利弊Apr 17, 2025 am 12:04 AM

Python適合快速開發和數據處理,而C 適合高性能和底層控制。 1)Python易用,語法簡潔,適用於數據科學和Web開發。 2)C 性能高,控制精確,常用於遊戲和系統編程。

Python:時間投入和學習步伐Python:時間投入和學習步伐Apr 17, 2025 am 12:03 AM

學習Python所需時間因人而異,主要受之前的編程經驗、學習動機、學習資源和方法及學習節奏的影響。設定現實的學習目標並通過實踐項目學習效果最佳。

Python:自動化,腳本和任務管理Python:自動化,腳本和任務管理Apr 16, 2025 am 12:14 AM

Python在自動化、腳本編寫和任務管理中表現出色。 1)自動化:通過標準庫如os、shutil實現文件備份。 2)腳本編寫:使用psutil庫監控系統資源。 3)任務管理:利用schedule庫調度任務。 Python的易用性和豐富庫支持使其在這些領域中成為首選工具。

Python和時間:充分利用您的學習時間Python和時間:充分利用您的學習時間Apr 14, 2025 am 12:02 AM

要在有限的時間內最大化學習Python的效率,可以使用Python的datetime、time和schedule模塊。 1.datetime模塊用於記錄和規劃學習時間。 2.time模塊幫助設置學習和休息時間。 3.schedule模塊自動化安排每週學習任務。

Python:遊戲,Guis等Python:遊戲,Guis等Apr 13, 2025 am 12:14 AM

Python在遊戲和GUI開發中表現出色。 1)遊戲開發使用Pygame,提供繪圖、音頻等功能,適合創建2D遊戲。 2)GUI開發可選擇Tkinter或PyQt,Tkinter簡單易用,PyQt功能豐富,適合專業開發。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
1 個月前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
1 個月前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
1 個月前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它們
1 個月前By尊渡假赌尊渡假赌尊渡假赌

熱工具

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)