Was ist der beste Weg, um Daten von einer Website zu kratzen? [geschlossen]

107

Ich muss Inhalte von einer Website extrahieren, aber die Anwendung bietet keine Anwendungsprogrammierschnittstelle oder einen anderen Mechanismus, um programmgesteuert auf diese Daten zuzugreifen.

Ich habe ein nützliches Drittanbieter-Tool namens Import.io gefunden , das Click-and-Go-Funktionen zum Scrapen von Webseiten und zum Erstellen von Datensätzen bietet. Das einzige, was ich möchte, ist, dass ich meine Daten lokal aufbewahren und keine Abonnementpläne abonnieren möchte .

Welche Technik verwendet dieses Unternehmen, um die Webseiten zu kratzen und ihre Datensätze zu erstellen? Ich fand einige Web-Scraping-Frameworks von pjscrape & Scrapy, die eine solche Funktion bieten könnten

0x1ad2
quelle
4
PHP kommt sicher nicht in Frage, das ist natürlich einfach falsch. gist.github.com/krakjoe/b1526fcc828621e840cb
Joe Watkins
@ JoeWatkins, das wirklich cool aussieht, braucht es eine spezielle PHP-Konfiguration, um zu laufen? Und wie ist die Leistung im Vergleich zu den unten bereitgestellten Tools / Sprachen?
0x1ad2
1
Es erfordert einen thread-sicheren Build von PHP und pthreads. Lesen Sie github.com/krakjoe/pthreads/blob/master/README.md . Sie können mich im Chat finden, wenn Sie Hilfe benötigen , mich oder andere :)
Joe Watkins
@ 0x1ad2 Wenn Sie Daten lokal speichern möchten, sollten Sie stattdessen Software ( datascraping.co ) anstelle von Web-APIs verwenden. Die meisten Tools verwenden Xpath, CSS Selector und REGEX, um die Daten von Websites zu extrahieren, und Data Scraping Studio unterstützt all diese drei Funktionen.
Vikash Rathee
Es gibt zwei Möglichkeiten: Zum einen können Sie Ihre eigenen mithilfe von Free / Open Source-Bibliotheken einführen, was viel Aufwand erfordert. Mit scrape.it können Sie buchstäblich einen Ajax-Webcrawler für jede Site generieren. Es ist ein kostenpflichtiges Tool, aber es hat funktioniert, wenn weder kostenlose Tools wie import.io noch Kimono gerendert werden konnten.
Ich liebe Python

Antworten:

271

Sie werden auf jeden Fall mit einem guten Web-Scraping-Framework beginnen wollen. Später können Sie entscheiden, dass sie zu einschränkend sind, und Sie können Ihren eigenen Stapel von Bibliotheken zusammenstellen, aber ohne viel Erfahrung mit dem Scraping wird Ihr Design viel schlechter sein als pjscrape oder Scrapy.

Hinweis: Ich verwende die Begriffe Crawlen und Scraping, die hier grundsätzlich austauschbar sind. Dies ist eine Kopie meiner Antwort auf Ihre Quora-Frage, sie ist ziemlich lang.

Werkzeuge

Machen Sie sich je nach Ihrem bevorzugten Browser mit den Firebug- oder Chrome-Entwicklertools vertraut. Dies ist unbedingt erforderlich, wenn Sie die Site durchsuchen, von der Sie Daten abrufen, und herausfinden, welche URLs die gesuchten Daten enthalten und aus welchen Datenformaten die Antworten bestehen.

Sie benötigen gute Kenntnisse in HTTP und HTML und möchten wahrscheinlich einen anständigen Mann in der Middle-Proxy-Software finden. Sie müssen in der Lage sein, HTTP-Anforderungen und -Antworten zu überprüfen und zu verstehen, wie die Cookies, Sitzungsinformationen und Abfrageparameter weitergegeben werden. Fiddler ( http://www.telerik.com/fiddler ) und Charles Proxy ( http://www.charlesproxy.com/ ) sind beliebte Tools. Ich benutze Mitmproxy ( http://mitmproxy.org/ ) oft, da ich eher ein Keyboard-Typ als ein Maus-Typ bin.

Eine Art Konsolen- / Shell- / REPL-Umgebung, in der Sie verschiedene Codeteile mit sofortigem Feedback ausprobieren können, ist von unschätzbarem Wert. Reverse Engineering-Aufgaben wie diese sind eine Menge Versuch und Irrtum, daher möchten Sie einen Workflow, der dies einfach macht.

Sprache

PHP ist im Grunde genommen nicht verfügbar, es ist nicht gut für diese Aufgabe geeignet und die Unterstützung für Bibliotheken / Frameworks ist in diesem Bereich schlecht. Python (Scrapy ist ein guter Ausgangspunkt) und Clojure / Clojurescript (unglaublich leistungsfähig und produktiv, aber eine große Lernkurve) sind großartige Sprachen für dieses Problem. Da Sie lieber keine neue Sprache lernen möchten und bereits Javascript kennen, würde ich definitiv empfehlen, bei JS zu bleiben. Ich habe pjscrape nicht verwendet, aber es sieht ziemlich gut aus, wenn man ihre Dokumente schnell liest. Es ist gut geeignet und bietet eine hervorragende Lösung für das unten beschriebene Problem.

Ein Hinweis zu regulären Ausdrücken: Verwenden Sie keine regulären Ausdrücke, um HTML zu analysieren. Viele Anfänger tun dies, weil sie bereits mit Regexen vertraut sind. Es ist ein großer Fehler, xpath- oder css-Selektoren zum Navigieren in HTML zu verwenden und nur reguläre Ausdrücke zu verwenden, um Daten aus dem tatsächlichen Text innerhalb eines HTML-Knotens zu extrahieren. Dies mag für Sie bereits offensichtlich sein. Es wird schnell klar, wenn Sie es versuchen, aber viele Leute verschwenden aus irgendeinem Grund viel Zeit damit, diesen Weg zu gehen. Haben Sie keine Angst vor xpath- oder css-Selektoren, sie sind viel einfacher zu lernen als reguläre Ausdrücke und wurden entwickelt, um genau dieses Problem zu lösen.

Javascript-schwere Websites

Früher musste man nur eine http-Anfrage stellen und die HTML-Antwort analysieren. Jetzt müssen Sie sich mit ziemlicher Sicherheit mit Websites befassen, die eine Mischung aus Standard-HTML-HTTP-Anforderungen / -Antworten und asynchronen HTTP-Aufrufen sind, die vom Javascript-Teil der Zielwebsite ausgeführt werden. Hier sind Ihre Proxy-Software und die Registerkarte "Netzwerk" von firebug / devtools sehr nützlich. Die Antworten auf diese können HTML oder JSON sein, in seltenen Fällen sind sie XML oder etwas anderes.

Es gibt zwei Ansätze für dieses Problem:

Der Low-Level-Ansatz:

Sie können herausfinden, welche Ajax-URLs die Site Javascript aufruft und wie diese Antworten aussehen, und dieselben Anfragen selbst stellen. Sie können also den HTML-Code von http://example.com/foobar abrufen und ein Datenelement extrahieren. Anschließend müssen Sie die JSON-Antwort von http://example.com/api/baz?foo=b ... nach ziehen Holen Sie sich die anderen Daten. Sie müssen sich bewusst sein, dass Sie die richtigen Cookies oder Sitzungsparameter übergeben. Es ist sehr selten, aber gelegentlich sind einige erforderliche Parameter für einen Ajax-Aufruf das Ergebnis einer verrückten Berechnung im Javascript der Site. Reverse Engineering kann ärgerlich sein.

Der eingebettete Browser-Ansatz:

Warum müssen Sie herausfinden, welche Daten in HTML enthalten sind und welche Daten von einem Ajax-Aufruf stammen? Alle Sitzungs- und Cookie-Daten verwalten? Sie müssen dies nicht tun, wenn Sie eine Site durchsuchen. Der Browser und das Site-Javascript tun dies. Das ist der springende Punkt.

Wenn Sie die Seite nur in eine kopflose Browser-Engine wie phantomjs laden, wird die Seite geladen, das Javascript ausgeführt und Sie erfahren, wann alle Ajax-Aufrufe abgeschlossen sind. Sie können bei Bedarf Ihr eigenes Javascript einfügen, um die entsprechenden Klicks auszulösen, oder was auch immer erforderlich ist, um das Site-Javascript zum Laden der entsprechenden Daten auszulösen.

Sie haben jetzt zwei Möglichkeiten: Lassen Sie das fertige HTML ausspucken und analysieren oder fügen Sie Javascript in die Seite ein, die Ihre Analyse und Datenformatierung durchführt und die Daten ausspuckt (wahrscheinlich im JSON-Format). Sie können diese beiden Optionen auch frei mischen.

Welcher Ansatz ist am besten?

Das hängt davon ab, dass Sie mit dem Low-Level-Ansatz auf jeden Fall vertraut und vertraut sein müssen. Der eingebettete Browser-Ansatz funktioniert für alles, er ist viel einfacher zu implementieren und lässt einige der schwierigsten Probleme beim Scraping verschwinden. Es ist auch eine ziemlich komplexe Maschine, die Sie verstehen müssen. Es geht nicht nur um HTTP-Anfragen und -Antworten, sondern auch um Anfragen, das Rendern eingebetteter Browser, Site-Javascript, injiziertes Javascript, Ihren eigenen Code und die wechselseitige Interaktion mit dem eingebetteten Browserprozess.

Der eingebettete Browser ist aufgrund des Rendering-Overheads auch im Maßstab viel langsamer, aber das spielt mit ziemlicher Sicherheit keine Rolle, es sei denn, Sie kratzen viele verschiedene Domänen. Durch die Notwendigkeit, Ihre Anforderungen zu bewerten, wird die Renderzeit bei einer einzelnen Domain völlig vernachlässigbar.

Ratenbegrenzung / Bot-Verhalten

Sie müssen sich dessen sehr bewusst sein. Sie müssen Anfragen an Ihre Zieldomänen zu einem angemessenen Preis stellen. Sie müssen einen gut erzogenen Bot schreiben, wenn Sie Websites crawlen. Dies bedeutet, dass Sie robots.txt respektieren und den Server nicht mit Anfragen belasten. Fehler oder Nachlässigkeit sind hier sehr unethisch, da dies als Denial-of-Service-Angriff angesehen werden kann. Die akzeptable Rate hängt davon ab, wen Sie fragen. 1 req / s ist das Maximum, mit dem der Google-Crawler ausgeführt wird, aber Sie sind nicht Google und wahrscheinlich nicht so willkommen wie Google. Halte es so langsam wie möglich. Ich würde 2-5 Sekunden zwischen jeder Seitenanforderung vorschlagen.

Identifizieren Sie Ihre Anforderungen mit einer Benutzeragentenzeichenfolge, die Ihren Bot identifiziert, und erstellen Sie eine Webseite für Ihren Bot, auf der der Zweck erläutert wird. Diese URL wird in die Agentenzeichenfolge aufgenommen.

Sie können leicht blockiert werden, wenn die Site Sie blockieren möchte. Ein intelligenter Ingenieur am Ende kann Bots leicht identifizieren, und ein paar Minuten Arbeit am Ende können dazu führen, dass wochenlange Arbeit Ihren Scraping-Code an Ihrem Ende ändert oder es einfach unmöglich macht. Wenn die Beziehung gegensätzlich ist, kann ein intelligenter Ingenieur am Zielstandort einen genialen Ingenieur, der einen Crawler schreibt, vollständig behindern. Scraping-Code ist von Natur aus fragil und kann leicht ausgenutzt werden. Etwas, das diese Reaktion provozieren würde, ist mit ziemlicher Sicherheit sowieso unethisch. Schreiben Sie also einen gut erzogenen Bot und machen Sie sich darüber keine Sorgen.

Testen

Keine Einheit / Integrationstestperson? Schade. Du musst jetzt eins werden. Websites ändern sich häufig und Sie werden Ihren Code häufig ändern. Dies ist ein großer Teil der Herausforderung.

Es gibt viele bewegliche Teile beim Scrapen einer modernen Website. Gute Testpraktiken helfen sehr. Viele der Fehler, die beim Schreiben dieses Codetyps auftreten, sind solche, die nur beschädigte Daten stillschweigend zurückgeben. Ohne gute Tests zur Überprüfung auf Regressionen werden Sie feststellen, dass Sie unbrauchbare beschädigte Daten für eine Weile in Ihrer Datenbank gespeichert haben, ohne es zu merken. Dieses Projekt macht Sie mit der Datenvalidierung (einige gute Bibliotheken) und dem Testen vertraut. Es gibt nicht viele andere Probleme, die zusammenfassende Tests erfordern und sehr schwer zu testen sind.

Der zweite Teil Ihrer Tests umfasst das Zwischenspeichern und die Änderungserkennung. Während Sie Ihren Code schreiben, möchten Sie den Server nicht ohne Grund immer wieder auf dieselbe Seite hämmern. Während Sie Ihre Komponententests ausführen, möchten Sie wissen, ob Ihre Tests fehlschlagen, weil Sie Ihren Code gebrochen haben oder weil die Website neu gestaltet wurde. Führen Sie Ihre Komponententests anhand einer zwischengespeicherten Kopie der beteiligten URLs aus. Ein Caching-Proxy ist hier sehr nützlich, aber schwierig zu konfigurieren und richtig zu verwenden.

Sie möchten auch wissen, ob sich die Site geändert hat. Wenn sie die Site neu gestaltet haben und Ihr Crawler defekt ist, bestehen Ihre Komponententests immer noch, da sie gegen eine zwischengespeicherte Kopie ausgeführt werden! Sie benötigen entweder einen weiteren, kleineren Satz von Integrationstests, die selten für die Live-Site ausgeführt werden, oder eine gute Protokollierung und Fehlererkennung in Ihrem Crawler-Code, der die genauen Probleme protokolliert, Sie auf das Problem hinweist und das Crawlen beendet. Jetzt können Sie Ihren Cache aktualisieren, Ihre Komponententests ausführen und sehen, was Sie ändern müssen.

Rechtsfragen

Das Gesetz hier kann etwas gefährlich sein, wenn Sie dumme Dinge tun. Wenn sich das Gesetz einmischt, haben Sie es mit Leuten zu tun, die wget and curl regelmäßig als "Hacking-Tools" bezeichnen. Das willst du nicht.

Die ethische Realität der Situation ist, dass es keinen Unterschied zwischen der Verwendung von Browsersoftware zum Anfordern einer URL und dem Anzeigen einiger Daten und der Verwendung Ihrer eigenen Software zum Anfordern einer URL und zum Anzeigen einiger Daten gibt. Google ist das größte Scraping-Unternehmen der Welt und sie werden dafür geliebt. Das Erkennen des Namens Ihres Bots im Benutzeragenten und die Offenheit für die Ziele und Absichten Ihres Webcrawlers helfen hier, da das Gesetz versteht, was Google ist. Wenn Sie etwas Schattiges tun, z. B. gefälschte Benutzerkonten erstellen oder auf Bereiche der Website zugreifen, die Sie nicht sollten (entweder durch robots.txt "blockiert" oder aufgrund eines Autorisierungs-Exploits), müssen Sie sich darüber im Klaren sein, dass Sie etwas Unethisches tun und die Unkenntnis des Gesetzes über Technologie wird hier außerordentlich gefährlich sein. Es ist eine lächerliche Situation, aber es ist eine echte.

Es ist buchstäblich möglich, als aufstrebender Bürger eine neue Suchmaschine aufzubauen, einen Fehler zu machen oder einen Fehler in Ihrer Software zu haben und als Hacker gesehen zu werden. Nicht etwas, das Sie angesichts der aktuellen politischen Realität wollen.

Wer soll ich überhaupt diese riesige Textwand schreiben?

Ich habe in meinem Leben viel Code im Zusammenhang mit Webcrawling geschrieben. Ich mache seit mehr als einem Jahrzehnt als Berater, Mitarbeiter und Gründer eines Startups webbezogene Softwareentwicklung. Die frühen Tage waren das Schreiben von Perl-Crawlern / Scrapern und PHP-Websites. Als wir versteckte Iframes einbetteten, die CSV-Daten in Webseiten luden, um Ajax zu machen, bevor Jesse James Garrett sie Ajax nannte, bevor XMLHTTPRequest eine Idee war. Vor jQuery, vor json. Ich bin Mitte 30, das gilt anscheinend als uralt für dieses Geschäft.

Ich habe zweimal große Crawler- / Scraping-Systeme geschrieben, einmal für ein großes Team eines Medienunternehmens (in Perl) und kürzlich für ein kleines Team als CTO eines Suchmaschinen-Startups (in Python / Javascript). Ich arbeite derzeit als Berater und programmiere hauptsächlich in Clojure / Clojurescript (eine wunderbare Fachsprache im Allgemeinen und hat Bibliotheken, die Crawler- / Scraper-Probleme zu einer Freude machen).

Ich habe auch erfolgreiche Anti-Crawler-Softwaresysteme geschrieben. Es ist bemerkenswert einfach, nahezu unbeschreibliche Websites zu schreiben, wenn Sie Bots identifizieren und sabotieren möchten, die Sie nicht mögen.

Ich schreibe lieber Crawler, Scraper und Parser als jede andere Art von Software. Es ist herausfordernd, macht Spaß und kann verwendet werden, um erstaunliche Dinge zu erschaffen.

Jesse Sherlock
quelle
4
Früher stimmte ich Ihnen zu, dass PHP eine schlechte Wahl ist, aber mit den richtigen Bibliotheken ist es nicht schlecht. Die Manipulation von Regex und Arrays / Stings ist ungeschickt, aber auf der positiven Seite ist es schnell und überall.
pguardiario
3
In einer Umgebung, in der es einige Bibliotheken gibt, die dies zu einem Vergnügen machen, und viele, die es ganz einfach und ganz einfach machen ... warum sollten Sie sich mit "nicht schlecht" zufrieden geben? Ich stimme zu, es ist in PHP (und FORTRAN, C, VB usw.) machbar, aber wenn Ihr Problem nicht wirklich einfach ist, wäre es eine viel bessere Idee, die richtigen Tools für den Job zu verwenden. Und wieder, es sei denn, Sie haben ein unglaublich einfaches Problem zu lösen ... was macht es aus, dass Regex überall ist? Das Installieren von Bibliotheken ist viel einfacher als fast jedes Scraping-Problem. Und tatsächlich ist Regex für dieses Problem oft ziemlich langsam.
Jesse Sherlock
5
Sie mögen Recht haben, aber ich weiß, dass ich es in PHP nicht so einfach machen kann. Bevor ich von PHP wegging, hatte ich fast ein Jahrzehnt Berufserfahrung in PHP. Ich habe mehr als ein Jahr lang in Python ein Scraping-System in großem Maßstab aufgebaut, und ich kann mir nicht vorstellen, auf einige der netten Bibliotheken zu verzichten, die in PHP nicht verfügbar sind, oder auf die prägnanten Meta-Programmiertechniken, die in Python verfügbar sind . Das ist auch der Grund, warum ich nach Clojure gezogen bin, um noch leistungsfähigere Metaprogrammierfähigkeiten zu erhalten.
Jesse Sherlock
4
Enlive sind neben der Leistung von Clojure selbst für projektspezifischen Code die größten Gewinner. Schema ist eine großartige Validierungsbibliothek, die einen so großen Teil des Informationsextraktionscodes ausmacht. Ich bin derzeit sehr zufrieden mit der einfachen Interaktion mit der Java-Welt für Dinge wie Mahout sowie Nashorn / Rhino für einige Arten der Ausführung von js. Und Clojure-Leute sind die Typen, die Bibliotheken wie diese schreiben: github.com/shriphani/subotai, damit Sie das nicht müssen. ... Fortsetzung im nächsten Kommentar ...
Jesse Sherlock
3
Ich habe auch festgestellt, dass es wirklich großartig ist, Clojurescript (häufig Code, der zwischen clj und cljs mit cljx geteilt wird) zu verwenden, um die js, die Sie in die Seite einfügen, anstelle von clojurescript zu schreiben, wenn Sie wirklich einen echten Browser benötigen und mit Phantomjs / Casperjs arbeiten müssen . Core.async eignet sich hervorragend zum Koordinieren von hochkonkurrierendem Crawling-Code auf dem Server sowie zum Verlassen der Callback-Hölle in der js-Umgebung (die Koordination der Browser-Automatisierung mit core.async cljs-Code in phantomjs ist im Vergleich zu den Alternativen der Himmel).
Jesse Sherlock
21

Ja, du kannst es selbst machen. Es geht nur darum, die Quellen der Seite zu erfassen und sie nach Ihren Wünschen zu analysieren.

Es gibt verschiedene Möglichkeiten. Eine gute Kombination ist die Verwendung von Python-Anfragen (die auf urllib2 basieren, urllib.requestin Python3) und BeautifulSoup4 , das über Methoden zum Auswählen von Elementen verfügt und auch CSS-Selektoren zulässt :

import requests
from BeautifulSoup4 import BeautifulSoup as bs
request = requests.get("http://foo.bar")
soup = bs(request.text) 
some_elements = soup.find_all("div", class_="myCssClass")

Einige bevorzugen xpath parsing oder jquery-like pyquery, lxml oder etwas anderes .

Wenn die gewünschten Daten von JavaScript erstellt werden , funktioniert das oben Gesagte nicht. Du brauchst entweder Python-Ghost oder Selen. Ich bevorzuge letzteres in Kombination mit PhantomJS , viel leichter und einfacher zu installieren und einfach zu bedienen:

from selenium import webdriver
client = webdriver.PhantomJS()
client.get("http://foo")
soup = bs(client.page_source)

Ich würde raten, Ihre eigene Lösung zu starten. Sie werden die Vorteile von Scrapy verstehen.

ps: schau mal rein: https://github.com/scrapy/scrapely

pps: Schauen Sie sich Portia an, um Informationen ohne Programmierkenntnisse visuell zu extrahieren: https://github.com/scrapinghub/portia

Ehvince
quelle
Okay, danke für die Antwort, das einzige Problem ist, dass Python nicht in meinen Fähigkeiten ist. Gibt es andere gute Programmiersprachen, die die gleichen Aufgaben erledigen könnten? Ich arbeite hauptsächlich mit PHP und Javascript.
0x1ad2
Entschuldigen Sie die Verwirrung (ich habe das Python-Framework in meiner Frage erwähnt), aber wenn Python der beste Weg ist, könnte ich es lernen.
0x1ad2
Python macht Scrapy sehr einfach. Es ist auch leicht zu lernen. Der beste Schaber, der im Moment gut funktioniert, ist kratzig. Sie haben auch eine sehr gute Dokumentation.
Abhishek