Der ultimative Leitfaden zum Start von Web Scraping mit Elixir

Suciu Dan am 18. Oktober 2022

Einführung

Unter Web Scraping versteht man das Extrahieren von Daten aus öffentlich zugänglichen Websites wie Foren, Social-Media-Sites, Nachrichtensites, E-Commerce-Plattformen usw. Um Ihnen einen Vorgeschmack auf das zu geben, was Sie heute bauen werden, beschreibt dieser Artikel die Erstellung eines Web Scrapers in Elixir.

Falls Ihnen die Definition von Web Scraping noch nicht klar ist, betrachten wir das Speichern eines Bildes von einer Website als manuelles Web Scraping. Wenn Sie alle Bilder einer Website von Hand speichern wollen, kann dies je nach Komplexität der Website Stunden oder sogar Tage dauern. 

Sie können diesen Prozess automatisieren, indem Sie einen Web Scraper entwickeln.

Vielleicht fragen Sie sich, für welche Zwecke ein Web Scraper eingesetzt werden kann. Hier sind die häufigsten:

Nachrichtenverfolgung

Sie können die neuesten Nachrichten von Ihrer bevorzugten Finanznachrichtenseite abrufen, einen Stimmungsanalysealgorithmus ausführen und wissen, in was Sie investieren sollten, Minuten bevor der Markt beginnt und sich bewegt

Einblicke in soziale Medien

Sie können die Kommentare auf Ihren Social-Media-Seiten auslesen und analysieren, worüber Ihre Abonnenten sprechen und wie sie über Ihr Produkt oder Ihre Dienstleistung denken.

Preisüberwachung

Wenn Ihre Leidenschaft das Sammeln von Konsolen und Videospielen ist, Sie aber kein Vermögen für die neueste PS5 ausgeben wollen, können Sie einen Web Scraper erstellen, der die eBay-Angebote abruft und Ihnen eine Benachrichtigung schickt, wenn eine günstige Konsole auf dem Markt ist.

Ausbildung im maschinellen Lernen

Wenn Sie eine mobile Anwendung erstellen möchten, die die Rasse einer Katze auf einem beliebigen Bild erkennen kann, benötigen Sie eine Menge Trainingsdaten. Anstatt Hunderttausende von Bildern mit Katzen manuell zu speichern, um das Modell zu trainieren, können Sie einen Web Scraper verwenden, um dies automatisch zu tun.

Wir werden unseren Web Scraper in Elixir entwickeln, einer Programmiersprache, die auf Erlang aufbaut und von José Valim, einem Mitglied des Kernteams von Ruby on Rails, entwickelt wurde. Die Programmiersprache leiht sich die Einfachheit der Ruby-Syntax und kombiniert sie mit der Fähigkeit von Erlang, Systeme mit niedriger Latenz, verteilte und fehlertolerante Systeme zu erstellen.

Anforderungen

Bevor Sie die erste Codezeile schreiben, stellen Sie sicher, dass Sie Elixir auf Ihrem Computer installiert haben. Laden Sie das Installationsprogramm für Ihr Betriebssystem herunter und folgen Sie den Anweisungen auf der Seite Installieren

Während der Installation werden Sie feststellen, dass auch die Programmiersprache Erlang erforderlich ist. Denken Sie daran, dass Elixir in der Erlang-VM läuft, Sie brauchen also beides.

Erste Schritte

In diesem Artikel erfahren Sie, wie Sie einen Web Scraper in Elixir erstellen, die Produkte von eBay für PS5-Listings scrapen und die extrahierten Daten (Name, URL, Preis) lokal speichern.

Inspektion der Zielscheibe

Nun ist es an der Zeit, die Suchergebnisse auf der eBay-Seite zu prüfen und einige Selektoren zu sammeln.

Gehen Sie zu ebay.com, geben Sie den Begriff PS5 in die Sucheingabe ein und klicken Sie auf die Schaltfläche Suchen. Sobald die Seite mit den Suchergebnissen geladen ist, öffnen Sie das Tool "Inspect" in Ihrem Browser (klicken Sie mit der rechten Maustaste auf eine beliebige Stelle der Seite und wählen Sie "Inspect").

Sie müssen die folgenden Selektoren sammeln:

  • Produktliste Artikel
  • Produkt-URL
  • Name des Produkts
  • Preis des Produkts

Verwenden Sie das Werkzeug "Element auswählen" und suchen Sie nach der Produktliste (ul) und dem Produktartikel (li):

blog-image

Anhand dieser beiden Elemente können Sie die Klassen extrahieren, die der Crawler für die Datenextraktion benötigt:

  • .srp-results .s-item die untergeordneten Elemente des Listenelements products (ul)
  • .s-item__title span der Produkttitel
  • .s-item__link der Produktlink
  • .s-item__price der Produktpreis

Erstellen des Projekts

Lassen Sie uns ein Elixir-Projekt mit dem Befehl mix erstellen:

mix new elixir_spider --sup

Das Flag --sup erzeugt ein OTP-Anwendungsskelett einschließlich eines Überwachungsbaums, eine notwendige Funktion für eine Anwendung, die mehrere gleichzeitige Prozesse wie einen Crawler verwaltet.

Erstellen des temporären Ordners

Wechseln Sie das aktuelle Verzeichnis in das Stammverzeichnis des Projekts:

cd elixir_spider

Erstellen Sie das temporäre Verzeichnis:

mkdir temp

Wir verwenden dieses Verzeichnis, um die gescrapten Elemente zu speichern.

Hinzufügen der Abhängigkeiten

Nachdem das Projekt erstellt wurde, müssen Sie die beiden Abhängigkeiten hinzufügen:

  • Crawly ist ein Anwendungsrahmen für das Crawlen von Websites und die Extraktion strukturierter Daten
  • Floki ist ein HTML-Parser, der die Suche nach Knoten mit CSS-Selektoren ermöglicht

Öffnen Sie die Datei mix.exs und fügen Sie die Abhängigkeiten in den deps-Block ein:

defp deps do
[
{:crawly, "~> 0.14.0"},
{:floki, "~> 0.33.1"}
]
end

Holen Sie die Abhängigkeiten, indem Sie diesen Befehl ausführen:

mix deps.get

Erstellen Sie die Konfiguration

Erstellen Sie die Datei config/config.exs und fügen Sie diese Konfiguration darin ein:

import Config

config :crawly,
closespider_timeout: 10,
concurrent_requests_per_domain: 8,
closespider_itemcount: 100,

middlewares: [
Crawly.Middlewares.DomainFilter,
Crawly.Middlewares.UniqueRequest,
{Crawly.Middlewares.UserAgent, user_agents: ["Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:105.0) Gecko/20100101 Firefox/105.0"]}
],
pipelines: [
{Crawly.Pipelines.Validate, fields: [:url, :title, :price]},
{Crawly.Pipelines.DuplicatesFilter, item_id: :title},
Crawly.Pipelines.JSONEncoder,
{Crawly.Pipelines.WriteToFile, extension: "jl", folder: "./temp"}
]

Allgemeine Optionen

Gehen wir die einzelnen Eigenschaften durch und machen wir uns ein Bild von ihnen:

  • closespider_timeout: Ganzzahl, die maximale Anzahl von Sekunden, die der Spider geöffnet bleibt
  • concurrent_requests_per_domain: die maximale Anzahl der Anfragen, die für jede gescrapte Domain gestellt werden
  • closespider_itemcount: die maximale Anzahl der Elemente, die von der Element-Pipeline übergeben werden

Benutzer-Agent

Wenn Sie den Benutzeragenten einstellen, verbessern Sie die Scraping-Ergebnisse, indem Sie einen echten Browser imitieren. Websites sind nicht glücklich über Scraper und versuchen, alle User-Agents zu blockieren, die nicht echt erscheinen. Sie können ein Tool wie dieses verwenden, um Ihren Browser-Benutzeragenten zu ermitteln.

WebScrapingAPI rotiert den User-Agent und die IP-Adresse bei jeder Anfrage und implementiert außerdem unzählige Ausweichmöglichkeiten, um diese Art von Situation zu verhindern. Ihre Anfragen werden nicht blockiert und die Implementierung eines Wiederholungsmechanismus liefert Ihnen amazon-Ergebnisse.

Pipelines

Die Pipelines sind Befehle, die von oben nach unten abgearbeitet werden und die Manipulation der verarbeiteten Elemente ermöglichen. Wir verwenden die folgenden Pipelines:

  • Felder validieren (Titel, Preis, URL): prüft, ob der Artikel die ausgewerteten Felder enthält
  • Duplikat-Filter: prüft auf doppelte Artikel nach Titel
  • JSON-Encoder: kodiert die Strukturen in ein JSON-Objekt
  • In Datei schreiben: schreibt die Elemente in den Ordner ./temp

Erstellen der Spinne

Ein Web-Crawler oder Spider ist eine Art Bot, der eine Website durchsucht und Daten anhand von benutzerdefinierten Feldern über CSS-Selektoren extrahiert. Ein Crawler kann alle Links einer Seite extrahieren und bestimmte Links (z. B. Paginierungslinks) verwenden, um weitere Daten zu sammeln. 

Es ist an der Zeit, die Basis für den Crawler zu setzen: Erstellen Sie die Datei ebay_scraper.ex im Ordner lib/elixir_spider und fügen Sie den folgenden Code darin ein:

# lib/elixir_spider/ebay.ex
defmodule EbayScraper do
use Crawly.Spider

@impl Crawly.Spider
def base_url(), do: ""

@impl Crawly.Spider
def init() do

end

@impl Crawly.Spider
def parse_item(response) do

end
end

Dies ist nur das Grundgerüst für die Datei, die nicht ausgeführt wird und keine Ergebnisse liefert. Lassen Sie uns zuerst über jede Funktion sprechen und sie dann nacheinander ausfüllen.

Die Funktion base_url() wird einmal aufgerufen und liefert die Basis-URL für die Ziel-Website, die der Crawler durchsuchen wird; sie wird auch verwendet, um externe Links zu filtern und zu verhindern, dass der Crawler ihnen folgt. Sie wollen nicht das gesamte Internet scrapen.

@impl Crawly.Spider
def base_url(), do: "https://www.ebay.com/"

Die init() -Funktion wird einmal aufgerufen und dient dazu, den Standardzustand für den Crawler zu initialisieren; in diesem Fall gibt die Funktion die start_url zurück, von der aus das Scraping beginnen wird.

Ersetzen Sie Ihre leere Funktion durch diese:

@impl Crawly.Spider
def init() do
[start_urls: ["https://www.ebay.com/sch/i.html?_nkw=ps5"]]
end

Der ganze Zauber der Datenextraktion geschieht in der Funktion parse_item(). Diese Funktion wird für jede abgefragte URL aufgerufen. Innerhalb dieser Funktion verwenden wir den Floki HTML-Parser, um die benötigten Felder zu extrahieren: Titel, URL und Preis.

Die Funktion wird wie folgt aussehen:

@impl Crawly.Spider
def parse_item(response) do
# Parse response body to document
{:ok, document} = Floki.parse_document(response.body)

# Create item (for pages where items exists)
items =
document
|> Floki.find(".srp-results .s-item")
|> Enum.map(fn x ->
%{
title: Floki.find(x, ".s-item__title span") |> Floki.text(),
price: Floki.find(x, ".s-item__price") |> Floki.text(),
url: Floki.find(x, ".s-item__link") |> Floki.attribute("href") |> Floki.text(),
}
end)

%{items: items}
end

Wie Sie vielleicht bemerkt haben, verwenden wir die Klassen, die wir im Abschnitt Erste Schritte - Inspektion des Ziels gefunden haben, um die benötigten Daten aus den DOM-Elementen zu extrahieren.

Der Betrieb der Spinne

Nun ist es an der Zeit, den Code zu testen und sicherzustellen, dass er funktioniert. Führen Sie im Stammverzeichnis des Projekts den folgenden Befehl aus:

iex -S mix run -e "Crawly.Engine.start_spider(EbayScraper)"

Wenn Sie PowerShell verwenden, stellen Sie sicher, dass Sie iex durch iex.bat ersetzen, da Sie sonst eine Fehlermeldung für den nicht vorhandenen Parameter -S erhalten. Verwenden Sie diesen Befehl für PowerShell:

iex.bat -S mix run -e "Crawly.Engine.start_spider(EbayScraper)"

Überprüfung der Ergebnisse

Öffnen Sie den Ordner ./temp und prüfen Sie die Datei .jl. Sie sollten eine Textdatei sehen, die eine Liste von JSON-Objekten enthält, eines pro Zeile. Jedes Objekt enthält die Informationen, die wir aus der eBay-Produktliste benötigen: Titel, Preis und URL.

So sollte das Produktobjekt aussehen:

{"url":"https://www.ebay.com/itm/204096893295?epid=19040936896&hash=item2f851f716f:g:3G8AAOSwNslhoSZW&amdata=enc%3AAQAHAAAA0Nq2ODU0vEdnTBtnKgiVKIcOMvqJDPem%2BrNHrG4nsY9c3Ny1bzsybI0zClPHX1w4URLWSfXWX%2FeKXpdgpOe%2BF8IO%2FCh77%2FycTnMxDQNr5JfvTQZTF4%2Fu450uJ3RC7c%2B9ze0JHQ%2BWrbWP4yvDJnsTTWmjSONi2Cw71QMP6BnpfHBkn2mNzJ7j3Y1%2FSTIqcZ%2F8akkVNhUT0SQN7%2FBD38ue9kiUNDw9YDTUI1PhY14VbXB6ZMWZkN4hCt6gCDCl5mM7ZRpfYiDaVjaWVCbxUIm3rIg%3D%7Ctkp%3ABFBMwpvFwvRg","title":"PS5 Sony PlayStation 5 Console Disc Version!  US VERSION!","price":"$669.99"}

Verbessern Sie die Spinne

Wir haben alle Produkte von der ersten Seite der Produktliste abgerufen, aber das ist nicht genug. Es ist an der Zeit, eine Paginierung zu implementieren und den Crawler alle verfügbaren Produkte extrahieren zu lassen.

Ändern Sie die Funktion parse_item() und fügen Sie einen neuen Block hinzu, der eine Request-Struktur mit dem nächsten Paginierungslink erstellt. Fügen Sie diesen Code nach dem items-Code ein:

# Extrahiere den Link zur nächsten Seite und wandle ihn in eine Anfrage um
requests =
document
|> Floki.find(".s-pagination a.pagination__next")
|> Floki.attribute("href")
|> Crawly.Utils.build_absolute_urls(response.request_url)
|> Crawly.Utils.requests_from_urls()

Aktualisieren Sie die Rückgabeanweisung der Funktion parse_item(), um auch die nächsten Anfragen aufzunehmen. Die Struktur sieht dann wie folgt aus:

%{
:requests => requests,
:items => items
}

Führen Sie den Crawler erneut aus, aber bereiten Sie diesmal einen Kaffee vor. Das Durchsuchen aller Seiten nach den PS5-Listen wird einige Minuten dauern.

Nachdem der Crawler seine Arbeit beendet hat, überprüfen Sie den Ordner ./temp auf die gesammelten Ergebnisse. Sie haben eBay erfolgreich nach PS5-Konsolen durchsucht und verfügen über eine Liste mit deren Preisen. Sie können diesen Crawler erweitern, um andere Produkte zu scrapen.

Schlussfolgerung

In diesem Artikel haben Sie gelernt, was ein Web Scraper ist, welche Anwendungsfälle diese Crawler haben, wie man mit Hilfe von bereits erstellten Bibliotheken einen Scraper mit Elixir in wenigen Minuten einrichten kann und wie man die eigentlichen Daten ausführt und extrahiert.

Wenn Sie das Gefühl hatten, dass dies eine Menge Arbeit war, möchte ich Ihnen eine nicht so gute Nachricht überbringen: Wir haben nur an der Oberfläche gekratzt. Wenn Sie diesen Scraper über einen längeren Zeitraum betreiben, werden Sie mehr Probleme bekommen, als Sie sich vorstellen können.

eBay wird Ihre Aktivität erkennen und sie als verdächtig einstufen; der Crawler wird Captcha-Felder erhalten; Sie müssen die Crawler-Funktionalität erweitern, um Captchas zu lösen

Die Erkennungssysteme von eBay könnten Ihre IP-Adresse markieren und Ihnen den Zugriff auf die Website verwehren; Sie müssen einen Proxy-Pool einrichten und die IP-Adressen bei jeder Anfrage wechseln. 

Dreht sich Ihnen schon der Kopf? Lassen Sie uns über ein weiteres Thema sprechen: den Benutzer-Agenten. Sie müssen eine große Datenbank mit Benutzer-Agenten aufbauen und diesen Wert bei jeder Anfrage ändern. Das Erkennungssystem blockiert Scraper auf der Grundlage der IP-Adresse und des User Agents.

Wenn Sie sich mehr auf die geschäftliche Seite konzentrieren und Ihre Zeit in die Datenextraktion investieren möchten, anstatt die Erkennungsprobleme zu lösen, ist ein Scraper als Service die bessere Wahl. Eine Lösung wie WebScrapingAPI behebt alle oben genannten Probleme und noch eine ganze Reihe mehr. 

Nachrichten und Aktualisierungen

Bleiben Sie auf dem Laufenden mit den neuesten Web Scraping-Anleitungen und Nachrichten, indem Sie unseren Newsletter abonnieren.

We care about the protection of your data. Read our <l>Privacy Policy</l>.Privacy Policy.

Ähnliche Artikel

Vorschaubild
Wissenschaft des Web ScrapingScrapy vs. Selenium: Ein umfassender Leitfaden zur Auswahl des besten Web-Scraping-Tools

Erforschen Sie den detaillierten Vergleich zwischen Scrapy und Selenium für Web Scraping. Von der Datenerfassung in großem Maßstab bis hin zum Umgang mit dynamischen Inhalten - entdecken Sie die Vor- und Nachteile sowie die einzigartigen Funktionen der beiden Frameworks. Erfahren Sie, wie Sie das beste Framework für die Anforderungen und den Umfang Ihres Projekts auswählen können.

WebscrapingAPI
Autorenavatar
WebscrapingAPI
14 Minuten lesen
Vorschaubild
LeitfädenScrapy Splash Tutorial: Die Kunst des Scrapings von JavaScript-gerenderten Websites mit Scrapy und Splash beherrschen

Lernen Sie, wie Sie mit Scrapy und Splash dynamische JavaScript-gerenderte Websites scrapen können. Von der Installation über das Schreiben eines Spiders bis hin zum Umgang mit Seitenumbrüchen und der Verwaltung von Splash-Antworten bietet dieser umfassende Leitfaden Schritt-für-Schritt-Anleitungen für Anfänger und Experten gleichermaßen.

Ștefan Răcila
Autorenavatar
Ștefan Răcila
6 Minuten lesen
Vorschaubild
LeitfädenDer ultimative Leitfaden für Online Job Scraping, seine Vor- und Nachteile

Definition und Verwendung von Online-Job-Scraping. Vor- und Nachteile von Job Scraping sowie Strategien und mögliche Risiken.

Suciu Dan
Autorenavatar
Suciu Dan
8 Minuten lesen