Python-Web-Scraping - BeautifulSoup
Python-Web-Scraping bezeichnet den Prozess des automatischen Extrahierens von Informationen aus dem Internet durch das Schreiben von Python-Programmen.
Der grundlegende Web-Scraping-Prozess umfasst normalerweise das Senden von HTTP-Anfragen zum Abrufen von Webseiteninhalten, das Parsen der Webseiten, das Extrahieren von Daten und anschließend das Speichern der Daten.
Pythons reichhaltiges Ökosystem macht es zu einer beliebten Sprache für die Entwicklung von Web-Scrapern, insbesondere wegen seiner leistungsstarken Bibliotheksunterstützung.
Im Allgemeinen kann der Web-Scraping-Prozess in die folgenden Schritte unterteilt werden:
- HTTP-Anfragen senden: Der Scraper ruft HTML-Seiten von der Zielwebsite über HTTP-Anfragen ab. Zu den häufig verwendeten Bibliotheken gehören
requests。 - HTML-Inhalt parsen: Nachdem die HTML-Seite abgerufen wurde, muss der Scraper den Inhalt parsen und Daten extrahieren. Gängige Bibliotheken sind unter anderem
BeautifulSoup、lxml、Scrapy, usw. - Daten extrahieren: Extrahieren Sie die erforderlichen Daten, indem Sie HTML-Elemente lokalisieren (wie Tags, Attribute, Klassennamen usw.).
- Daten speichern: Speichern Sie die extrahierten Daten in Formaten wie Datenbanken, CSV-Dateien und JSON-Dateien zur späteren Verwendung oder Analyse.
Dieses Kapitel stellt hauptsächlich BeautifulSoup vor, eine Python-Bibliothek zum Parsen von HTML- und XML-Dokumenten. Sie kann Daten aus Webseiten extrahieren und wird häufig für Web Scraping und Data Mining verwendet.

BeautifulSoup
BeautifulSoup ist eine Python-Bibliothek zum Extrahieren von Daten aus Webseiten, besonders geeignet zum Parsen von HTML- und XML-Dateien.
BeautifulSoup kann Webseiteninhalte extrahieren und manipulieren, indem es eine einfache API bereitstellt, was es sehr geeignet für Web-Scraping- und Datenextraktionsaufgaben macht.
BeautifulSoup installieren
Um BeautifulSoup zu verwenden, müssen Sie beautifulsoup4 und lxml oder html.parser (einen HTML-Parser) installieren.
Wir können pip verwenden, um diese Abhängigkeiten zu installieren:
pip install beautifulsoup4 pip install lxml # 推荐使用 lxml 作为解析器(速度更快)
Wenn Sie lxml nicht haben, können Sie den in Python integrierten html.parser als Parser verwenden.
Grundlegende Verwendung
BeautifulSoup wird zum Parsen von HTML- oder XML-Daten verwendet und bietet Methoden zum Navigieren, Suchen und Ändern des Parse-Baums.
Zu den gängigen BeautifulSoup-Operationen gehören das Finden von Tags, das Abrufen von Tag-Attributen, das Extrahieren von Text usw.
Um BeautifulSoup zu verwenden, müssen Sie zuerst BeautifulSoup importieren und die HTML-Seite in ein BeautifulSoup-Objekt laden.
Normalerweise verwenden Sie zuerst eine Web-Scraping-Bibliothek (wierequests), um den Webseiteninhalt abzurufen:
Beispiel
import requests
# Verwenden Sie requests, um den Webseiteninhalt abzurufen
url = 'https://cn.bing.com/' # Den Webseiteninhalt der Bing-Suchmaschine scrapen
response = requests.get(url)
# Verwenden Sie BeautifulSoup, um die Webseite zu parsen
soup = BeautifulSoup(response.text, 'lxml') # Verwenden Sie den lxml-Parser
# Parsen Sie den Webseiteninhalt mit dem html.parser-Parser
# soup = BeautifulSoup(response.text, 'html.parser')
Webseitentitel abrufen:
Beispiel
import requests
# Geben Sie die Website an, deren Titel Sie abrufen möchten
url = 'https://cn.bing.com/' # Den Webseiteninhalt der Bing-Suchmaschine scrapen
# Senden Sie eine HTTP-Anfrage, um den Inhalt der Webseite abzurufen
response = requests.get(url)
# Problem mit chinesischem Zeichensalat
response.encoding = 'utf-8'
# Stellen Sie sicher, dass die Anfrage erfolgreich war
if response.status_code == 200:
# Verwenden Sie BeautifulSoup, um den Inhalt der Webseite zu parsen
soup = BeautifulSoup(response.text, 'lxml')
# Finden Sie das <title>-Tag
title_tag = soup.find('title')
# Geben Sie den Titeltext aus
if title_tag:
print(title_tag.get_text())
else:
print("Das <title>-Tag wurde nicht gefunden")
else:
print("Anfrage fehlgeschlagen, Statuscode:", response.status_code)
Nach Ausführen des obigen Codes lautet der ausgegebene Titel:
搜索 - Microsoft 必应
Problem mit chinesischem Zeichensalat
Bei der Verwendung der requests-Bibliothek zum Scrapen chinesischer Webseiten können Kodierungsprobleme auftreten, wodurch chinesische Inhalte nicht korrekt angezeigt werden. Um sicherzustellen, dass chinesische Webseiten korrekt gescrapt und angezeigt werden, müssen Sie sich normalerweise um die Zeichenkodierung der Webseite kümmern.
Automatische Kodierungserkennung: requests leitet die Kodierung der Webseite normalerweise automatisch aus dem Content-Type in den Antwort-Headern ab, aber dies kann manchmal ungenau sein. In solchen Fällen können Sie chardet verwenden, um die Kodierung automatisch zu erkennen.
Beispiel
url = 'https://cn.bing.com/'
response = requests.get(url)
# Verwende chardet, um die Kodierung automatisch zu erkennen
import chardet
encoding = chardet.detect(response.content)['encoding']
print(encoding)
response.encoding = encoding
Nach dem Ausführen des obigen Codes lautet die Ausgabe:
utf-8
Wenn Sie die Kodierung der Webseite kennen (z. B. utf-8 oder gbk), können Sie direktresponse.encoding festlegen:
response.encoding = 'utf-8' # 或者 'gbk',根据实际情况选择
Tags finden
BeautifulSoup bietet mehrere Methoden zum Finden von Tags in einer Webseite. Zu den am häufigsten verwendeten gehörenfind()undfind_all()。
find()Gibt das erste passende Tag zurückfind_all()Gibt alle passenden Tags zurück
Beispiel
import requests
# Geben Sie die Website an, deren Titel Sie abrufen möchten
url = 'https://www.baidu.com/' # Scrape den Webseiteninhalt der Bing-Suchmaschine
# Senden Sie eine HTTP-Anfrage, um den Inhalt der Webseite abzurufen
response = requests.get(url)
# Problem mit chinesischem Zeichensalat
response.encoding = 'utf-8'
soup = BeautifulSoup(response.text, 'lxml')
# Finde das erste <a>-Tag
first_link = soup.find('a')
print(first_link)
print("----------------------------")
# Hole das href-Attribut des ersten <a>-Tags
first_link_url = first_link.get('href')
print(first_link_url)
print("----------------------------")
# Alle <a>-Tags finden
all_links = soup.find_all('a')
print(all_links)
Das Ausgabeergebnis ist ähnlich wie das folgende:
<a class="mnav" href="http://news.baidu.com" name="tj_trnews">新闻</a> ---------------------------- http://news.baidu.com ---------------------------- [<a class="mnav" href="http://news.baidu.com" name="tj_trnews">新闻</a>, <a class="mnav" href="https://www.hao123.com" name="tj_trhao123">hao123</a>, <a class="mnav" href="http://map.baidu.com" name="tj_trmap">地图</a>, <a class="mnav" href="http://v.baidu.com" name="tj_trvideo">视频</a>,
Tag-Text abrufen
Mit derget_text()-Methode können Sie den Textinhalt innerhalb eines Tags extrahieren:
Beispiel
import requests
# Geben Sie die Website an, deren Titel Sie abrufen möchten
url = 'https://www.baidu.com/' # Scrape den Webseiteninhalt der Bing-Suchmaschine
# Senden Sie eine HTTP-Anfrage, um den Inhalt der Webseite abzurufen
response = requests.get(url)
# Problem mit chinesischem Zeichensalat
response.encoding = 'utf-8'
soup = BeautifulSoup(response.text, 'lxml')
# Den Textinhalt des ersten <p>-Tags abrufen
paragraph_text = soup.find('p').get_text()
# Den gesamten Textinhalt auf der Seite abrufen
all_text = soup.get_text()
print(all_text)
Das Ausgabeergebnis ist ähnlich wie das folgende:
Baidu it, and you'll know.
Untergeordnete und übergeordnete Tags finden
Sie können dieparent- undchildren-Eigenschaften verwenden, um auf die übergeordneten und untergeordneten Tags eines Tags zuzugreifen:# 获取当前标签的父标签 parent_tag = first_link.parent # 获取当前标签的所有子标签 children = first_link.children
Beispiel
import requests
# Geben Sie die Website an, deren Titel Sie abrufen möchten
url = 'https://www.baidu.com/' # Scrape den Webseiteninhalt der Bing-Suchmaschine
# Senden Sie eine HTTP-Anfrage, um den Inhalt der Webseite abzurufen
response = requests.get(url)
# Problem mit chinesischem Zeichensalat
response.encoding = 'utf-8'
soup = BeautifulSoup(response.text, 'lxml')
# Finde das erste <a>-Tag
first_link = soup.find('a')
print(first_link)
print("----------------------------")
# Eltern-Tag des aktuellen Tags abrufen
parent_tag = first_link.parent
print(parent_tag.get_text())
Das Ausgabeergebnis ist ähnlich wie das folgende:
<a class="mnav" href="http://news.baidu.com" name="tj_trnews">新闻</a> ---------------------------- 新闻 hao123 地图 视频 贴吧 登录 更多产品
Tags mit bestimmten Attributen finden
Sie können Tags mit bestimmten Attributen finden, indem Sie Attributparameter übergeben.
Zum Beispiel alle div-Tags mit dem Klassennamen example-class finden:
# 查找所有 class="example-class" 的 <div> 标签
divs_with_class = soup.find_all('div', class_='example-class')
# 查找具有 id="unique-id" 的 <p> 标签
unique_paragraph = soup.find('p', id='unique-id')
Rufen Sie den Such-Button mit der id su ab:

Beispiel
import requests
# Geben Sie die Website an, deren Titel Sie abrufen möchten
url = 'https://www.baidu.com/' # Scrape den Webseiteninhalt der Bing-Suchmaschine
# Senden Sie eine HTTP-Anfrage, um den Inhalt der Webseite abzurufen
response = requests.get(url)
# Problem mit chinesischem Zeichensalat
response.encoding = 'utf-8'
soup = BeautifulSoup(response.text, 'lxml')
# Finde das <input>-Tag mit id="unique-id"
unique_input = soup.find('input', id='su')
input_value = unique_input['value'] # Wert des Eingabefelds abrufen
print(input_value)
Das Ausgabeergebnis ist:
Baidu it.
Erweiterte Nutzung
CSS-Selektoren
BeautifulSoup unterstützt auch das Finden von Tags mithilfe von CSS-Selektoren.
Die select()-Methode ermöglicht es Ihnen, eine jQuery-ähnliche Selektor-Syntax zu verwenden, um Tags zu finden:
# 使用 CSS 选择器查找所有 class 为 'example' 的 <div> 标签
example_divs = soup.select('div.example')
# 查找所有 <a> 标签中的 href 属性
links = soup.select('a[href]')
Umgang mit verschachtelten Tags
BeautifulSoup unterstützt tief verschachtelte HTML-Strukturen. Sie können diese Strukturen verarbeiten, indem Sie rekursiv untergeordnete Tags finden:
# 查找嵌套的 <div> 标签
nested_divs = soup.find_all('div', class_='nested')
for div in nested_divs:
print(div.get_text())
Ändern von Webseiteninhalten
BeautifulSoup ermöglicht es Ihnen, HTML-Inhalte zu ändern.
Wir können Tag-Attribute, Text ändern oder Tags löschen:
Beispiel
first_link['href'] = 'http://new-url.com'
# Den Textinhalt des ersten <p>-Tags ändern
first_paragraph = soup.find('p')
first_paragraph.string = 'Updated content'
# Einen Tag löschen
first_paragraph.decompose()
Umwandlung in einen String
Das geparste BeautifulSoup-Objekt kann wieder in einen HTML-String umgewandelt werden:
# 转换为字符串 html_str = str(soup)
BeautifulSoup-Attribute und -Methoden
Im Folgenden sind häufig verwendete Attribute und Methoden in BeautifulSoup aufgeführt:
| Methode/Attribut | Beschreibung | Beispiel |
|---|---|---|
BeautifulSoup() | Wird verwendet, um HTML- oder XML-Dokumente zu parsen und ein BeautifulSoup-Objekt zurückzugeben. | soup = BeautifulSoup(html_doc, 'html.parser') |
.prettify() | Formatiert und verschönert den Dokumentinhalt und erzeugt einen strukturierten String. | print(soup.prettify()) |
.find() | Findet das erste passende Tag. | tag = soup.find('a') |
.find_all() | Findet alle passenden Tags und gibt eine Liste zurück. | tags = soup.find_all('a') |
.find_all_next() | Findet alle Tags, die nach dem aktuellen Tag liegen und die Bedingungen erfüllen. | tags = soup.find('div').find_all_next('p') |
.find_all_previous() | Findet alle Tags, die vor dem aktuellen Tag liegen und die Bedingungen erfüllen. | tags = soup.find('div').find_all_previous('p') |
.find_parent() | Gibt das übergeordnete Tag des aktuellen Tags zurück. | parent = tag.find_parent() |
.find_all_parents() | Finde alle übergeordneten Tags des aktuellen Tags. | parents = tag.find_all_parents() |
.find_next_sibling() | Finde den nächsten Geschwister-Tag des aktuellen Tags. | next_sibling = tag.find_next_sibling() |
.find_previous_sibling() | Finde den vorherigen Geschwister-Tag des aktuellen Tags. | prev_sibling = tag.find_previous_sibling() |
.parent | Rufe den übergeordneten Tag des aktuellen Tags ab. | parent = tag.parent |
.next_sibling | Rufe den nächsten Geschwister-Tag des aktuellen Tags ab. | next_sibling = tag.next_sibling |
.previous_sibling | Rufe den vorherigen Geschwister-Tag des aktuellen Tags ab. | prev_sibling = tag.previous_sibling |
.get_text() | Extrahiere den Textinhalt innerhalb des Tags, wobei alle HTML-Tags ignoriert werden. | text = tag.get_text() |
.attrs | Gib alle Attribute des Tags zurück, dargestellt als Dictionary. | href = tag.attrs['href'] |
.string | Rufe den String-Inhalt innerhalb des Tags ab. | string_content = tag.string |
.name | Gib den Namen des Tags zurück. | tag_name = tag.name |
.contents | Gib alle untergeordneten Elemente des Tags als Liste zurück. | children = tag.contents |
.descendants | Gib alle Nachfahren-Elemente des Tags in Generatorform zurück. | for child in tag.descendants: print(child) |
.parent | Rufe den übergeordneten Tag des aktuellen Tags ab. | parent = tag.parent |
.previous_element | Ruft das vorherige Element des aktuellen Tags ab (Text ausgeschlossen). | prev_elem = tag.previous_element |
.next_element | Ruft das nächste Element des aktuellen Tags ab (Text ausgeschlossen). | next_elem = tag.next_element |
.decompose() | Entfernt den aktuellen Tag und seinen Inhalt aus dem Baum. | tag.decompose() |
.unwrap() | Entfernt den Tag selbst und behält nur seinen Kindinhalt bei. | tag.unwrap() |
.insert() | Fügt einen neuen Tag oder Text in den Tag ein. | tag.insert(0, new_tag) |
.insert_before() | Fügt einen neuen Tag vor dem aktuellen Tag ein. | tag.insert_before(new_tag) |
.insert_after() | Fügt einen neuen Tag nach dem aktuellen Tag ein. | tag.insert_after(new_tag) |
.extract() | Löscht den Tag und gibt den Tag zurück. | extracted_tag = tag.extract() |
.replace_with() | Ersetzt den aktuellen Tag und seinen Inhalt. | tag.replace_with(new_tag) |
.has_attr() | Prüft, ob der Tag das angegebene Attribut besitzt. | if tag.has_attr('href'): |
.get() | Ruft den Wert des angegebenen Attributs ab. | href = tag.get('href') |
.clear() | Leert alle Inhalte des Tags. | tag.clear() |
.encode() | Kodieren Sie den Tag-Inhalt als Byte-Stream. | encoded = tag.encode() |
.is_empty_element | Prüfen Sie, ob das Tag ein Void-Element ist (z. B.<br>、<img>usw.). | if tag.is_empty_element: |
.is_ancestor_of() | Prüfen Sie, ob das aktuelle Tag ein Vorfahre des angegebenen Tags ist. | if tag.is_ancestor_of(another_tag): |
.is_descendant_of() | Prüfen Sie, ob das aktuelle Tag ein Nachkomme des angegebenen Tags ist. | if tag.is_descendant_of(another_tag): |
Weitere Attribute
| Methode/Attribut | Beschreibung | Beispiel |
|---|---|---|
.style | Rufen Sie den Inline-Stil des Tags ab. | style = tag['style'] |
.id | Rufen Sie die ... des Tags abidAttributs. | id = tag['id'] |
.class_ | Rufen Sie die ... des Tags abclassAttributs. | class_name = tag['class'] |
.string | Rufen Sie den String-Inhalt innerhalb des Tags ab, wobei andere Tags ignoriert werden. | content = tag.string |
.parent | Rufen Sie das übergeordnete Element des Tags ab. | parent = tag.parent |
Sonstiges
| Methode/Attribut | Beschreibung | Beispiel |
|---|---|---|
find_all(string) | Verwenden Sie einen String, um passende Tags zu finden. | tag = soup.find_all('div', class_='container') |
find_all(id) | Finden Sie das angegebene ...id-Tag anzeigen können. | tag = soup.find_all(id='main') |
find_all(attrs) | Finden Sie Tags mit den angegebenen Attributen. | tag = soup.find_all(attrs={"href": "http://example.com"}) |