Startseite BlogWeb-Scraping Web Scraping von Google-Suchergebnissen in Python

Web Scraping von Google-Suchergebnissen in Python

von Kadek

Data Scraping ist ein wesentlicher Bestandteil eines jeden Unternehmens. Um aktuelle Informationen anbieten zu können, ist es notwendig, die Interessen und Trends von Kunden und 

Eine der wertvollsten Anwendungen von Scrapern ist das Scrapen von Google-Suchergebnissen. Mit dem Scraping von Suchmaschinenergebnissen können Sie verfolgen, welche Daten die Nutzer erhalten, und Leads sammeln.  

Unserer Erfahrung nach ist Python eine der am besten geeigneten Programmiersprachen für Scraping. Mit ihr können Sie einfach und schnell Skripte zum Sammeln von Daten schreiben. In diesem Tutorial sehen wir uns also an, wie Sie Google-Suchergebnisse in Python scrapen können, welche Herausforderungen Sie dabei bewältigen müssen und wie Sie diese umgehen können.

Google SERP Seitenanalyse

Bevor Sie einen Google Scraper erstellen, müssen Sie die Seite analysieren, die Sie scrapen wollen, um zu wissen, wo sich die notwendigen Elemente befinden. Sie müssen zunächst den Link berücksichtigen, den Google bei einer Suchanfrage generiert. 


Forschung rhe link

Der Link ist ganz einfach, und wir können ihn selbst generieren. Der Teil "https://www.google.com/search?q=" bleibt unverändert, gefolgt von dem Abfragetext mit einem "+" anstelle eines Leerzeichens.

Jetzt müssen wir herausfinden, wo sich die Daten befinden, die wir benötigen. Öffnen Sie dazu DevTools (klicken Sie mit der rechten Maustaste auf den Bildschirm und drücken Sie Inspect, oder drücken Sie einfach F12).


Recherchieren Sie die Seite

Leider werden fast alle Klassen auf den Ergebnisseiten der Suchmaschinen automatisch generiert. Daher ist es schwierig, die Daten anhand des Klassennamens zu ermitteln. Die Struktur der Seite bleibt jedoch unverändert. Auch die Klasse 'g' der Suchergebnisse bleibt unverändert.

Wenn wir uns die Elemente innerhalb dieser Klasse genau ansehen, können wir die Tags identifizieren, die den Link, den Titel und die Beschreibung des Elements enthalten:


Tags finden

Nun, da wir uns die Seite angesehen und die Elemente gefunden haben, die wir scrapen wollen, können wir uns an die Erstellung des Scrapers machen.

Einrichten der Entwicklungsumgebung

Bevor wir uns mit dem Scraping von Google-Suchergebnissen beschäftigen, müssen wir eine geeignete Entwicklungsumgebung in Python einrichten. Dazu gehört die Installation der notwendigen Bibliotheken und Tools, die es uns ermöglichen, Anfragen an Google zu senden, HTML-Antworten zu parsen und die Daten effektiv zu verarbeiten.

Stellen Sie zunächst sicher, dass Sie Python auf Ihrem Rechner installiert haben. Um dies zu überprüfen, können Sie Folgendes verwenden:

python -v

Wenn Sie eine Version von Python haben, dann haben Sie sie. Wir werden Python Version 3.10.7 verwenden. Wenn Sie Python nicht installiert haben, besuchen Sie die offizielle Python-Website und laden Sie die neueste Version herunter, die mit Ihrem Betriebssystem kompatibel ist. Folgen Sie den Installationsanweisungen und fügen Sie Python zur PATH-Variable Ihres Systems hinzu.

Um die verschiedenen Möglichkeiten zum Scraping der Google SERP zu zeigen, installieren wir die folgenden Bibliotheken:

pip install beautifulsoup4
pip install selenium
pip install google-serp-api

Wir werden in unserem Python-Skript auch die requests-Bibliothek verwenden, eine vorinstallierte Python-Bibliothek. Wenn Sie diese jedoch aus irgendeinem Grund nicht haben, können Sie den Befehl verwenden:

pip install requests

Sie können auch die urllib-Bibliothek anstelle der requests-Bibliothek verwenden.

Um Selenium Headless Browser zu verwenden, müssen Sie außerdem die entsprechende WebDriver-Datei für Ihren Browser herunterladen. Selenium benötigt einen separaten WebDriver für die Schnittstelle zu jedem Browser. Wenn Sie zum Beispiel Google Chrome verwenden, benötigen Sie den ChromeDriver. Sie können ihn von der offiziellen Website herunterladen.

Scraping der Google-Suche mit Python und BeautifulSoup

Nachdem wir nun die Entwicklungsumgebung eingerichtet haben, können wir mit dem Parsen und Extrahieren von Daten aus Google-Suchergebnissen beginnen. Wir werden die requests-Bibliothek verwenden, um HTTP-Anfragen zu senden und die HTML-Antwort abzurufen, sowie die BeautifulSoup-Bibliothek, um die HTML-Struktur zu analysieren und zu navigieren. Lassen Sie uns eine neue Datei erstellen und die Bibliotheken verbinden:

import requests
from bs4 import BeautifulSoup

Um unseren Scraper zu tarnen und die Wahrscheinlichkeit einer Blockierung zu verringern, setzen wir Abfrage-Header:

header={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36'}

Es ist wünschenswert, dass Sie in der Anfrage die vorhandenen Überschriften angeben. Sie können zum Beispiel Ihre eigenen verwenden, die Sie in DevTools auf der Registerkarte Netzwerk finden. Dann führen wir die Abfrage aus und schreiben die Antwort in eine Variable:

data = requests.get('https://www.google.com/search?q=cafe+in+new+york', headers=header)

In diesem Stadium erhalten wir bereits den Code der Seite, den wir dann verarbeiten müssen. Erstellen Sie ein BeautifulSoup-Objekt und analysieren Sie den resultierenden HTML-Code der Seite:

soup = BeautifulSoup(data.content, "html.parser")

Lassen Sie uns auch eine Variable result erstellen, in die wir die Daten über die Elemente schreiben werden:

results = []

Damit wir die Daten Element für Element verarbeiten können, erinnern Sie sich daran, dass jedes Element eine Klasse 'g' hat. Das heißt, um alle Elemente durchzugehen und Daten von ihnen zu erhalten, holen Sie sich alle Elemente mit der Klasse 'g' und gehen sie eines nach dem anderen durch, um die erforderlichen Daten zu erhalten. Lassen Sie uns dazu eine for-Schleife erstellen:

for g in soup.find_all('div',  {'class':'g'}):

Wenn wir uns den Code der Seite genau ansehen, sehen wir außerdem, dass alle Elemente Kinder der <a> Tag, in dem der Seitenlink gespeichert ist. Lassen Sie uns das verwenden und die Daten für Titel, Link und Beschreibung abrufen. Wir berücksichtigen, dass die Beschreibung leer sein kann und fügen sie in den try...except-Block ein:

        if anchors:
            link = anchors[0]['href']
            title = g.find('h3').text
            try:
                description = g.find('div', {'data-sncf':'2'}).text
            except Exception as e:
                description = "-"

Geben Sie die Daten über die Elemente in die Ergebnisvariable ein:

            results.append(str(title)+";"+str(link)+';'+str(description))

Jetzt könnten wir die Variable auf dem Bildschirm anzeigen, aber lassen Sie uns die Dinge komplizierter machen und die Daten in einer Datei speichern. Dazu erstellen oder überschreiben Sie eine Datei mit den Spalten "Titel", "Link", "Beschreibung":

with open("serp.csv", "w") as f:
    f.write("Title; Link; Description\n")

Geben Sie nun die Daten aus der Ergebnisvariable Zeile für Zeile ein:

for result in results:
    with open("serp.csv", "a", encoding="utf-8") as f:
        f.write(str(result)+"\n")

Derzeit haben wir einen einfachen Suchmaschinen-Scraper, der die Ergebnisse in einer CSV-Datei sammelt. 


Bereitgestellte Daten

Vollständiger Code:

import requests
from bs4 import BeautifulSoup

url="https://www.google.com/search?q=cafe+in+new+york"
header={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36'}
data = requests.get(url, headers=header)

if data.status_code == 200:
    soup = BeautifulSoup(data.content, "html.parser")
    results = []
    for g in soup.find_all('div',  {'class':'g'}):
        anchors = g.find_all('a')
        if anchors:
            link = anchors[0]['href']
            title = g.find('h3').text
            try:
                description = g.find('div', {'data-sncf':'2'}).text
            except Exception as e:
                description = "-"
            results.append(str(title)+";"+str(link)+';'+str(description))

with open("serp.csv", "w") as f:
    f.write("Title; Link; Description\n")

for result in results:
    with open("serp.csv", "a", encoding="utf-8") as f:
        f.write(str(result)+"\n")

Leider hat dieses Skript mehrere Nachteile:

  1. Es sammelt nur wenige Daten.
  2. Es sammelt keine dynamischen Daten.
  3. Es verwendet keine Proxys.
  4. Es führt keine Aktionen auf der Seite durch. 
  5. Ein Captcha wird nicht gelöst.

Lassen Sie uns ein neues Skript auf der Grundlage der Selenium-Bibliothek schreiben, um einige dieser Probleme zu lösen.

Headless Browser verwenden, um Daten aus Suchergebnissen zu erhalten

Ein Headless-Browser kann von Vorteil sein, wenn Sie mit Webseiten arbeiten, die dynamische Inhalte, CAPTCHA-Herausforderungen oder JavaScript-Rendering erfordern. Selenium, ein leistungsstarkes Web-Automatisierungstool, ermöglicht es uns, mit einem Headless-Browser mit Webseiten zu interagieren und Daten aus ihnen zu extrahieren.

Erstellen Sie eine neue Datei und verbinden Sie die Bibliotheken:

from selenium import webdriver
from selenium.webdriver.common.by import By

Lassen Sie uns nun zeigen, wo sich der zuvor heruntergeladene Web-Treiber befindet:

DRIVER_PATH = 'C:\chromedriver.exe'
driver = webdriver.Chrome(executable_path=DRIVER_PATH)

Im vorherigen Skript haben wir die Abfrage mit einem Link angegeben. Aber wir haben gesehen, dass alle Abfragen gleich aussahen. Lassen Sie uns das also verbessern und es möglich machen, einen Link auf der Grundlage einer Textabfrage zu erzeugen:

search_query = "cafe in new york"
base_url = "https://www.google.com/search?q="
search_url = base_url + search_query.replace(" ", "+")

Jetzt können wir die gewünschte Seite aufrufen:

driver.get(search_url)

Lassen Sie uns die Daten mithilfe der CSS-Selektoren aus dem vorherigen Skript extrahieren:

results = []
result_divs = driver.find_elements(By.CSS_SELECTOR, "div.g")
for result_div in result_divs:
    result = {}
    anchor = result_div.find_elements(By.CSS_SELECTOR, "a")
    link = anchor[0].get_attribute("href")
    title = result_div.find_element(By.CSS_SELECTOR, "h3").text
    description_element = result_div.find_element(By.XPATH, "//div[@data-sncf="2"]")
    description = description_element.text if description_element else "-"
    results.append(str(title)+";"+str(link)+';'+str(description))

Schließen Sie den Browser:

driver.quit()

Und speichern Sie dann die Daten in einer Datei:

with open("serp.csv", "w") as f:
    f.write("Title; Link; Description\n")
for result in results:
    with open("serp.csv", "a", encoding="utf-8") as f:
        f.write(str(result)+"\n")

Mit Selenium haben wir einige der Probleme gelöst, die mit Scraping verbunden sind. So haben wir zum Beispiel das Risiko einer Blockierung deutlich verringert, da der Headless Browser die Arbeit eines echten Benutzers vollständig simuliert und das Skript somit nicht von einer Person zu unterscheiden ist.  

Außerdem ermöglicht uns dieser Ansatz, mit verschiedenen Elementen auf der Seite zu arbeiten und dynamische Seiten zu verschrotten.

Allerdings können wir immer noch nicht unseren Standort kontrollieren, wir können das Captcha nicht lösen, falls es auftritt, und wir verwenden keine Proxys. Gehen wir zur folgenden Bibliothek über, um diese Probleme zu lösen.

Web Scraping mit Google Search API 

Um mit unserer Bibliothek arbeiten zu können, benötigen Sie einen API-Schlüssel, den Sie in Ihrem Konto finden können. Um also einen funktionsreichen Google SERP Scraper zu erstellen, sollten Sie unsere Bibliothek verwenden:

from google_serp_api import ScrapeitCloudClient

Lassen Sie uns auch die integrierte json-Bibliothek einbinden, um die Antwort im JSON-Format zu verarbeiten:

import json

Lassen Sie uns den API-Schlüssel angeben und die Parameter festlegen:

client = ScrapeitCloudClient(api_key='YOUR-API-KEY')
response = client.scrape(
    params={
        "keyword": "cafe in new york",
        "country": "US",
        "num_results": 10,
        "domain": "com"
    }
)

Sie können das Suchwort, das Land, aus dem Sie Daten abrufen möchten, die Anzahl der abzurufenden Ergebnisse und die Google-Domäne festlegen. Wenn Sie diesen Code ausführen, wird eine JSON-formatierte Antwort mit Daten in der folgenden Ansicht zurückgegeben:

status
scrapingResult  
    currentPage
    organic
        domain
        linkType
        position
        snippet
        title
        url
    pagination
        page
        path
    relatedKeywords
        keyword
        path
    totalResults
    timeTaken

Lassen Sie uns die Daten von "organic" und "relatedKeywords" in separaten Dateien speichern. Formatieren Sie zunächst die empfangene Antwort aus dem String in JSON und fügen Sie die Daten aus den gewünschten Attributen in Variablen ein.

data = json.loads(response.text)
organic_results = data['scrapingResult']['organic']
keywords = data['scrapingResult']['relatedKeywords']

Erstellen Sie Variablen mit dem gewünschten Ergebnis.

rows_organic = []
rows_keys =[]

Gehen Sie alle Fahrspuren Element für Element durch und fügen Sie sie in der richtigen Form in die Variablen ein:

for result in organic_results:
    rows_organic.append(str(result['position'])+";"+str(result['title'])+";"+str(result['url'])+";"+str(result['domain'])+";"+str(result['snippet']))
for result in keywords:
    rows_keys.append(str(result['keyword'])+";"+str(result['path']))

Lassen Sie uns die Daten in Dateien speichern:

with open("data_organic.csv", "w") as f:
    f.write("position; title; url; domain; snippet'\n")
for row in rows_organic:
    with open("data_organic.csv", "a", encoding="utf-8") as f:
        f.write(str(row)+"\n")
with open("data_keys.csv", "w") as f:
    f.write("keyword; path'\n")
for row in rows_keys:
    with open("data_keys.csv", "a", encoding="utf-8") as f:
        f.write(str(row)+"\n")

Als Ergebnis der Ausführung des Skripts erhalten wir zwei Dateien:


CSV-Datei

Wir können die Anzahl der Ergebnisse ändern, indem wir den Parameter num_results in "params" ändern. Nehmen wir jedoch an, wir haben eine Datei, in der alle Schlüsselwörter gespeichert sind, die wir zum Scrapen von Daten benötigen. Wir müssen die Datei zunächst öffnen und sie dann Zeile für Zeile mit einem neuen Schlüsselwort durchgehen:

with open("keywords.csv") as f:
    lines = f.readlines()
with open("data_keys.csv", "w") as f:
    f.write("search_key; keyword; path'\n")
with open("data_organic.csv", "w") as f:
    f.write("search_key; position; title; url; domain; snippet'\n")
for line in lines:

Wir haben Spaltenüberschriften für neue Dateien festgelegt, bevor das Schlüsselwort übergeben wird. Das bedeutet, dass die Datei nicht überschrieben wird, wenn Sie ein neues Schlüsselwort suchen. Stattdessen wird die Datei mit weiteren Daten angereichert. Wir haben außerdem eine weitere Spalte hinzugefügt, die die Textsuchanfrage enthält, auf die die Ergebnisse zutreffen.

Ändern Sie nun die Antwort und geben Sie das Schlüsselwort an, das mit der variablen Zeile übereinstimmen wird:

response = client.scrape(
        params={
            "keyword": str(line.replace("\n","")),
            "country": "US",
            "num_results": 10,
            "domain": "com"
        }
    )

Der Rest des Codes wird ähnlich sein. Es wird lediglich eine neue Spalte mit der variablen Zeile hinzugefügt. Als Ergebnis erhalten wir die folgenden zwei Dateien:


Finale Dateien

Vollständiger Python-Code:

from google_serp_api import ScrapeitCloudClient
import json
with open("keywords.csv") as f:
    lines = f.readlines()

with open("data_keys.csv", "w") as f:
    f.write("search_key; keyword; path'\n")

with open("data_organic.csv", "w") as f:
    f.write("search_key; position; title; url; domain; snippet'\n")

for line in lines:

    client = ScrapeitCloudClient(api_key='YOUR-API-KEY')
    response = client.scrape(
        params={
            "keyword": str(line.replace("\n","")),
            "country": "US",
            "num_results": 10,
            "domain": "com"
        }
    )
    data = json.loads(response.text)
    organic_results = data['scrapingResult']['organic']
    keywords = data['scrapingResult']['relatedKeywords']
    rows_organic = []
    rows_keys =[]

    for result in organic_results:
        rows_organic.append(str(line.replace("\n",""))+";"+str(result['position'])+";"+str(result['title'])+";"+str(result['url'])+";"+str(result['domain'])+";"+str(result['snippet']))
    for result in keywords:
        rows_keys.append(str(line.replace("\n",""))+";"+str(result['keyword'])+";"+str(result['path']))

    for row in rows_organic:
        with open("data_organic.csv", "a", encoding="utf-8") as f:
            f.write(str(row)+"\n")

    for row in rows_keys:
        with open("data_keys.csv", "a", encoding="utf-8") as f:
            f.write(str(row)+"\n")

Der Hauptvorteil der Scrape-It.Cloud-Bibliothek besteht darin, dass Sie sich keine Gedanken über Proxy-Rotation, JavaScript-Rendering oder das Lösen von Captchas machen müssen - die API liefert vorbereitete Daten.

Scraping der Google-Suche mit Python: Herausforderungen und Grenzen

Das Scraping von Google-Suchergebnissen mit Python kann knifflig sein. Beim Scraping von Google-Suchergebnissen gibt es mehrere Herausforderungen zu bewältigen, von der technischen Komplexität im Zusammenhang mit dem sich ständig ändernden Algorithmus der Suchmaschine bis hin zu den eingebauten Anti-Scraping-Schutzmaßnahmen. Außerdem besteht die Möglichkeit, IP-Adressen zu blockieren und Captchas einzugeben, sowie viele andere Herausforderungen, die wir weiter unten besprechen werden.

Einschränkungen bei der Geolokalisierung

Die Google-Suchergebnisse können je nach Standort variieren. Wenn Sie beispielsweise von den Vereinigten Staaten aus suchen, können Ihre Ergebnisse anders ausfallen als bei einer Suche in Kanada. Wenn Sie die Erlaubnis haben, auf Standortdaten zuzugreifen, oder wenn Sie genügend Suchanfragen von einem Ort aus gestellt haben, wird Google die Suchergebnisse nur für dieses Gebiet anzeigen. Um herauszufinden, wie die Suchergebnisse für andere Länder oder Städte aussehen, müssen Sie einen Proxy-Server von diesem Ort aus verwenden oder Sie können eine vorgefertigte Web Scraping API nutzen, die sich um all dies kümmert.

Länderspezifische Domains

Google unterstützt verschiedene Suchdomänen für verschiedene Länder. Zum Beispiel google.co.uk für Großbritannien oder google.de für Deutschland. Jede hat ihre eigenen Funktionen, ihre eigene Google SERP und ihre eigenen Google Maps, die beim Scrapen berücksichtigt werden müssen.

Beschränkungen auf Ergebnisseiten

Die Seite zeigt eine begrenzte Anzahl von Ergebnissen an. Um die nächste Reihe anzuzeigen, müssen Sie entweder durch die vorhandenen Suchergebnisse blättern oder zur nächsten Seite wechseln. Denken Sie daran, dass jeder Seitenwechsel von Google als neue Anfrage betrachtet wird und dass bei zu vielen Anfragen Ihre IP-Adresse blockiert werden kann oder Sie eine Captcha-Abfrage zur Verifizierung durchführen müssen.

Captcha und Anti-Scraping-Maßnahmen

Wie wir bereits erwähnt haben, verfügt Google über verschiedene Methoden, um gegen Web Scraping vorzugehen. Captcha und die Sperrung von IP-Adressen sind zwei der gängigsten Strategien.

Um Captcha-Herausforderungen zu lösen, können Sie Dienste von Drittanbietern nutzen, bei denen echte Menschen diese gegen eine geringe Gebühr lösen. Allerdings müssen Sie dies in Ihre eigene Anwendung integrieren und richtig einrichten.

Das Gleiche gilt für IP-Sperren. Sie können diese Herausforderung umgehen, indem Sie Proxys mieten, um Ihre IP-Adresse zu verbergen und auch diese Sperren zu umgehen - aber nur, wenn Sie einen entsprechenden Proxy-Anbieter finden, der zuverlässig genug ist, um Ihnen diese Aufgabe anzuvertrauen. Sie können sich auch unsere Liste kostenloser Proxys ansehen.

Dynamische HTML-Struktur

JavaScript-Rendering ist eine weitere Möglichkeit, sich gegen Scraper und Bots zu schützen. Das bedeutet, dass der Seiteninhalt dynamisch erstellt wird und sich bei jedem Laden der Seite ändert. Die Klassen auf einer Webseite können beispielsweise bei jedem Öffnen der Seite andere Namen haben - die Gesamtstruktur der Webseite bleibt jedoch konsistent. Das macht das Scraping der Seite schwieriger, aber immer noch möglich.

Unvorhersehbare Änderungen

Google entwickelt sich ständig weiter und verbessert seine Algorithmen und Prozesse. Das bedeutet, dass alle Web Scraping Tools nicht ewig ohne Wartung verwendet werden können - sie müssen mit den neuesten Änderungen von Google auf dem Laufenden gehalten werden.

Fazit und Schlussfolgerungen

Es gibt verschiedene Möglichkeiten und Bibliotheken, die bei der Datenextraktion aus Google SERPs in Python helfen. Jeder wählt die Option, die am besten zu seinem Projekt und seinen Fähigkeiten passt. 

Wenn Sie neu im Scraping sind und nur eine kleine Menge an Daten abrufen möchten, sind Sie vielleicht mit der Requests-Bibliothek zum Ausführen von Abfragen und der BeautifulSoup-Bibliothek zum Parsen der erhaltenen Daten zufrieden. Wenn Sie mit Headless Browsern und Automatisierungstools vertraut sind, dann ist Selenium das Richtige für Sie.

Und wenn Sie es vermeiden möchten, Dienste von Drittanbietern zu verbinden, um Captchas zu lösen, Proxys zu mieten und sich keine Gedanken darüber zu machen, wie Sie das Blockieren oder den Erhalt der gewünschten Daten vermeiden können, können Sie die google_serp_api-Bibliothek verwenden.

Verwandte Beiträge

Einen Kommentar hinterlassen