目錄
安裝
安裝解析器
美麗湯中的物品
取得標題、標題和連結
处理多值和重复属性
浏览 DOM
仅解析文档的一部分
最终想法
首頁 後端開發 Python教學 Python中使用Beautiful Soup進行網頁抓取:基礎知識探究

Python中使用Beautiful Soup進行網頁抓取:基礎知識探究

Sep 02, 2023 am 10:49 AM

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 class="firstHeading" id="firstHeading" lang="en">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 class="firstHeading, mainHeading">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 属性访问元素的所有祖先。顶级 <html> 标签的父级是 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

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

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

熱門話題

Java教學
1653
14
CakePHP 教程
1413
52
Laravel 教程
1306
25
PHP教程
1251
29
C# 教程
1224
24
Python vs.C:申請和用例 Python vs.C:申請和用例 Apr 12, 2025 am 12:01 AM

Python适合数据科学、Web开发和自动化任务,而C 适用于系统编程、游戏开发和嵌入式系统。Python以简洁和强大的生态系统著称,C 则以高性能和底层控制能力闻名。

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

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

您可以在2小時內學到多少python? 您可以在2小時內學到多少python? Apr 09, 2025 pm 04:33 PM

兩小時內可以學到Python的基礎知識。 1.學習變量和數據類型,2.掌握控制結構如if語句和循環,3.了解函數的定義和使用。這些將幫助你開始編寫簡單的Python程序。

2小時的Python計劃:一種現實的方法 2小時的Python計劃:一種現實的方法 Apr 11, 2025 am 12:04 AM

2小時內可以學會Python的基本編程概念和技能。 1.學習變量和數據類型,2.掌握控制流(條件語句和循環),3.理解函數的定義和使用,4.通過簡單示例和代碼片段快速上手Python編程。

Python與C:學習曲線和易用性 Python與C:學習曲線和易用性 Apr 19, 2025 am 12:20 AM

Python更易學且易用,C 則更強大但複雜。 1.Python語法簡潔,適合初學者,動態類型和自動內存管理使其易用,但可能導致運行時錯誤。 2.C 提供低級控制和高級特性,適合高性能應用,但學習門檻高,需手動管理內存和類型安全。

Python:探索其主要應用程序 Python:探索其主要應用程序 Apr 10, 2025 am 09:41 AM

Python在web開發、數據科學、機器學習、自動化和腳本編寫等領域有廣泛應用。 1)在web開發中,Django和Flask框架簡化了開發過程。 2)數據科學和機器學習領域,NumPy、Pandas、Scikit-learn和TensorFlow庫提供了強大支持。 3)自動化和腳本編寫方面,Python適用於自動化測試和系統管理等任務。

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

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

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

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

See all articles