Mit dem technologischen Fortschritt werden Webserver immer besser in der Lage, den Benutzerverkehr von Web-Scrapern zu unterscheiden, wodurch es für uns alle schwieriger wird, auf die Daten zuzugreifen, die wir
Obwohl es viele Methoden gibt, mit denen wir viele Sicherheitsmaßnahmen umgehen können, gibt es vor allem eine, die nicht genug Aufmerksamkeit erhält: benutzerdefinierte HTTP-Header.
In unserem heutigen Artikel erfahren Sie, was HTTP-Header sind, warum sie für Web Scraping wichtig sind und wie wir sie in unserem Code verwenden können.
Inhaltsübersicht
Was sind HTTP-Header?
Laut MDN ist ein HTTP-Header ein Feld einer HTTP-Anfrage oder -Antwort, das zusätzliche Kontext- und Metadaten über die Anfrage oder Antwort weitergibt. Er besteht aus einem Namen, bei dem die Groß- und Kleinschreibung beachtet wird (z.B. age, cache-control, Date, cookie, etc.), gefolgt von einem Doppelpunkt (:) und seinem Wert.
Einfacher ausgedrückt: Der Benutzer/Client sendet eine Anfrage mit Anfrage-Headern, die dem Server weitere Details liefern. Der Server antwortet dann mit den angeforderten Daten in der Struktur, die den im Anfragekopf enthaltenen Spezifikationen entspricht.
Zur Verdeutlichung sehen Sie hier den Anfrage-Header, den unser Browser zum Zeitpunkt der Erstellung dieses Artikels an Prerender sendet:
</p>
Behörde: in.hotjar.com
:method: POST
:path: /api/v2/client/sites/2829708/visit-data?sv=7
:scheme: https
akzeptieren: */*
akzeptiere-encoding: gzip, deflate, br
akzeptiere-Sprache: en-US,en;q=0.9,it;q=0.8,es;q=0.7
Inhalt-Länge: 112
Inhaltstyp: text/plain; charset=UTF-8
Herkunft: https://prerender.io
Verweiser: https://prerender.io/
sec-ch-ua: " Nicht A;Marke";v="99", "Chromium";v="101", "Microsoft Edge";v="101"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "macOS"
sec-fetch-dest: leer
sec-fetch-mode: cors
sec-fetch-site: standortübergreifend
Benutzer-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, wie Gecko) Chrome/101.0.4951.64 Safari/537.36 Edg/101.0.1210.47
<p>
Was sind Web Cookies?
Web-Cookies, auch HTTP-Cookies oder Browser-Cookies genannt, sind Daten, die von einem Server (HTTP-Antwort-Header) an den Browser eines Benutzers gesendet werden, um ihn später zu identifizieren. Bei einer späteren Anfrage (HTTP-Header-Anfrage) sendet der Browser das Cookie zurück an den Server, so dass der Server den Browser wiedererkennen kann.
Websites und Webanwendungen verwenden Cookies für die Sitzungsverwaltung (z. B. damit Sie eingeloggt bleiben), die Personalisierung (um Einstellungen und Präferenzen beizubehalten), die Nachverfolgung und in einigen Fällen auch für die Sicherheit.
Schauen wir uns an, wie ein Cookie im Anfrage-Header von LinkedIn aussehen würde:
Warum sind Kopfzeilen für Web Scraping wichtig?
Viele Website-Besitzer wissen, dass ihre Daten auf die eine oder andere Weise abgegriffen werden. Daher verwenden sie viele verschiedene Tools und Strategien, um Bots zu identifizieren und sie von ihren Websites fernzuhalten. Und dafür gibt es viele gute Gründe, denn schlecht optimierte Bots können Websites verlangsamen oder sogar zerstören.
Anmerkung: Sie können vermeiden, dass Webserver überlastet werden, und die Wahrscheinlichkeit verringern, dass Sie blockiert werden, wenn Sie die folgenden Best Practices für Web Scraping befolgen.
Eine der Möglichkeiten, der nicht viel Aufmerksamkeit geschenkt wird, ist jedoch die Verwendung von HTTP-Headern und Cookies. Da Ihr Browser/Client HTTP-Header in seinen Anfragen sendet, kann der Server diese Informationen verwenden, um falsche Benutzer zu erkennen und ihnen den Zugriff auf die Website zu verweigern oder falsche/schlechte Informationen zu liefern.
Aber das Gleiche kann auch andersherum funktionieren. Durch die Optimierung der Header, die über die Anfragen unseres Bots gesendet werden, können wir das Verhalten eines organischen Nutzers imitieren und so das Risiko verringern, auf eine schwarze Liste gesetzt zu werden. In einigen Fällen können wir auch die Qualität der von uns gesammelten Daten verbessern.
Die häufigsten HTTP-Header für Web Scraping
Es gibt eine lange Liste von HTTP-Headern, die wir lernen und in unseren Anfragen verwenden könnten, aber in den meisten Fällen sind es nur einige wenige, die uns beim Web Scraping wirklich interessieren:
1. Benutzer-Agent
Dies ist wahrscheinlich der wichtigste Header, da er "den Anwendungstyp, das Betriebssystem, den Softwarehersteller oder die Softwareversion des anfragenden Software-User-Agents" identifiziert und somit die erste Überprüfung ist, die die meisten Server durchführen.
Wenn Sie z.B. eine Anfrage mit der Python-Bibliothek Requests senden, zeigt das User-Agent-Feld die folgenden Informationen an - je nach Ihrer Python-Version:
</p>
Benutzer-Agent: python-requests/2.22.0
<p>
Das ist leicht zu erkennen und wird durch die Strenge blockiert.
Stattdessen möchten wir, dass unser User-Agent-Header eher so aussieht wie der in unserem ersten Beispiel:
</p>
Benutzer-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, wie Gecko) Chrome/101.0.4951.64 Safari/537.36 Edg/101.0.1210.47
<p>
2. Accept-Language
Obwohl dies nicht immer notwendig ist, teilt es dem Server mit, welche Sprachversion der Daten er bereitstellen soll. Wenn zwischen den einzelnen Anfragen eine große Diskrepanz in Bezug auf die Sprache besteht, könnte dies dem Server mitteilen, dass ein Bot beteiligt ist.
Technisch gesehen sollte der Server jedoch immer darauf achten, dass er sich nicht über eine explizite Benutzerentscheidung hinwegsetzt. Wenn also die URLs, die Sie scrapen, bereits bestimmte Sprachen haben, kann dies immer noch als organischer Benutzer wahrgenommen werden.
Hier sehen Sie, wie es in unserer Beispielanfrage aussieht:
</p>
accept-language: en-US,en;q=0.9,it;q=0.8,es;q=0.7
<p>
3. Accept-Encoding
Wie der Name schon sagt, teilt es dem Server mit, welcher Komprimierungsalgorithmus für die zurückgesendete Ressource verwendet werden kann. Dadurch können bis zu 70% der für bestimmte Dokumente benötigten Bandbreite eingespart werden, wodurch die Belastung der Server durch unsere Skripte verringert wird.
</p>
akzeptiere-verschlüsselung: gzip, deflate, br
<p>
4. Referent
Der Referer HTTP-Header teilt dem Server die Seite mit, von der der Benutzer kommt. Obwohl er hauptsächlich zur Nachverfolgung verwendet wird, kann er uns auch dabei helfen, das Verhalten eines organischen Benutzers zu imitieren, indem wir dem Server z.B. mitteilen, dass wir von einer Suchmaschine wie Google gekommen sind.
</p>
Referent: https://prerender.io/
<p>
5. Keks
Wir haben bereits erörtert, was Cookies sind, aber wir haben vielleicht nicht klar gesagt, warum Cookies für Web Scraping wichtig sind.
Cookies ermöglichen es Servern, mit Hilfe eines kleinen Datenpakets zu kommunizieren. Aber was passiert, wenn der Server ein Cookie sendet, der Browser es aber nicht speichert und bei der nächsten Anfrage zurücksendet? Cookies können auch verwendet werden, um festzustellen, ob die Anfrage von einem echten Benutzer oder einem Bot stammt.
Umgekehrt können wir Web-Cookies verwenden, um das organische Verhalten eines Benutzers beim Surfen auf einer Website zu imitieren, indem wir die Cookies nach jeder Interaktion an den Server zurücksenden. Indem wir das Cookie selbst ändern, können wir dem Server mitteilen, dass wir ein neuer Benutzer sind, was es unseren Scraping-Skripten erleichtert, nicht blockiert zu werden.
Wie zeigt man HTTP-Header an? [Einschließlich Cookies]
Bevor wir Kopfzeilen in unserem Code verwenden können, müssen wir sie von irgendwoher abrufen können. Dazu verwenden wir unseren eigenen Browser und rufen die Ziel-Website auf. Für unser Beispiel gehen wir zu google.com > Rechtsklick > Inspizieren um die Entwicklertools zu öffnen.
Von dort aus navigieren wir zur Registerkarte Netzwerk und suchen bei Google nach der Abfrage "web scraping headers".
Während die Seite lädt, wird die Registerkarte Netzwerk aufgefüllt. Schauen wir uns die Registerkarte Fetch/XHR genauer an. Hier finden wir die Dokumente, die vom Browser abgerufen werden, und natürlich die HTTP-Header, die in der Anfrage verwendet werden.
Es gibt zwar keinen einheitlichen Standardnamen für die Datei, nach der wir suchen, aber in der Regel ist es ein relevanter Name für das, was wir auf der Seite zu tun versuchen, oder es ist die Datei, die die zu rendernden Daten liefert.
Wenn Sie auf die Datei klicken, wird standardmäßig die Registerkarte Kopfzeilen geöffnet und wenn Sie nach unten scrollen, sehen Sie den Abschnitt Anfragekopfzeilen.
Jetzt können wir die Kopfzeilenfelder und ihren Wert kopieren und in unseren Code einfügen.
Wie Sie benutzerdefinierte Kopfzeilen für Web Scraping verwenden
Die Art und Weise, wie Sie benutzerdefinierte Header verwenden, hängt von der Programmiersprache ab, die Sie verwenden. Wir werden jedoch versuchen, so viele Beispiele wie möglich hinzuzufügen.
Eine Sache, die Ihnen auffallen wird, ist, dass: ja, jede Methode ist anders, aber sie haben dieselbe Logik, so dass es unabhängig von der Codebasis, die Sie verwenden, sehr einfach ist, sie zu übersetzen.
Für alle unsere Beispiele senden wir unsere Anfrage an https://httpbin.org/headers, eine Website, die zeigt, wie die Antwort und die Anfragen aus der Sicht des Servers aussehen.
So sieht es aus, wenn wir den obigen Link in unserem Browser öffnen:
Die Website antwortet mit den Kopfzeilen, die unser Browser sendet, und wir können nun dieselben Kopfzeilen verwenden, wenn wir unsere Anfrage per Code senden.
Benutzerdefinierte Header in Python verwenden
Bevor wir unsere benutzerdefinierten Kopfzeilen verwenden, sollten wir zunächst eine Testanfrage senden, um zu sehen, was sie zurückgibt:
</p>
Importanträge
url="https://httpbin.org/headers"
Antwort = requests.get(url)
print(antwort.text)
<p>
Wie Sie sehen können, wird als User-Agent der Standard python-requests/2.26.0 verwendet, was es einem Server sehr leicht machen würde, unseren Bot zu erkennen.
Lassen Sie uns nun zum nächsten Schritt übergehen und unsere benutzerdefinierten Kopfzeilen zu unserer Anfrage hinzufügen:
</p>
Importanträge
url="https://httpbin.org/headers"
headers = {
'accept': '*/*',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, wie Gecko) Chrome/101.0.4951.64 Safari/537.36 Edg/101.0.1210.53',
'Accept-Language': 'en-US,en;q=0.9,it;q=0.8,es;q=0.7',
'referer': 'https://www.google.com/',
'cookie': 'DSID=AAO-7r4OSkS76zbHUkiOpnI0kk-X19BLDFF53G8gbnd21VZV2iehu-w_2v14cxvRvrkd_NjIdBWX7wUiQ66f-D8kOkTKD1BhLVlqrFAaqDP3LodRK2I0NfrObmhV9HsedGE7-mQeJpwJifSxdchqf524IMh9piBflGqP0Lg0_xjGmLKEQ0F4Na6THgC06VhtUG5infEdqMQ9otlJENe3PmOQTC_UeTH5DnENYwWC8KXs-M4fWmDADmG414V0_X0TfjrYu01nDH2Dcf3TIOFbRDb993g8nOCswLMi92LwjoqhYnFdf1jzgK0'
}
response = requests.get(url, headers=headers)
print(antwort.text)
<p>
Zunächst erstellen wir ein Wörterbuch mit unseren Kopfzeilen. Einige davon haben wir aus dem HTTPbin, aber die Cookies stammen aus der MDN-Dokumentation und wir haben Google als Referer hinzugefügt, denn in den meisten Fällen kommen die Nutzer über einen Link von Google auf die Website.
Hier ist das Ergebnis:
Theoretisch könnten Sie jede beliebige Kombination als Werte für Ihre benutzerdefinierten Kopfzeilen verwenden. Einige Websites erlauben Ihnen jedoch keinen Zugriff darauf, wenn Sie nicht einen bestimmten Satz von Kopfzeilen senden. Wenn Sie versuchen, beim Scraping benutzerdefinierte Kopfzeilen zu verwenden, ist es besser zu sehen, welche Kopfzeilen Ihr Browser bereits sendet, wenn Sie auf der Ziel-Website navigieren.
Benutzerdefinierte Header in Node.JS verwenden
Wir werden dasselbe tun, aber wir verwenden das Node.JS Axios-Paket, um unsere Anfrage zu senden:
</p>
const axios = require('axios').default;
const url="https://httpbin.org/headers";
const headers = {
'accept': '*/*',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, wie Gecko) Chrome/101.0.4951.64 Safari/537.36 Edg/101.0.1210.53',
'Accept-Language': 'en-US,en;q=0.9,it;q=0.8,es;q=0.7',
'referer': 'https://www.google.com/',
'cookie': 'DSID=AAO-7r4OSkS76zbHUkiOpnI0kk-X19BLDFF53G8gbnd21VZV2iehu-w_2v14cxvRvrkd_NjIdBWX7wUiQ66f-D8kOkTKD1BhLVlqrFAaqDP3LodRK2I0NfrObmhV9HsedGE7-mQeJpwJifSxdchqf524IMh9piBflGqP0Lg0_xjGmLKEQ0F4Na6THgC06VhtUG5infEdqMQ9otlJENe3PmOQTC_UeTH5DnENYwWC8KXs-M4fWmDADmG414V0_X0TfjrYu01nDH2Dcf3TIOFbRDb993g8nOCswLMi92LwjoqhYnFdf1jzgK0',
};
axios.get(url, Headers={headers})
.then((response) => {
console.log(response.data);
}, (error) => {
console.log(error);
});
<p>
Hier ist das Ergebnis:
Benutzerdefinierte Kopfzeilen in ScraperAPI verwenden
Eine großartige Funktion der ScraperAPI ist, dass sie maschinelles Lernen und jahrelange statistische Analysen einsetzt, um die beste Kombination von Kopfzeilen für jede Anfrage zu ermitteln, die wir senden.
In letzter Zeit sehen wir jedoch immer mehr kleine Websites, die ihre Sicherheitsmaßnahmen verbessern, und es gibt nicht genug Daten, damit die API die optimale Kombination automatisch ermitteln kann. Wenn Sie also eine hohe Fehlerquote bemerken, sollten Sie versuchen, benutzerdefinierte Kopfzeilen zu verwenden, wie wir es oben gezeigt haben.
In unserer Dokumentation finden Sie eine vollständige Liste von Programmierbeispielen für Node.JS, PHP, Ruby Web Scraping und Java. Aus Zeitgründen finden Sie hier jedoch ein vollständiges Python-Beispiel für die Verwendung von ScraperAPI mit benutzerdefinierten Headern:
</p>
Importanträge
headers = {
'accept': '*/*',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, wie Gecko) Chrome/101.0.4951.64 Safari/537.36 Edg/101.0.1210.53',
'Accept-Language': 'en-US,en;q=0.9,it;q=0.8,es;q=0.7',
'referer': 'https://www.google.com/',
'cookie': 'DSID=AAO-7r4OSkS76zbHUkiOpnI0kk-X19BLDFF53G8gbnd21VZV2iehu-w_2v14cxvRvrkd_NjIdBWX7wUiQ66f-D8kOkTKD1BhLVlqrFAaqDP3LodRK2I0NfrObmhV9HsedGE7-mQeJpwJifSxdchqf524IMh9piBflGqP0Lg0_xjGmLKEQ0F4Na6THgC06VhtUG5infEdqMQ9otlJENe3PmOQTC_UeTH5DnENYwWC8KXs-M4fWmDADmG414V0_X0TfjrYu01nDH2Dcf3TIOFbRDb993g8nOCswLMi92LwjoqhYnFdf1jzgK0'
}
payload = {
'api_key': '51e43be283e4db2a5afb62660xxxxxxx',
'url': 'https://httpbin.org/headers',
'keep_headers': 'true',
}
response = requests.get('http://api.scraperapi.com', params=payload, headers=headers)
print(antwort.text)
<p>
Die Verwendung benutzerdefinierter Header in Python ist also ganz einfach:
- Wir müssen unser Wörterbuch der Kopfzeilen wie zuvor erstellen und gleich danach unsere Nutzdaten erstellen
- Das erste Element, das wir der Nutzlast hinzufügen, ist unser API-Schlüssel, den wir generieren können, indem wir ein kostenloses ScraperAPI-Konto anlegen
- Als nächstes fügen wir unsere Ziel-URL hinzu - in diesem Fall https://httpbin.org/headers
- Der letzte Parameter ist keep_headers. Setzen Sie ihn auf true, um der ScraperAPI mitzuteilen, dass sie unsere benutzerdefinierten Kopfzeilen behalten soll.
- Zum Schluss fügen wir alle Elemente direkt in unserer Methode requests.get() zusammen
Die Kombination aus all diesen Angaben ergibt eine URL wie diese:
</p>
http://api.scraperapi.com/?api_key=51e43be283e4db2a5afb62660xxxxxxx&url=http://httpbin.org/headers&keep_headers=true
<p>
Einpacken
Web Scraping ist sowohl eine Kunst als auch eine Wissenschaft. Da jede Website anders ist, gibt es nicht nur eine einzige Vorgehensweise. Daher ist es für den Erfolg unserer Projekte entscheidend, dass wir möglichst viele Tools zur Verfügung haben.
Der Zugriff auf den Inhalt einer Seite im richtigen Format ist ein entscheidender Teil des Prozesses und die Verwendung der richtigen HTTP-Header in Ihren Anfragen kann den ganzen Unterschied ausmachen.
Wenn Sie ScraperAPI verwenden, können Sie sich sicher sein, dass unsere API in 99% der Fälle die richtigen Header für Sie auswählt und sendet, so dass Sie sich keine Gedanken mehr machen müssen. In den seltenen Fällen, in denen die Fehlerquote hoch ist, sollten Sie jedoch versuchen, die Kopfzeilen zu extrahieren und zu verwenden, die Ihr Browser an die Zielseite sendet. Nach unserer Erfahrung ist das der Trick.
Wenn Sie jedoch Probleme haben, eine erfolgreiche Anfrage zu garantieren, zögern Sie nicht, uns zu kontaktieren.
Bis zum nächsten Mal, viel Spaß beim Schaben!