Heim BlogWeb-Scraping Wie man Forex-Märkte mit schöner Suppe durchkämmt

Wie man Forex-Märkte mit schöner Suppe durchkämmt

von Kadek

Forex, auch Devisenhandel genannt, ist ein internationaler Markt, auf dem Menschen verschiedene Währungen elektronisch außerbörslich (OTC) handeln – mit der Besonderheit, dass es keinen zentralen Marktplatz gibt.

Es ist ein bisschen so, als würde man Geld tauschen, wenn man in den Urlaub fährt, nur dass (auf dem Devisenmarkt) Menschen Währungen kaufen und verkaufen, um von Wertänderungen zu profitieren.

Menschen aus aller Welt handeln rund um die Uhr, fünf Tage die Woche, mit Währungen, was ihn zu einem der größten Finanzmärkte der Welt macht. Und wie bei jeder finanziellen Entscheidung helfen Ihnen die richtigen Daten dabei, genaue und profitable Investitionen zu tätigen.

Der Forex-Markt unterliegt starken Schwankungen. Daher verschafft Ihnen die Vorhersage potenzieller Aufwärts- oder Abwärtsbewegungen einen unfairen Vorteil und erzielt die gewünschten Ergebnisse.

In diesem Artikel extrahieren wir Währungsdaten aus Yahoo Finance mit Pythons Requests und Beautiful Soup und exportieren sie mit Pandas in eine CSV-Datei.

TL;DR über das Scraping von Forex-Daten mit Beautiful Soup (BS4)

Für diejenigen mit Erfahrung gibt es hier die vollständige Codebasis:

import requests
from bs4 import BeautifulSoup
import pandas as pd

forex_data = ()

payload = {
   'api_key': 'YOUR_API_KEY',
   'country_code': 'us',
   'url': 'https://finance.yahoo.com/currencies'
}

response = requests.get('https://api.scraperapi.com', params=payload)
soup = BeautifulSoup(response.content, 'html.parser')

table = soup.find('tbody')
all_currencies = table.select('tr')
for currency in all_currencies:
   name =  currency.find('td', attrs={'aria-label': 'Name'}).text
   last_price = currency.select_one('td(aria-label="Last Price")').text
   change = currency.find('td', attrs={'aria-label': 'Change'}).text
   percentage = currency.select_one('td(aria-label="% Change") > fin-streamer > span').text
   forex_data.append({
       'Currency': name,
       'Last Price': last_price,
       'Change': change,
       '% Change': percentage
   })

df = pd.DataFrame(forex_data)
df.to_csv('forex.csv', index=False)

Um zu erfahren, wie wir es aufgebaut haben und welchen Denkprozess dahinter steckt, lesen Sie bitte weiter.

1. Grundlegendes zur HTML-Struktur von Yahoo Finance

Bevor wir mit dem Codieren beginnen, werfen wir zunächst einen Blick auf die Währungsseite von Yahoo, um zu verstehen, womit wir es zu tun haben.

Grundlegendes zur HTML-Struktur von Yahoo FinanceGrundlegendes zur HTML-Struktur von Yahoo Finance

Die verfügbaren Währungen auf der Seite scheinen zumindest optisch in einem Tabellenformat angezeigt zu werden.

An dieser Stelle müssen wir zwei Dinge überprüfen:

  1. Stellen Sie sicher, dass wir aus der rohen HTML-Datei auf diese Daten zugreifen können – mit anderen Worten, dass der Inhalt nicht über AJAX eingefügt wird.
  2. Stellen Sie sicher, dass der HTML-Code auch als Tabelle strukturiert ist.

Um Nummer eins zu erledigen, kopieren Sie einen der Währungsnamen und klicken Sie mit der rechten Maustaste auf die Seite > Seitenquelle anzeigen.

Grundlegendes zur HTML-Struktur von Yahoo FinanceGrundlegendes zur HTML-Struktur von Yahoo Finance

Jetzt suchen wir nach dem Text, den wir kopiert haben. Wenn es im Quellcode erscheint, können wir die Daten mit einer einfachen Anfrage extrahieren.

Grundlegendes zur HTML-Struktur von Yahoo FinanceGrundlegendes zur HTML-Struktur von Yahoo Finance

Super, wir haben es gefunden! Diese Prüfung ist wichtig, denn wenn der Inhalt über JavaScript eingefügt wird, müssen wir einen anderen Ansatz wählen. Wir könnten beispielsweise auf die „versteckte API“ abzielen, von der die Seite die Daten erhält, wie wir es beim Scrapen dieser dynamischen Tabelle getan haben, oder wir könnten auch einen Headless-Browser wie Selenium oder Puppeteer (Option Node.js) verwenden.

Bei der zweiten Überprüfung werden Sie überrascht sein, wie oft Websites Tabellen ohne das Traditionelle anzeigen table > thead > tbody > tr > td Wenn Sie also eine Tabelle wie diese finden, überprüfen Sie vor dem Feiern immer den HTML-Code im Browser.

Grundlegendes zur HTML-Struktur von Yahoo FinanceGrundlegendes zur HTML-Struktur von Yahoo Finance

Weitere tolle Neuigkeiten! Die Daten in einer gut strukturierten Tabelle zu haben, erleichtert den gesamten Prozess und wir könnten mit Pandas sogar die gesamte Tabelle extrahieren. In diesem Tutorial verwenden wir jedoch BS4 zum Parsen der Tabelle und verwenden Pandas nur zum Exportieren der Ergebnisse.

Weiter geht's. Jedes tr-Tag stellt eine Zeile in der Tabelle dar – die Sie visuell sehen können, indem Sie mit der Maus darüber fahren.

Grundlegendes zur HTML-Struktur von Yahoo FinanceGrundlegendes zur HTML-Struktur von Yahoo Finance

Jede Zelle wird durch ein td-Tag dargestellt…

Grundlegendes zur HTML-Struktur von Yahoo FinanceGrundlegendes zur HTML-Struktur von Yahoo Finance

… und alle Zeilen befinden sich innerhalb des tbody-Tags.

Grundlegendes zur HTML-Struktur von Yahoo FinanceGrundlegendes zur HTML-Struktur von Yahoo Finance

Das wissend. Ein guter Plan wäre, auf den Körper zu zielen und dann alle Zeilen in einer Variablen zu speichern. Dann können wir die Liste der Zeilen durchlaufen und den Namen, den letzten Preis, die Änderung und die prozentuale Änderung jeder Währung extrahieren.

Nachdem wir nun unseren Spielplan haben, programmieren wir unseren Scraper!

2. Starten des Forex-Datenextraktionsprojekts

Erstellen wir zunächst ein neues Verzeichnis für unser Projekt und unsere Python-Datei. Wir haben unsere forex_scraper.py genannt – sehr originell, oder?

Als nächstes importieren wir alle notwendigen Abhängigkeiten:

import requests
from bs4 import BeautifulSoup
import pandas as pd

Nachdem unsere Abhängigkeiten fertig sind, ist es an der Zeit, unsere Initialen zu senden get() Anfrage. Obwohl Yahoo Finance über viele öffentliche Daten verfügt, heißt das nicht, dass sie nicht versuchen werden, Ihre Skripte zu blockieren. Wenn Sie Ihre Anfrage direkt von Ihrem Computer aus senden, kann dies dazu führen, dass Ihre IP vorübergehend oder sogar dauerhaft gesperrt wird.

Um dieses Problem zu vermeiden, verwenden wir ScraperAPI, um alle gefundenen Anti-Scraping-Mechanismen zu umgehen und sicherzustellen, dass wir eine erfolgreiche Antwort vom Server erhalten. Machen Sie sich an dieser Stelle keine Gedanken über die Preise, denn der kostenlose Plan bietet Ihnen 5.000 API-Credits für die ersten 7 Tage und 1.000 API-Credits pro Monat.

Erstellen Sie einfach ein kostenloses ScraperAPI-Konto und kopieren Sie Ihren API-Schlüssel. Wir übergeben dann den Schlüssel und unsere Ziel-URL über eine Nutzlast, die als Parameter zum Endpunkt von ScraperAPI hinzugefügt wird:

payload = {
   'api_key': 'YOUR_API_KEY',
   'country_code': 'us',
   'url': 'https://finance.yahoo.com/currencies'
}

response = requests.get('https://api.scraperapi.com', params=payload)

Außerdem verwenden wir die country_code Parameter, um ScraperAPI anzuweisen, beim Senden unserer Anfragen immer US-Proxys zu verwenden.

Um eine Erfolgsquote von 99,99 % zu gewährleisten, nutzt ScraperAPI maschinelles Lernen und jahrelange statistische Analysen, um die beste Kombination aus IP und Headern auszuwählen und etwaige zusätzliche Komplexitäten zu bewältigen.

Da wir nichts weiter hinzuzufügen haben, senden wir die Anfrage und print() den Statuscode, um zu überprüfen, ob es funktioniert, indem Sie:

print(response.status_code)

Nachdem Sie das Skript ausgeführt haben, sollte in Ihrem Terminal eine 200 angezeigt werden.

3. Zugriff auf Daten aus der ersten Zelle

Wenn Sie dem folgen, gibt das Skript an dieser Stelle den gesamten Roh-HTML-Code zurück – Sie können ihn sehen, wenn Sie (response) anstelle des status_code ausgeben – wir müssen ihn also mit Beautiful Soup analysieren, um ihn in einen analysierten Code umzuwandeln Baum, der es uns ermöglicht, die verschiedenen Knoten zu durchlaufen und die Daten zu extrahieren.

soup = BeautifulSoup(response.content, 'html.parser'

Jetzt befinden sich alle Knoten in einem Suppenobjekt, auf das wir das verwenden können .find() Und .select() Methoden zur gezielten Ausrichtung auf bestimmte Elemente. Nach dem Plan wählen wir nun den Körper des Tisches aus, der dazwischen gewickelt wird

tags.

table = soup.find('tbody')

.find() gibt das erste gefundene Element zurück, und da es nur ein tbody-Element gibt, funktioniert es für uns einwandfrei.

Im Fall der Zeilen möchten wir, dass unser Skript eine Liste mit allen zurückgibt tr Elemente und nicht nur das erste, also werden wir es verwenden .select() – das eine Liste aller Elemente zurückgibt, die den von uns übergebenen Kriterien entsprechen – in unserer Tabellenvariablen.

all_currencies = table.select('tr')

Notiz: wir könnten auch das nutzen .find_all() Methode, aber wir wollen zeigen, wie man beide verwendet.

Nachdem wir nun unsere Zeilenliste haben, können wir jede Zelle durchlaufen und Daten daraus extrahieren. Das heißt, jede Zelle ist eine td Element, wie können wir unserem Scraper also mitteilen, aus welchen Zellen er die Daten extrahieren soll?

Wenn Sie die Struktur richtig verstanden haben, alle

has a series of

tags. So we can imagine each row like this:

Zugriff auf Daten aus der ersten ZelleZugriff auf Daten aus der ersten Zelle

Jedes Rechteck ist ein td Element, und die Liste beginnt bei 0. Theoretisch könnten Sie alle td-Tags innerhalb der Zeile als Ziel verwenden und dann jede Spalte anhand ihrer Position im Index auswählen.

Zum Glück offenbart uns eine nähere Betrachtung der Elemente einen einfacheren Weg. Alle Elemente innerhalb der Zeilen haben ein aria-label Attribut mit einem sehr beschreibenden Wert.

Zugriff auf Daten aus der ersten ZelleZugriff auf Daten aus der ersten Zelle

Beispielsweise hat das Währungspaar den Wert „Name“ und der letzte Preis darunter den Wert „Letzter Preis“. Um den Namen jeder Währung anzusprechen, können wir eine Schleife wie diese erstellen:

for currency in all_currencies:
   name =  currency.find('td', attrs={'aria-label': 'Name'}).text
   print(name)

Sie erhalten eine Liste mit 24 Währungen auf Ihrem Terminal ausgedruckt, was bedeutet, dass unser Skript bisher funktioniert!

4. Alle Daten zu einem Array hinzufügen

Die Ausrichtung auf die restlichen Datenpunkte erfolgt nach einem sehr ähnlichen Prozess, jedoch mit einigen geringfügigen Änderungen.

Im Gegensatz zum Währungsnamen befindet sich der Text der Zellen „Letzter Preis“ in einem anderen – seltsam aussehenden – Element innerhalb der Währung td.

Alle Daten zu einem Array hinzufügenAlle Daten zu einem Array hinzufügen

Bei Verwendung des .find() Methode, es gab das Element zurück, aber wir konnten die Daten damit nicht extrahieren .text. Stattdessen haben wir die verwendet select_one() Methode, die eine etwas andere Syntax verwendet, um auf ein einzelnes Element abzuzielen, und es hat funktioniert:

   last_price = currency.select_one('td(aria-label="Last Price")').text

Für die Spalte „Änderung“ haben wir die gleiche Methode wie für „Name“ verwendet:

   change = currency.find('td', attrs={'aria-label': 'Change'}).text

Und schließlich mussten wir bei der prozentualen Änderung etwas kreativer werden, um das Ziel zu erreichen span Element, in dem der Text bereitgestellt wird, ohne dass eine Menge geschrieben werden muss .find() Methoden:

   percentage = currency.select_one('td(aria-label="% Change") > fin-streamer > span').text

Notiz: Achten Sie auf die Unterschiede zwischen den find() Und select() Methoden, da sie Ihr Hauptwerkzeug zum einfachen Extrahieren von Daten mithilfe von CSS-Selektoren sind.

Da alle Daten von unserem Parser abgerufen werden, fügen wir vor der Nutzlast ein leeres Array hinzu ...

… und nutzen Sie die .append() Methode zum Formatieren und Speichern aller Daten in forex_data:

   forex_data.append({
       'Currency': name,
       'Last Price': last_price,
       'Change': change,
       '% Change': percentage
   })

Dieses letzte Snippet wird in die for-Schleife eingefügt, nachdem das letzte Element extrahiert wurde. Im Grunde extrahiert unser Skript jedes Element und hängt es dann an das Array an, wobei jedes Element einen Namen hat und das Ganze ein einzelnes Element bildet.

Folgendes erhalten wir nach dem Drucken des Arrays:

(
   {
      "Currency":"EUR/USD",
      "Last Price":"1.1031",
      "Change":"-0.0018",
      "% Change":"-0.17%"
   },

   {
      "Currency":"USD/JPY",
      "Last Price":"133.9490",
      "Change":"+0.3320",
      "% Change":"+0.25%"
   },

   {
      "Currency":"USD/GBP",
      "Last Price":"1.2495",
      "Change":"+0.0030",
      "% Change":"+0.24%"
   },

   {
      "Currency":"USD/AUD",
      "Last Price":"0.6630",
      "Change":"+0.0024",
      "% Change":"+0.36%"
   },

   {
      "Currency":"USD/NZD",
      "Last Price":"0.6148",
      "Change":"+0.0029",
      "% Change":"+0.48%"
   },

   {
      "Currency":"EUR/JPY",
      "Last Price":"147.6980",
      "Change":"+0.2040",
      "% Change":"+0.14%"
   },

   {
      "Currency":"GBP/JPY",
      "Last Price":"167.3310",
      "Change":"+0.7770",
      "% Change":"+0.47%"
   },

   {
      "Currency":"EUR/GBP",
      "Last Price":"0.8826",
      "Change":"-0.0027",
      "% Change":"-0.31%"
   },

   {
      "Currency":"EUR/CAD",
      "Last Price":"1.4996",
      "Change":"-0.0051",
      "% Change":"-0.34%"
   },

   {
      "Currency":"EUR/SEK",
      "Last Price":"11.3484",
      "Change":"-0.0526",
      "% Change":"-0.46%"
   },

   {
      "Currency":"EUR/CHF",
      "Last Price":"0.9858",
      "Change":"+0.0024",
      "% Change":"+0.24%"
   },

   {
      "Currency":"EUR/HUF",
      "Last Price":"373.0700",
      "Change":"-0.7500",
      "% Change":"-0.20%"
   },

   {
      "Currency":"EUR/JPY",
      "Last Price":"147.6980",
      "Change":"+0.2040",
      "% Change":"+0.14%"
   },

   {
      "Currency":"USD/CNY",
      "Last Price":"6.9215",
      "Change":"-0.0041",
      "% Change":"-0.06%"
   },

   {
      "Currency":"USD/HKD",
      "Last Price":"7.8495",
      "Change":"+0.0009",
      "% Change":"+0.01%"
   },

   {
      "Currency":"USD/SGD",
      "Last Price":"1.3348",
      "Change":"-0.0005",
      "% Change":"-0.03%"
   },

   {
      "Currency":"USD/INR",
      "Last Price":"81.6850",
      "Change":"-0.0350",
      "% Change":"-0.04%"
   },

   {
      "Currency":"USD/MXN",
      "Last Price":"18.0482",
      "Change":"-0.0895",
      "% Change":"-0.49%"
   },

   {
      "Currency":"USD/PHP",
      "Last Price":"55.7100",
      "Change":"+0.0500",
      "% Change":"+0.09%"
   },

   {
      "Currency":"USD/IDR",
      "Last Price":"14,699.0000",
      "Change":"-130.0000",
      "% Change":"-0.88%"
   },

   {
      "Currency":"USD/THB",
      "Last Price":"34.0600",
      "Change":"+0.1450",
      "% Change":"+0.43%"
   },

   {
      "Currency":"USD/MYR",
      "Last Price":"4.4600",
      "Change":"+0.0050",
      "% Change":"+0.11%"
   },

   {
      "Currency":"USD/ZAR",
      "Last Price":"18.2845",
      "Change":"-0.1103",
      "% Change":"-0.60%"
   },

   {
      "Currency":"USD/RUB",
      "Last Price":"80.5300",
      "Change":"-1.5710",
      "% Change":"-1.91%"
   }

)

Notiz: Wir haben einen JSON-Formatierer verwendet, um das Ergebnis visuell zu organisieren, da es in Ihrem Terminal ausgedruckt nicht so aussieht. Dennoch kommt es auf die Name:Wert-Organisation an.

5. Exportieren der gecrackten Forex-Finanzdaten in eine CSV-Datei

Hier wird sich unsere Initiative, die Daten in einem Array zu speichern, auszahlen! Da wir die Reihenfolge und alle Informationen bereits in forex_data haben, können wir einfach einen Datenrahmen mit Pandas erstellen:

df = pd.DataFrame(forex_data)

Die Namen werden zu Spalten und jeder Datenpunkt wird unter dem bereits angegebenen liegen.

Für die letzte Berührung verwenden wir die .to_csv() Methode zum Erstellen der Datei im Verzeichnis unseres Projekts:

df.to_csv('forex.csv', index=False)

Wenn Sie mitgemacht haben, sollte Ihr Projekt so aussehen:

import requests
from bs4 import BeautifulSoup
import pandas as pd

forex_data = ()

payload = {
   'api_key': 'YOUR_API_KEY',
   'country_code': 'us',
   'url': 'https://finance.yahoo.com/currencies'
}

response = requests.get('https://api.scraperapi.com', params=payload)
soup = BeautifulSoup(response.content, 'html.parser')

table = soup.find('tbody')
all_currencies = table.select('tr')
for currency in all_currencies:
   name =  currency.find('td', attrs={'aria-label': 'Name'}).text
   last_price = currency.select_one('td(aria-label="Last Price")').text
   change = currency.find('td', attrs={'aria-label': 'Change'}).text
   percentage = currency.select_one('td(aria-label="% Change") > fin-streamer > span').text
   forex_data.append({
       'Currency': name,
       'Last Price': last_price,
       'Change': change,
       '% Change': percentage
   })

df = pd.DataFrame(forex_data)
df.to_csv('forex.csv', index=False)

Nachdem Sie dieses Skript ausgeführt haben, finden Sie die folgende CSV-Datei:

Exportieren der Daten in eine CSV-DateiExportieren der Daten in eine CSV-Datei

Sammeln Sie Forex-Finanzdaten automatisch mit ScraperAPI

Herzlichen Glückwunsch, Sie haben Ihren ersten Forex-Scraper gebaut! Wir hoffen, dass Ihnen dieses Web-Scraping-Tutorial genauso viel Spaß gemacht hat wie uns das Schreiben. Natürlich ist das erst der Anfang.

Wenn Sie beide Male, als wir Ihnen die Ergebnisse angezeigt haben, aufmerksam gemacht haben, sind die Werte für jedes Währungspaar unterschiedlich. Das liegt daran, dass Yahoo Finance die Preise auf der Seite ständig aktualisiert, sodass Sie bei jeder Anfrage einen leicht unterschiedlichen Wert erhalten.

Mit anderen Worten: Der nächste Schritt auf diesem Weg besteht darin, einen Web-Scraping-Planer so einzurichten, dass das Skript einige Male am Tag oder in der Woche automatisch ausgeführt wird. Auf diese Weise können Sie mit der Erstellung historischer Daten beginnen, die Sie in Ihre Handelsalgorithmen einspeisen können.

Ihre Web-Scraping-Lösung bietet keine automatische Scraping-Funktion? Schauen Sie sich ScraperAPI an. Mit unserer DataPipeline-Lösung können Sie bis zu 10.000 URLs termingerecht erfassen und Benachrichtigungen erhalten, wenn die Aufgaben erledigt sind. Melden Sie sich hier bei ScraperAPI an, um es auszuprobieren.

Die DataPipeline von ScraperAPI zum Scrapen von Forex-DatenDie DataPipeline von ScraperAPI zum Scrapen von Forex-Daten

Darüber hinaus können Sie diese Informationen auch vergleichen, indem Sie andere Forex-Datenquellen wie TradingView auswerten. Denken Sie daran: Je mehr Daten Sie haben, desto bessere Vorhersagen können Sie treffen. Beginnen Sie also jetzt mit der Erstellung.

Bis zum nächsten Mal, viel Spaß beim Schaben!

Related Posts

Hinterlasse einen Kommentar