Maison > Article > développement back-end > Utiliser Beautiful Soup pour le web scraping en Python : exploration des connaissances de base
Dans un tutoriel précédent, je vous ai montré comment accéder à une page Web via Python à l'aide du module Requêtes. Ce didacticiel couvre des sujets tels que l'exécution de requêtes GET/POST et le téléchargement par programme de contenu tel que des images ou des PDF. Une chose qui manque dans le didacticiel est un guide sur la façon de récupérer la page Web que vous visitez avec la demande d'extraction des informations dont vous avez besoin.
Dans ce tutoriel, vous découvrirez Beautiful Soup, une bibliothèque Python permettant d'extraire des données à partir de fichiers HTML. Ce didacticiel se concentre sur l'apprentissage des bases de la bibliothèque, le prochain didacticiel couvrant des sujets plus avancés. Veuillez noter que tous les exemples de ce didacticiel utilisent Beautiful Soup 4.
Vous pouvez utiliser pip
安装 Beautiful Soup 4。包名称为 beautifulsoup4
. Cela devrait fonctionner sur Python 2 et Python 3.
$ pip install beautifulsoup4
Si pip n'est pas installé sur votre système, vous pouvez directement télécharger l'archive tar du code source de Beautiful Soup 4 et l'installer en utilisant setup.py
.
$ python setup.py install
Beautiful Soup a été initialement emballé sous forme de code Python 2. Lorsque vous l'installez pour l'utiliser avec Python 3, il se met automatiquement à jour vers le code Python 3. Le code ne sera converti que si vous installez le package. Voici quelques erreurs courantes que vous remarquerez peut-être :
ImportError
. ImportError
. Les deux erreurs ci-dessus peuvent être corrigées en désinstallant et en réinstallant Beautiful Soup.
Avant de discuter des différences entre les différents analyseurs que Beautiful Soup peut utiliser, écrivons le code pour créer une soupe.
from bs4 import BeautifulSoup soup = BeautifulSoup("<html><p>This is <b>invalid HTML</p></html>", "html.parser")
BeautifulSoup
对象可以接受两个参数。第一个参数是实际标记,第二个参数是您要使用的解析器。不同的解析器是 html.parser
、lxml 和 html5lib。 lxml
Il existe deux versions de l'analyseur : l'analyseur HTML et l'analyseur XML.
html.parser
est un analyseur intégré qui ne fonctionne pas bien dans les anciennes versions de Python. Vous pouvez installer des analyseurs supplémentaires à l'aide de la commande suivante :
$ pip install lxml $ pip install html5lib
lxml
解析器非常快,可用于快速解析给定的 HTML。另一方面,html5lib
L'analyseur est très lent, mais aussi très indulgent. Voici des exemples utilisant chaque analyseur :
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>
Les différences décrites dans l'exemple ci-dessus n'ont de sens que si vous analysez du HTML non valide. Cependant, la plupart du HTML sur le Web est mal formé, et comprendre ces différences vous aidera à déboguer certaines erreurs d'analyse et à décider quel analyseur utiliser dans votre projet. En général, l'analyseur lxml
est un très bon choix.
Beautiful Soup analyse le document HTML donné dans une arborescence d'objets Python. Il y a quatre objets Python principaux que vous devez connaître : Tag
、NavigableString
、BeautifulSoup
和 Comment
.
Tag
对象指的是文档中的实际 XML 或 HTML 标记。您可以使用 tag.name
Le nom du tag d'accès. Vous pouvez également définir le nom de l'étiquette sur autre chose. Le changement de nom sera visible dans le balisage généré par Beautiful Soup.
Vous pouvez utiliser tag['class']
和 tag['id']
访问不同的属性,例如标签的类和 id。您还可以使用 tag.attrs
访问整个属性字典。您还可以添加、删除或修改标签的属性。像元素的 class
séparément. Ces attributs peuvent prendre plusieurs valeurs, stockées sous forme de liste.
est stocké dans Beautiful Soup sous la forme NavigableString
。它有一些有用的方法,例如 replace_with("string")
来替换标签内的文本。您还可以使用 unicode()
将 NavigableString
converti en chaîne Unicode.
Beautiful Soup vous permet également d'accéder aux commentaires dans les pages Web. Ces annotations sont stockées sous Comment
对象,该对象基本上也是一个 NavigableString
.
Vous avez déjà découvert les BeautifulSoup
objets dans la section précédente. Il est utilisé pour représenter l’ensemble du document. Puisqu’il ne s’agit pas d’un objet réel, il n’a ni nom ni propriétés.
Vous pouvez facilement extraire les titres de pages et autres données similaires à l'aide de Beautiful Soup. Grattons la page Wikipédia sur Python. Tout d’abord, vous devez obtenir la balise de page en utilisant le code suivant selon le didacticiel du module de requêtes pour accéder à la page Web.
import requests from bs4 import BeautifulSoup req = requests.get('https://en.wikipedia.org/wiki/Python_(programming_language)') soup = BeautifulSoup(req.text, "lxml")
Maintenant que vous avez créé votre soupe, vous pouvez récupérer le titre de la page web en utilisant le code suivant :
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 树中导航。链接这些标签名称可以帮助您更深入地导航树。例如,您可以使用 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。
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!