Verbesserung des Web Scraping mit großen Sprachmodellen: Eine moderne Herangehensweise

In meinen frühen Tagen als Data Engineer (das geht zurück bis 2016) hatte ich die Verantwortung, Daten von verschiedenen Websites zu scrapen. Web scraping dreht sich alles darum, Tools zu nutzen, die automatisiert sind, um große Mengen an Daten von Websites zu erhalten, normalerweise aus deren HTML.

I remember building around the application, digging into the HTML code, and trying to figure out the best solutions for scraping all the data. One of my main challenges was dealing with frequent changes to the websites: for example, the Amazon pages I was scraping changed every one to two weeks.

Eine Gedanken, die mir bei der Lektüre über Large Language Models (LLMs) kam, war: „Kann ich alle diese Fallstricke, die ich erlebt habe, um mit LLMs Daten aus Webseiten zu strukturieren, vermeiden?“

Lass uns sehen, ob ich es kann.

Web Scraping Tools und Techniken

Zu der Zeit verwendete ich hauptsächlich die Tools Requests, BeautifulSoup und Selenium. Jeder Dienst hat einen anderen Zweck und ist auf verschiedene Arten von Webumgebungen ausgerichtet.

  • Requests ist eine Python-Bibliothek, die zum einfachen Erstellen von HTTP-Anfragen verwendet werden kann. Diese Bibliothek führt GET- und POST-Operationen gegen URLs durch, die in den Anfragen bereitgestellt werden. Sie wird oft verwendet, um HTML-Inhalt zu holen, der von BeautifulSoup parsed werden kann.
  • BeautifulSoup ist eine Python-Bibliothek zum Parsen von HTML- und XML-Dokumenten. Sie erstellt einen Parse-Baum aus der Seitensource, der es ermöglicht, auf die verschiedenen Elemente der Seite leicht zuzugreifen. Gewöhnlich wird sie mit anderen Bibliotheken wie Requests oder Selenium kombiniert, die die HTML-Quellcode bereitstellen.
  • Selenium wird hauptsächlich für Websites eingesetzt, die viel JavaScript verwenden. Im Gegensatz zu BeautifulSoup, Selenium analysiert HTML-Code nicht einfach: Es interagiert mit Websites, indem es Benutzeraktionen wie Klicks und Scrollen emuliert. Dies erleichtert die Datenextraktion von Websites, die Inhalte dynamisch erstellen.

Diese Werkzeuge waren unverzichtbar, als ich versuchte, Daten von Websites zu extrahieren. Sie stellten jedoch auch einige Herausforderungen: Code, Tags und Strukturelemente mussten regelmäßig aktualisiert werden, um Änderungen im Layout der Website zu berücksichtigen, was die Langzeitpflege komplizierte.

Was sind große Sprachmodelle (LLMs)?

Große Sprachmodelle (LLMs) sind nächste Generation von Computerprogrammen, die durch Lesen und Analysieren großer Mengen von Textdaten lernen können. In diesem Zeitalter sind sie mit der erstaunlichen Fähigkeit ausgestattet, in einer menschlichen Erzählweise zu schreiben, was sie zu effizienten Agenten zur Verarbeitung von Sprache und zum Verständnis der menschlichen Sprache macht. Die herausragende Fähigkeit zeigte sich in solchen Situationen, in denen der Textkontext wirklich wichtig war.

Integration von LLMs in Web-Scraping

Der Web-Scraping-Prozess kann in großem Maße optimiert werden, indem LLMs (Large Language Models) in ihn implementiert werden. Wir müssen den HTML-Code einer Webseite entnehmen und ihn an das LLM übergeben, das die darauf verweisenden Objekte extrahiert. Daher trägt diese Vorgehensweise dazu bei, die Wartung zu erleichtern, da die Markup-Struktur sich entwickeln kann, aber der Inhalt selbst ändert sich in der Regel nicht.

Hier ist, wie die Architektur eines solchen integrierten Systems aussehen würde:

  1. HTML-Abrufen: Verwenden Sie Werkzeuge wie Selenium oder Requests, um den HTML-Inhalt einer Webseite abzurufen. Selenium kann mit dynamischem Inhalt umgehen, der mit JavaScript geladen wird, während Requests für statische Seiten geeignet ist.
  2. HTML-Parsen: Mit BeautifulSoup können wir diesen HTML als Text aus dem HTML-Rauschen (Fußzeile, Kopfzeile usw.) herausparsen.
  3. Erstellung von Pydantic-Modellen: Geben Sie das Pydantic-Modell an, das wir scrapen werden. Dies stellt sicher, dass die getypte und strukturierte Daten den vorgegebenen Schemata entspricht.
  4. Erstellung von Prompts für LLMs: Entwerfen Sie einen Prompt, der dem LLM mitteilt, welche Informationen extrahiert werden müssen.
  5. Verarbeitung durch LLM: Das Modell liest den HTML, versteht ihn und verwendet die Anweisungen für die Datenverarbeitung und -strukturierung.
  6. Ausgabe strukturierter Daten: Das LLM liefert die Ausgabe in Form strukturierter Objekte, die durch das Pydantic-Modell definiert sind.

Dieses Workflow hilft dabei, HTML (unstrukturiertes Daten) in strukturierte Daten zu transformieren, indem LLMs verwendet werden, um Probleme wie nicht standardmäßige Gestaltung oder dynamische Änderung der Web-Quell-HTML zu lösen.

Integration von LangChain mit BeautifulSoup und Pydantic

Dies ist die statische Webseite, die für das Beispiel ausgewählt wurde. Die Idee ist, alle dort aufgelisteten Aktivitäten zu scrapen und sie auf strukturierte Weise darzustellen.

Diese Methode wird die Roh-HTML von der statischen Webseite extrahieren und sie reinigen, bevor das LLM sie verarbeitet.

Python

 

from bs4 import BeautifulSoup
import requests


def extract_html_from_url(url):
    try:
        # HTML-Inhalt von der URL mit requests abrufen
        response = requests.get(url)
        response.raise_for_status()  # Raise an exception for bad responses (4xx and 5xx)

        # HTML-Inhalt mit BeautifulSoup analysieren
        soup = BeautifulSoup(response.content, "html.parser")
        excluded_tagNames = ["footer", "nav"]
        # Elemente mit Tag-Namen 'footer' und 'nav' ausschließen
        for tag_name in excluded_tagNames:
            for unwanted_tag in soup.find_all(tag_name):
                unwanted_tag.extract()

        # Das Suppe-Objekt verarbeiten, um hrefs in Anker-Tags beizubehalten
        for a_tag in soup.find_all("a"):
            href = a_tag.get("href")
            if href:
                a_tag.string = f"{a_tag.get_text()} ({href})"

        return ' '.join(soup.stripped_strings)  # Return text content with preserved hrefs

    except requests.exceptions.RequestException as e:
        print(f"Error fetching data from {url}: {e}")
        return None

Der nächste Schritt ist die Definition der Pydantic-Objekte, die wir von der Webseite scrapen werden. Zwei Objekte müssen erstellt werden:

  • Activity: Dies ist ein Pydantic-Objekt, das alle Metadaten im Zusammenhang mit der Aktivität darstellt, mit spezifizierten Attributen und Datentypen. Einige Felder sind als Optional markiert, falls sie für alle Aktivitäten nicht verfügbar sind. Die Bereitstellung einer Beschreibung, Beispiele und Metadaten helfen dem LLM, eine bessere Definition des Attributs zu haben.
  • ActivityScraper: Dies ist der Pydantic-Wrapper um die Activity. Das Ziel dieses Objekts ist es, sicherzustellen, dass das LLM versteht, dass es mehrere Aktivitäten zu scrapen gilt.
Python

 

from pydantic import BaseModel, Field
from typing import Optional

class Activity(BaseModel):
    title: str = Field(description="The title of the activity.")
    rating: float = Field(description="The average user rating out of 10.")
    reviews_count: int = Field(description="The total number of reviews received.")
    travelers_count: Optional[int] = Field(description="The number of travelers who have participated.")
    cancellation_policy: Optional[str] = Field(description="The cancellation policy for the activity.")
    description: str = Field(description="A detailed description of what the activity entails.")
    duration: str = Field(description="The duration of the activity, usually given in hours or days.")
    language: Optional[str] = Field(description="The primary language in which the activity is conducted.")
    category: str = Field(description="The category of the activity, such as 'Boat Trip', 'City Tours', etc.")
    price: float = Field(description="The price of the activity.")
    currency: str = Field(description="The currency in which the price is denominated, such as USD, EUR, GBP, etc.")

    
class ActivityScrapper(BaseModel):
    Activities: list[Activity] = Field("List of all the activities listed in the text")

Schließlich haben wir die Konfiguration des LLM. Wir werden die LangChain-Bibliothek verwenden, die ein ausgezeichnetes Toolkit bietet, um loszulegen.

A key component here is the PydanticOutputParser. Essentially, this will translate our object into instructions, as illustrated in the Prompt, and also parse the output of the LLM to retrieve the corresponding list of objects.

Python

 

from langchain.prompts import PromptTemplate
from langchain.output_parsers import PydanticOutputParser
from langchain_openai import ChatOpenAI
from dotenv import load_dotenv

load_dotenv()

llm = ChatOpenAI(temperature=0)
output_parser = PydanticOutputParser(pydantic_object = ActivityScrapper)

prompt_template = """
You are an expert making web scrapping and analyzing HTML raw code.
If there is no explicit information don't make any assumption.
Extract all objects that matched the instructions from the following html
{html_text}
Provide them in a list, also if there is a next page link remember to add it to the object.
Please, follow carefulling the following instructions
{format_instructions}
"""

prompt = PromptTemplate(
    template=prompt_template,
    input_variables=["html_text"],
    partial_variables={"format_instructions": output_parser.get_format_instructions}
)

chain = prompt | llm | output_parser

Der letzte Schritt besteht darin, die Kette aufzurufen und die Ergebnisse abzurufen.

Python

 

url = "https://www.civitatis.com/es/budapest/"
html_text_parsed = extract_html_from_url(url)
activites = chain.invoke(input={
    "html_text": html_text_parsed
})
activites.Activities

Hier ist, wie die Daten aussehen. Es dauert 46 Sekunden, um die gesamte Webseite zu scrapen.

Python

 

[Activity(title='Paseo en barco al anochecer', rating=8.4, reviews_count=9439, travelers_count=118389, cancellation_policy='Cancelación gratuita', description='En este crucero disfrutaréis de las mejores vistas de Budapest cuando se viste de gala, al anochecer. El barco es panorámico y tiene partes descubiertas.', duration='1 hora', language='Español', category='Paseos en barco', price=21.0, currency='€'),
 Activity(title='Visita guiada por el Parlamento de Budapest', rating=8.8, reviews_count=2647, travelers_count=34872, cancellation_policy='Cancelación gratuita', description='El Parlamento de Budapest es uno de los edificios más bonitos de la capital húngara. Comprobadlo vosotros mismos en este tour en español que incluye la entrada.', duration='2 horas', language='Español', category='Visitas guiadas y free tours', price=27.0, currency='€')
 ...
]

Demo und Vollständiges Repository

I have created a quick demo using Streamlit available here.

Im ersten Teil werden Sie mit dem Modell vertraut gemacht. Sie können so viele Zeilen wie nötig hinzufügen und den Namen, den Typ und die Beschreibung jedes Attributs angeben. Dies erzeugt automatisch ein Pydantic-Modell, das im Web-Scraping-Komponent verwendet werden soll.

Im nächsten Teil können Sie eine URL eingeben und alle Daten durch Klicken auf den Button auf der Webseite scrapen. Ein Download-Button erscheint, wenn das Scraping abgeschlossen ist, und ermöglicht Ihnen, die Daten im JSON-Format herunterzuladen.

Spielen Sie gern damit!

Schlussfolgerung

LLM bietet neue Möglichkeiten für die effiziente Extraktion von Daten aus nicht strukturierten Daten wie Websites, PDFs usw. Die Automatisierung des Web Scrapings durch LLM spart nicht nur Zeit, sondern stellt auch die Qualität der extrahierten Daten sicher.

Allerdings könnte das Senden von unverarbeitetem HTML an das LLM die Tokenkosten erhöhen und es ineffizient machen. Da HTML oft verschiedene Tags, Attribute und Inhalte enthält, können die Kosten schnell ansteigen.

Daher ist es entscheidend, das HTML vorzubereiten und zu reinigen, indem man alle unnötigen Metadaten und nicht genutzten Informationen entfernt. Dieser Ansatz hilft dabei, das LLM als Datenextraktor für Webseiten zu nutzen, wobei gleichzeitig ein anständiger Kostenrahmen gewahrt bleibt.

Das richtige Werkzeug für die richtige Aufgabe!

Source:
https://dzone.com/articles/enhancing-web-scraping-with-large-language-models