table des matières
Description de Beautiful Soup
Beautiful Soup est une bibliothèque Python capable d'extraire des données de fichiers HTML ou XML. Il peut réaliser une navigation de document idiomatique, trouver et modifier le chemin du document via votre convertisseur préféré. BeautifulSoup vous fera gagner des heures voire des jours de travail.
Ce qui précède est tiré du site officiel
Belle installation de soupe
$ easy_install beautifulsoup4
# or
$ pip install beautifulsoup4
Installez l'analyseur
Beautiful Soup prend non seulement en charge l'analyseur HTML dans la bibliothèque standard Python, mais prend également en charge de nombreux analyseurs tiers, tels que lxml
, html5lib
etc. Vous pouvez choisir parmi les trois méthodes suivantes pour installer lxml:
$ apt-get install Python-lxml
$ easy_install lxml
$ pip install lxml
Un autre analyseur alternatif est implémenté en Python pur html5lib
et html5lib
la méthode d'analyse est la même que celle du navigateur. Vous pouvez choisir les méthodes suivantes pour installer html5lib:
$ apt-get install Python-html5lib
$ easy_install html5lib
$ pip install html5lib
Les avantages et les inconvénients de chaque analyseur sont les suivants: Il est
recommandé de l'utiliser lxml
comme analyseur car il est plus efficace. Dans les versions antérieures à Python 2.7.3 et les versions antérieures à 3.2.2 dans Python 3 , vous devez installer lxml
ou html5lib
, car ces versions de Python ont du HTML intégré dans la bibliothèque standard La méthode analytique n'est pas suffisamment stable.
Remarque: si un document HTML ou XML n'est pas au format correct, les résultats renvoyés dans différents analyseurs peuvent être différents, vérifiez
Belle utilisation de la soupe
Beautiful Soup est très simple à utiliser. Passez un document (une chaîne ou un descripteur de fichier) dans la méthode de construction BeautifulSoup pour obtenir un objet document. Après avoir obtenu cet objet, nous pouvons faire quelque chose sur le document. Faites l'opération. La plupart du texte entrant est analysé par des robots d'exploration, de sorte que la combinaison de Beautiful Soup et de la bibliothèque de demandes offre une meilleure expérience.
from bs4 import BeautifulSoup
soup = BeautifulSoup(open("index.html"))
soup = BeautifulSoup("<html>data</html>")
Tout d'abord, le document est converti en Unicode, et toutes les instances de HTML sont converties en encodage Unicode
BeautifulSoup("Sacré bleu!")
<html><head></head><body>Sacré bleu!</body></html>
Ensuite, Beautiful Soup choisit l'analyseur le plus approprié pour analyser ce document.Si vous spécifiez manuellement un analyseur, Beautiful Soup choisira l'analyseur spécifié pour analyser le document.
Type d'objet
Belles documents HTML complexes soupe convertis en une structure arborescente complexe, chaque nœud est des objets Python, tous les objets peuvent être regroupés en quatre types: Tag
, NavigableString
, BeautifulSoup
, Comment
.
Laquelle:
-
La balise est une balise HTML, telle que les balises div, p, h1 ~ h6, etc. C'est aussi l'objet le plus utilisé.
-
NavigableString fait référence au texte à l'intérieur de l'étiquette et la traduction littérale est une chaîne traversable.
-
BeautifulSoup fait référence à l'ensemble du contenu d'un document, qui peut être traité comme une balise.
-
Comment est une NavigableString spéciale dont le contenu de sortie n'inclut pas de contenu de commentaire.
Marque
L'objet Tag est le même que la balise dans le document natif XML ou HTML:
soup = BeautifulSoup('<b class="boldest">Extremely bold</b>')
tag = soup.b
type(tag)
# <class 'bs4.element.Tag'>
Attributs importants dans la balise
Les attributs les plus importants de la balise sont: name
etattributes
Nom
Chaque balise a son propre nom, qui peut .name
être obtenu par:
tag.name
# u'b'
Si la balise est modifiée name
, cela affectera tous les documents HTML générés par l'objet Beautiful Soup actuel:
tag.name = "blockquote"
tag
# <blockquote class="boldest">Extremely bold</blockquote>
Les attributs
Une balise peut avoir plusieurs attributs . tag <b class="boldest">
avec un “class”
attribut, et . tag
la méthode d'opération de l'attribut avec la valeur "boldest" est la même que celle du dictionnaire: tag
l'attribut peut être ajouté, supprimé ou modifié
tag['class']
# u'boldest'
# tag的属性可以被添加,删除或修改
tag['class'] = 'verybold'
tag['id'] = 1
tag
# <blockquote class="verybold" id="1">Extremely bold</blockquote>
del tag['class']
del tag['id']
tag
# <blockquote>Extremely bold</blockquote>
tag['class']
# KeyError: 'class'
print(tag.get('class'))
# None
Vous pouvez également directement "cliquer" pour obtenir les attributs, par exemple: .attrs:
tag.attrs
# {u'class': u'boldest'}
Les chaînes sont souvent contenues dans des balises et .Beautiful Soup
utilisent des NavigableString
classes pour envelopper tag
les chaînes:
tag.string
# u'Extremely bold'
type(tag.string)
# <class 'bs4.element.NavigableString'>
Une NavigableString
chaîne en Python, Unicode
même chaîne, et prend également en charge certaines des fonctionnalités contenues dans l'arborescence des documents et traversant l'arborescence en recherchant des documents. Il unicode()
peut s'agir d'une méthode directement NavigableString
convertie en Unicode
chaîne cible :
unicode_string = unicode(tag.string)
unicode_string
# u'Extremely bold'
type(unicode_string)
# <type 'unicode'>
La chaîne contenue dans la balise ne peut pas être modifiée, mais elle peut être remplacée par d'autres chaînes, en utilisant replace_with()
:
tag.string.replace_with("No longer bold")
tag
# <blockquote>No longer bold</blockquote>
BeautifulSoup
L'objet BeautifulSoup représente tout le contenu d'un document. La plupart du temps, vous pouvez y penser car Tag 对象
il prend en charge la traversée de l'arborescence du document et la recherche de la plupart des méthodes décrites dans l'arborescence du document.
Étant donné que l'objet n'est pas une vraie balise HTML ou XML BeautifulSoup, ce n'est donc pas le cas name
et la attribute
propriété. Mais parfois, afficher ses .name
propriétés est très pratique, donc l'objet BeautifulSoup contient une valeur “[document]”
de propriété spéciale.name
Notes et chaînes spéciales:
Tag
, NavigableString
, BeautifulSoup
couvrant presque tout le contenu du xml et html, mais il y a des objets spéciaux: Comme la section commentaires du document, qui exige des Comment
objets utilisent une sortie de format spécial section commentaires:
markup = "<b><!--这是一段注释--></b>"
soup = BeautifulSoup(markup)
comment = soup.b.string
type(comment)
# <class 'bs4.element.Comment'>
# Comment 对象会使用特殊的格式输出注释部分
comment
# u'这是一段注释'
Parcourez l'arborescence des documents
Définissez d'abord une chaîne de texte HTML et effectuez l'analyse ci-dessous:
html_doc = """
<html><head><title>index</title></head>
<p class="title"><b>商城</b></p>
<p class="story">这是我的第三个商城,欢迎来参观
<a href="http://cityShop.com/elsie" class="city" id="home">home</a>
<a href="http://cityShop.com/lacie" class="city" id="design">design</a>
<a href="http://cityShop.com/tillie" class="city" id="products">products</a>
欢迎来参观.</p>
<p class="welcome">...</p>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html_doc)
Nœud enfant
Une balise peut contenir plusieurs chaînes ou d'autres balises, ce sont les nœuds enfants de cette balise. Beautiful Soup fournit de nombreuses opérations et attributs pour traverser les nœuds enfants.
Remarque: le nœud de chaîne dans Beautiful Soup ne prend pas en charge ces attributs car la chaîne n'a pas de nœuds enfants
Obtenez le nom du tag
Le moyen le plus simple de manipuler l'arborescence du document est de lui indiquer le nom de la balise que vous souhaitez obtenir. Si vous souhaitez obtenir la <head>
balise, utilisez simplement soup.head
:
soup.head
# <head><title>index</title></head>
soup.title
# <title>商城</title>
Vous pouvez tag
appeler cette méthode plusieurs fois dans l'arborescence du document . Par exemple, récupérez <body>
la première balise de la <b>
balise:
soup.body.b
# <b>商城</b>
Seule la première balise du nom actuel peut être obtenue en cliquant sur l'attribut:
soup.a
# <a href="http://cityShop.com/elsie" class="city" id="home">home</a>
Si vous souhaitez obtenir toutes les <a>
balises ou obtenir plus de contenu qu'une balise par nom, vous devez utiliser find_all()
:
soup.find_all('a')
# [<a href="http://cityShop.com/elsie" class="city" id="home">home</a>
# <a href="http://cityShop.com/lacie" class="city" id="design">design</a>
# <a href="http://cityShop.com/tillie" class="city" id="products">products</a>]
.contenu 和 .enfants
L' .contents
attribut tag peut tag
afficher les nœuds enfants dans une liste:
head_tag = soup.head
head_tag
# <head><title>index</title></head>
head_tag.contents
[<title>index</title>]
title_tag = head_tag.contents[0]
title_tag
# <title>index</title>
title_tag.contents
# [u'index']
Les nœuds enfants de la balise .children 生成器,
peuvent tag
être bouclés via:
for child in title_tag.children:
print(child)
# index
.children
Seul le nœud direct de la balise peut être obtenu, mais pas les nœuds descendants ,.descendants
peuvent être satisfaits.
.contents
Et .children
l'attribut de nœud enfant direct contient uniquement une balise, par exemple, <head>
l'étiquette n'est qu'un seul nœud enfant direct <title>
, mais <title>
l'étiquette contient également un sous-nœud: chaîne “index”
, la chaîne dans ce cas “index”
également une <head>
étiquette de nœud descendant. La .descendants
propriété peut toutes tag的子孙节点
être une boucle récursive:
for child in head_tag.descendants:
print(child)
# <title>index</title>
# index
Noeud parent
Chaque balise ou chaîne a un nœud parent: il est contenu dans une balise
.parent
En .parent
acquérant le nœud parent d'un attribut d'élément .title
de la balise parent est head
, html
la balise parent est l'objet BeautifulSoup et l'objet est la balise parent BeautifulSoup None.
title_tag = soup.title
title_tag
# <title>index</title>
title_tag.parent
# <head><title>index</title></head>
# 文档title的字符串也有父节点:<title>标签
title_tag.string.parent
# <title>index</title>
# 文档的顶层节点比如<html>的父节点是 BeautifulSoup 对象:
html_tag = soup.html
type(html_tag.parent)
# <class 'bs4.BeautifulSoup'>
# BeautifulSoup 对象的 .parent 是None:
print(soup.parent)
# None
.Parents
Élément par .parents
tous les nœuds obtenus de manière récursive des attributs d'élément pères, l'exemple suivant utilise la .parents
méthode traverse <a>
tous les nœuds jusqu'à la balise de nœud racine.
link = soup.a
link
# <a href="http://cityShop.com/elsie" class="city" id="home">home</a>
for parent in link.parents:
if parent is None:
print(parent)
else:
print(parent.name)
#结果:
# p
# body
# html
# [document]
# None
Nœud frère
Les
nœuds frères .next_sibling et .previous_sibling sont des éléments frères au même niveau. Dans l'arborescence du document, utilisez l' attribut .next_sibling
et .previous_sibling
pour interroger les nœuds frères:
soup = BeautifulSoup(html_doc, "lxml");
p_tag=soup.p
print(p_tag.next_sibling)
print(p_tag.next_sibling.next_sibling)
# 输出结果
<p class="story">这是我的第三个商城,欢迎来参观
<a href="http://cityShop.com/elsie" class="city" id="home">home</a>
<a href="http://cityShop.com/lacie" class="city" id="design">design</a>
<a href="http://cityShop.com/tillie" class="city" id="products">products</a>
欢迎来参观.</p>
p 的第一个 next_sibling 是p 和 p 之间的换行符。
.next_siblings et .previous_siblings
through .next_siblings
and .previous_siblings
property peuvent être des frères de sortie itérés du nœud actuel:
soup = BeautifulSoup(html_doc, "lxml");
p_tag=soup.p
for p_tag in p_tag.previous_siblings:
print( p_tag)
# 输出结果
<p class="story">这是我的第三个商城,欢迎来参观
<a href="http://cityShop.com/elsie" class="city" id="home">home</a>
<a href="http://cityShop.com/lacie" class="city" id="design">design</a>
<a href="http://cityShop.com/tillie" class="city" id="products">products</a>
欢迎来参观.</p>
# 输出结果
<p class="title"><b>商城</b></p>
En avant et en arrière
Par .next_element
et les .previous_element
objets avant ou après l'obtention d'une balise spécifiée sont analysés, faites attention à cela et les frères et sœurs sont quelque peu différents, le frère fait référence au même nœud père a un nœud enfant, et cela avant ou après un document est conforme à un Calculé dans l'ordre d'analyse.
Par exemple, dans une instance de texte html_doc
, le head
frère est body
(sans égard aux sauts de ligne), car ils ont un parent commun html
, mais head
le nœud suivant l'est title
. C'est soup.head.next_sibling = title soup.head.next_element = title`.
soup = BeautifulSoup(html_doc, "lxml");
head_tag=soup.head
print(head_tag.next_element)
title_tag=soup.title
print(title_tag.next_element)
# 输出结果
<title>index</title>
index
Notez également que l' title
étiquette suivante n'est pas résolue body
, mais title
le contenu de la balise, car html
l'ordre de résolution est l' title
onglet ouvert , puis analyse le contenu, puis fermez title
l'étiquette.
.previous_element
La propriété est juste le .next_element
contraire, elle pointe vers l'objet en cours d'analyse 前一个解析对象
:
last_a_tag.previous_element
# u' and\n'
last_a_tag.previous_element.next_element
# <a href="http://cityShop.com/tillie" class="city" id="products">products</a>
En outre, le même peut .next_elements
et .previous_elements
pour itérer l'arborescence de documents. Les caractères de nouvelle ligne occupent également l'ordre d'analyse, ce qui est cohérent avec l'effet de l'itération des nœuds frères.
for element in last_a_tag.next_elements:
print(repr(element))
# u'Tillie'
# u';\欢迎来参观.'
# u'\n\n'
# <p class="story">...</p>
# u'...'
# u'\n'
# None
Rechercher dans l'arborescence des documents
Beautiful Soup définit de nombreuses méthodes de recherche, dont les plus importantes et les plus couramment utilisées sont: find()
et find_all()
.
Définissez une instance de document:
html_doc = """
<html><head><title>index</title></head>
<p class="title"><b>商城首页</b></p>
<p class="story">这是我的第三个商城,欢迎来参观
<a href="http://cityShop.com/elsie" class="city" id="home">home</a>
<a href="http://cityShop.com/lacie" class="city" id="design">design</a>
<a href="http://cityShop.com/tillie" class="city" id="products">products</a>
欢迎来参观.</p>
<p class="story">...</p>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html_doc)
Utilisez une find_all()
méthode similaire pour rechercher le contenu du document que vous souhaitez rechercher:
soup.find_all('b')
# 结果
# [<b>商城首页</b>]
Si vous transmettez une expression régulière en tant que paramètre, Beautiful Soup match()
correspondra au contenu via l'expression régulière . Dans l'exemple suivant, toutes b
les balises commençant par sont trouvées , ce qui signifie que les balises de <body>
somme <b>
doivent être trouvées:
import re
for tag in soup.find_all(re.compile("^b")):
print(tag.name)
# body
# b
Trouvez toutes les ”t”
balises contenues dans le nom :
for tag in soup.find_all(re.compile("t")):
print(tag.name)
# 结果
# html
# title
Transmettez les paramètres de la liste et Beautiful Soup renverra le contenu qui correspond à n'importe quel élément de la liste. Le code suivant recherche toutes les <a>
balises et <b>
balises du document :
soup.find_all(["a", "b"])
# [<b>商城首页</b>
# <a href="http://cityShop.com/elsie" class="city" id="home">home</a>
# <a href="http://cityShop.com/lacie" class="city" id="design">design</a>
# <a href="http://cityShop.com/tillie" class="city" id="products">products</a>]
Documentation plus détaillée: https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html#