Heim  >  Artikel  >  Backend-Entwicklung  >  Einführung in Python-Crawler (4) – Detaillierte Erläuterung der HTML-Textanalysebibliothek BeautifulSoup

Einführung in Python-Crawler (4) – Detaillierte Erläuterung der HTML-Textanalysebibliothek BeautifulSoup

零下一度
零下一度Original
2017-05-27 11:55:392103Durchsuche

Beautiful Soup ist eine Bibliothek in Python. Ihre Hauptfunktion besteht darin, Daten von Webseiten abzurufen. Der folgende Artikel führt Sie hauptsächlich in die relevanten Informationen von BeautifulSoup ein, der HTML-Textanalysebibliothek des Python-Crawlers. Die Einführung im Artikel ist sehr detailliert und bietet einen gewissen Referenz- und Lernwert für alle Freunde, die sie benötigen.

Vorwort

Der dritte Artikel in der Python-Crawler-Reihe stellt das Artefakt „Requests“ der Netzwerkanforderungsbibliothek vor Zieldaten: Der von verschiedenen Websites zurückgegebene Inhalt hat normalerweise viele verschiedene Formate, eines davon ist das json-Format. Diese Art von Daten ist für Entwickler am benutzerfreundlichsten. Ein weiteres XML-Format, und das gebräuchlichste Format ist HTML-Dokument. Heute werde ich darüber sprechen, wie man interessante Daten aus HTML extrahiert.

Schreiben Sie Ihren eigenen HTML-Parsing-Analysator. Oder regulären Ausdruck verwenden? Glücklicherweise gibt es in der Python-Community bereits eine sehr ausgereifte Lösung für dieses Problem. Der Schwerpunkt liegt auf HTML-Dokumentoperationen Name von Lewis Carroll Poesie.

BeautifulSoup ist eine Python-Bibliothek zum Parsen von HTML-Dokumenten. Mit BeautifulSoup müssen Sie nur sehr wenig Code verwenden, um interessante Inhalte in HTML zu extrahieren um ein unvollständig formatiertes HTML-Dokument korrekt zu verarbeiten.

BeautifulSoup installieren

pip install beautifulsoup4

BeautifulSoup3 wurde offiziell wegen Wartungsarbeiten eingestellt, Sie müssen die neueste Version BeautifulSoup4 herunterladen.

HTML-Tags

Bevor Sie BeautifulSoup4 lernen, müssen Sie über grundlegende Kenntnisse von HTML-Dokumenten verfügen. Wie im folgenden Code gezeigt, ist HTML erforderlich ist eine Baumorganisationsstruktur.

<html> 
 <head>
  <title>hello, world</title>
 </head>
 <body>
  <h1>BeautifulSoup</h1>
  <p>如何使用BeautifulSoup</p>
 <body>
</html>
  • Es besteht aus vielen Tags (Tag), wie HTML, Head, Titel usw. sind alle Tags

  • A Tag-Paar Bildet einen Knoten, wie zum Beispiel ... Es ist ein Wurzelknoten

  • Es gibt eine bestimmte Beziehung zwischen Knoten, wie zum Beispiel h1 und p sind Nachbarn voneinander, sie sind benachbart Geschwisterknoten

  • h1 ist der direkte untergeordnete Knoten von body oder der untergeordnete Knoten von HTML

  • body ist der übergeordnete Knoten von p ) node, html ist der Vorgängerknoten von p

  • Die zwischen den Tags verschachtelte Zeichenfolge ist ein spezieller untergeordneter Knoten unter dem Knoten, z. B. auch „Hallo, Welt“ Ein Knoten, aber ohne Namen.

Verwenden von BeautifulSoup

Für die Erstellung eines BeautifulSoup-Objekts sind zwei Parameter erforderlich. Der zweite Parameter ist eine Textzeichenfolge und teilt BeautifulSoup mit, welchen Parser zum Parsen des HTML-Codes verwendet werden soll.

Der Parser ist für das Parsen von HTML in verwandte Objekte verantwortlich, während BeautifulSoup für die Verarbeitung von Daten (Hinzufügen, Löschen, Ändern und Abfragen) verantwortlich ist. „html.parser“ ist Pythons integrierter Parser und „lxml“ ist ein Parser, der auf der C-Sprache basiert. Er wird schneller ausgeführt, erfordert jedoch eine zusätzliche Installation

Es kann über das BeautifulSoup-Objekt zu jedem gefunden werden Tag-Knoten in HTML.

from bs4 import BeautifulSoup 
text = """
<html> 
 <head>
  <title >hello, world</title>
 </head>
 <body>
  <h1>BeautifulSoup</h1>
  <p class="bold">如何使用BeautifulSoup</p>
  <p class="big" id="key1"> 第二个p标签</p>
  <a href="http://foofish.net" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >python</a>
 </body>
</html> 
"""
soup = BeautifulSoup(text, "html.parser")

# title 标签
>>> soup.title
<title>hello, world</title>

# p 标签
>>> soup.p
<p class="bold">\u5982\u4f55\u4f7f\u7528BeautifulSoup</p>

# p 标签的内容
>>> soup.p.string
u&#39;\u5982\u4f55\u4f7f\u7528BeautifulSoup&#39;

BeatifulSoup abstrahiert HTML in vier Haupttypen von Datentypen, nämlich Tag, NavigableString, BeautifulSoup und Kommentar. Jeder Tag-Knoten ist ein Tag-Objekt. NavigableString-Objekte sind im Allgemeinen in Tag-Objekte eingeschlossene Zeichenfolgen, die das gesamte HTML-Dokument darstellen. Zum Beispiel:

>>> type(soup)
<class &#39;bs4.BeautifulSoup&#39;>
>>> type(soup.h1)
<class &#39;bs4.element.Tag&#39;>
>>> type(soup.p.string)
<class &#39;bs4.element.NavigableString&#39;>

Tag

Jedes Tag hat einen Namen, der dem HTML-Tag-Namen entspricht.


>>> soup.h1.name
u&#39;h1&#39;
>>> soup.p.name
u&#39;p&#39;

-Tags können auch Attribute haben. Die Zugriffsmethode von Attributen ähnelt der von Wörterbüchern. Sie gibt ein Listenobjekt

>>> soup.p[&#39;class&#39;]
[u&#39;bold&#39;]

zurück NavigableString

Um den Inhalt im Tag abzurufen, können Sie ihn direkt mit .stirng abrufen. Es handelt sich um ein NavigableString-Objekt, in das Sie es explizit konvertieren können eine Unicode-Zeichenfolge.

>>> soup.p.string
u&#39;\u5982\u4f55\u4f7f\u7528BeautifulSoup&#39;
>>> type(soup.p.string)
<class &#39;bs4.element.NavigableString&#39;>
>>> unicode_str = unicode(soup.p.string)
>>> unicode_str
u&#39;\u5982\u4f55\u4f7f\u7528BeautifulSoup&#39;

Nachdem wir die Grundkonzepte vorgestellt haben, können wir nun offiziell mit dem Thema Wie finden wir die Daten, die uns wichtig sind, aus HTML beginnen. BeautifulSoup bietet zwei Methoden, eine ist die Durchquerung und die andere ist die Suche. Normalerweise werden die beiden kombiniert, um die Suchaufgabe abzuschließen.

Durchlaufen Sie den Dokumentbaum

Durchlaufen Sie den Dokumentbaum. Wie der Name schon sagt, beginnt er beim HTML-Tag des Stammknotens und durchläuft ihn Ein Nachteil besteht darin, dass, wenn sich der gesuchte Inhalt am Ende des Dokuments befindet, das gesamte Dokument durchlaufen werden muss, um ihn zu finden, was langsam ist. Daher ist es notwendig, mit der zweiten Methode zusammenzuarbeiten.

Das Abrufen von Tag-Knoten durch Durchlaufen des Dokumentbaums kann direkt über den Tag-Namen erfolgen, zum Beispiel:

Abrufen des Body-Tags:

>>> soup.body
<body>\n<h1>BeautifulSoup</h1>\n<p class="bold">\u5982\u4f55\u4f7f\u7528BeautifulSoup</p>\n</body>

获取 p 标签

>>> soup.body.p
<p class="bold">\u5982\u4f55\u4f7f\u7528BeautifulSoup</p>

获取 p 标签的内容

>>> soup.body.p.string
\u5982\u4f55\u4f7f\u7528BeautifulSoup

前面说了,内容也是一个节点,这里就可以用 .string 的方式得到。遍历文档树的另一个缺点是只能获取到与之匹配的第一个子节点,例如,如果有两个相邻的 p 标签时,第二个标签就没法通过 .p 的方式获取,这是需要借用 next_sibling 属性获取相邻且在后面的节点。此外,还有很多不怎么常用的属性,比如:.contents 获取所有子节点,.parent 获取父节点,更多的参考请查看官方文档。

搜索文档树

搜索文档树是通过指定标签名来搜索元素,另外还可以通过指定标签的属性值来精确定位某个节点元素,最常用的两个方法就是 find 和 find_all。这两个方法在 BeatifulSoup 和 Tag 对象上都可以被调用。

find_all()

find_all( name , attrs , recursive , text , **kwargs )

find_all 的返回值是一个 Tag 组成的列表,方法调用非常灵活,所有的参数都是可选的。

第一个参数 name 是标签节点的名字。

# 找到所有标签名为title的节点
>>> soup.find_all("title")
[<title>hello, world</title>]
>>> soup.find_all("p")
[<p class="bold">\xc8\xe7\xba\xce\xca\xb9\xd3\xc3BeautifulSoup</p>, 
<p class="big"> \xb5\xda\xb6\xfe\xb8\xf6p\xb1\xea\xc7\xa9</p>]

第二个参数是标签的class属性值

# 找到所有class属性为big的p标签
>>> soup.find_all("p", "big")
[<p class="big"> \xb5\xda\xb6\xfe\xb8\xf6p\xb1\xea\xc7\xa9</p>]

等效于

>>> soup.find_all("p", class_="big")
[<p class="big"> \xb5\xda\xb6\xfe\xb8\xf6p\xb1\xea\xc7\xa9</p>]

因为 class 是 Python 关键字,所以这里指定为 class_。

kwargs 是标签的属性名值对,例如:查找有href属性值为 "http://foofish.net" 的标签

>>> soup.find_all(href="foofish.net" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" )
[<a href="foofish.net" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >python</a>]

当然,它还支持正则表达式

>>> import re
>>> soup.find_all(href=re.compile("^http"))
[<a href="http://foofish.net" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >python</a>]

属性除了可以是具体的值、正则表达式之外,它还可以是一个布尔值(True/Flase),表示有属性或者没有该属性。

>>> soup.find_all(id="key1")
[<p class="big" id="key1"> \xb5\xda\xb6\xfe\xb8\xf6p\xb1\xea\xc7\xa9</p>]
>>> soup.find_all(id=True)
[<p class="big" id="key1"> \xb5\xda\xb6\xfe\xb8\xf6p\xb1\xea\xc7\xa9</p>]

遍历和搜索相结合查找,先定位到 body 标签,缩小搜索范围,再从 body 中找 a 标签。

>>> body_tag = soup.body
>>> body_tag.find_all("a")
[<a href="http://foofish.net" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >python</a>]

find()

find 方法跟 find_all 类似,唯一不同的地方是,它返回的单个 Tag 对象而非列表,如果没找到匹配的节点则返回 None。如果匹配多个 Tag,只返回第0个。

>>> body_tag.find("a")
<a href="foofish.net" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >python</a>
>>> body_tag.find("p")
<p class="bold">\xc8\xe7\xba\xce\xca\xb9\xd3\xc3BeautifulSoup</p>

get_text()

获取标签里面内容,除了可以使用 .string 之外,还可以使用 get_text 方法,不同的地方在于前者返回的一个 NavigableString 对象,后者返回的是 unicode 类型的字符串。

>>> p1 = body_tag.find(&#39;p&#39;).get_text()
>>> type(p1)
<type &#39;unicode&#39;>
>>> p1
u&#39;\xc8\xe7\xba\xce\xca\xb9\xd3\xc3BeautifulSoup&#39;

>>> p2 = body_tag.find("p").string
>>> type(p2)
<class &#39;bs4.element.NavigableString&#39;>
>>> p2
u&#39;\xc8\xe7\xba\xce\xca\xb9\xd3\xc3BeautifulSoup&#39;
>>>

实际场景中我们一般使用 get_text 方法获取标签中的内容。

总结

BeatifulSoup 是一个用于操作 HTML 文档的 Python 库,初始化 BeatifulSoup 时,需要指定 HTML 文档字符串和具体的解析器。BeatifulSoup 有3类常用的数据类型,分别是 Tag、NavigableString、和 BeautifulSoup。查找 HTML元素有两种方式,分别是遍历文档树和搜索文档树,通常快速获取数据需要二者结合。

【相关推荐】

1. python爬虫入门(5)--正则表达式实例教程

2. python爬虫入门(3)--利用requests构建知乎API

3. python爬虫入门(2)--HTTP库requests

4.  总结Python的逻辑运算符and

5. python爬虫入门(1)--快速理解HTTP协议

Das obige ist der detaillierte Inhalt vonEinführung in Python-Crawler (4) – Detaillierte Erläuterung der HTML-Textanalysebibliothek BeautifulSoup. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn