في أيامي الأولى كمهندس بيانات (مما يعود إلى عام 2016)، كانت مسؤوليتي هي جرد البيانات من مواقع إلكترونية مختلفة. تجريد الويب يتعلق باستخدام أدوات مصطنعة تلتقط كميات هائلة من البيانات من المواقع الإلكترونية، عادةً من تمثيل النص التوضيحي للإنترنت.
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.
فكرة واحدة جاءت ليعقل عندما بدأت قراءة حول نماذج اللغة الكبيرة (LLMs) كانت، “هل يمكنني تجنب كل تلك الم pitfalls التي واجهتها باستخدام LLMs لتنظيم البيانات من صفحات الويب؟”
دعونا نرى ما إذا كان بإمكاني.
أدوات وتقنيات تجريد الويب
في ذلك الوقت، كانت الأدوات الرئيسية التي كنت أستخدمها هي Requests، BeautifulSoup، و Selenium. كل خدمة لها هدف مختلف وتستهدف أنواع مختلفة من بيئات الويب.
- الطلبات هي مكتبة بايثون والتي يمكن استخدامها لإجراء طلبات HTTP بسهولة. تقوم هذه المكتبة بإجراء عمليات GET و POST ضد الروابط المقدمة في الطلبات. غالبًا ما يتم استخدامها لجلب محتوى HTML الذي يمكن تحليله بواسطة BeautifulSoup.
- BeautifulSoup هي مكتبة بايثون لتحليل المستندات النصية التشعبية والملفات XML، حيث تقوم ببناء شجرة تحليل من مصدر الصفحة مما يسمح لك بالوصول إلى العناصر المختلفة على الصفحة بسهولة. عادة، يتم إقترانها مع مكتبات أخرى مثل Requests أو Selenium التي توفر رمز المصدر HTML.
- Selenium يستخدم بشكل أساسي للمواقع التي تتضمن الكثير من JavaScript. على عكس BeautifulSoup، Selenium لا يحلل فقط HTML الرموز: إنه يتفاعل مع المواقع عن طريق تقليد إجراءات المستخدم مثل النقر والتمرير. هذا يسهل استخراج البيانات من المواقع التي تخلق المحتوى بشكل ديناميكي.
كانت هذه الأدوات ضرورية عندما كنت أحاول استخراج البيانات من المواقع. ومع ذلك، فإنها أيضًا شكلت بعض التحديات: كان على الكود والعلامات والعناصر الهيكلية التحديث بانتظام لتلبية التغييرات في تخطيط الموقع، مما جعل الصيانة المستدامة معقدة.
ما هي نماذج اللغة الكبيرة (LLMs)؟
نماذج اللغة الكبيرة (LLMs) هي برامج حاسوبية من الجيل التالي التي يمكنها التعلم من خلال القراءة وتحليل كميات هائلة من بيانات النص. في هذا العصر، لديهم القدرة المذهلة على الكتابة بطريقة كائنية تشبه الإنسان مما يجعلهم وكلاء فعالون لمعالجة اللغة وفهم اللغة البشرية. أظهرت القدرة الرائعة في مثل هذه المواقف، حيث كانت سياق النص مهمًا جدًا.
دمج نماذج LLMs في جلب البيانات من الويب
عملية التنقيب عن البيانات على الويب يمكن تحسينها بشكل كبير عند دمج نماذج LLMs فيها. نحتاج لأخذ رمز HTML من صفحة ويب وإضافته إلى نموذج LLM، الذي سيستخرج الكائنات التي يشير إليها. وبالتالي، يسهم هذا الاستراتيجي في تسهيل الصيانة، حيث يمكن تطور بنية الترميز ولكن المحتوى نفسه لا يتغير عادة.
هذا هو مظهر النظام المتكامل بهذه الطريقة:
- استلام HTML: استخدم أدوات مثل Selenium أو Requests لجلب محتوى HTML لصفحة ويب. يمكن لـ Selenium التعامل مع المحتوى الديناميكي المحمل باستخدام JavaScript، بينما تكون Requests مناسبة للصفحات الثابتة.
- تحليل HTML: باستخدام BeautifulSoup، يمكننا تحليل هذا الـ HTML كنص، مما يزيل الضجيج من الـ HTML (التذييل، الرأس، إلخ).
- إنشاء نماذج Pydantic: اكتب نموذج Pydantic الذي سنقوم بتنقيب البيانات منه. هذا يضمن أن البيانات المكتوبة والمنظمة تتوافق مع المخططات المعرفة مسبقًا.
- إنشاء موجهات لنماذج LLMs: صمم موجهًا يبلغ النموذج LLM عن المعلومات التي يجب استخراجها.
- معالجة من قبل نموذج LLM: النموذج يقرأ الـ HTML، يفهمه، ويستخدم التعليمات لمعالجة وتنظيم البيانات.
- ناتج البيانات المنظمة: سيقدم النموذج LLM الناتج على شكل كائنات منظمة تحددها نموذج Pydantic.
يساعد هذا النموذج على تحويل HTML (بيانات غير منظمة) إلى بيانات منظمة باستخدام نماذج الذكاء الاصطناعي الكبيرة (LLMs)، مما يحل مشاكل مثل التصميم غير القياسي أو تعديل ديناميكي لمصدر HTML الويب.
تكامل LangChain مع BeautifulSoup و Pydantic
هذا هو الصفحة الثابتة المختارة للمثال. الفكرة هي سحب جميع الأنشطة المدرجة هناك وتقديمها بطريقة منظمة.
هذه الطريقة ستستخرج HTML الأولي من الصفحة الثابتة وتنظفه قبل معالجته بواسطة نموذج الذكاء الاصطناعي الكبير (LLM).
from bs4 import BeautifulSoup
import requests
def extract_html_from_url(url):
try:
# استلام محتوى HTML من الرابط باستخدام requests
response = requests.get(url)
response.raise_for_status() # Raise an exception for bad responses (4xx and 5xx)
# تحليل محتوى HTML باستخدام BeautifulSoup
soup = BeautifulSoup(response.content, "html.parser")
excluded_tagNames = ["footer", "nav"]
# إستبعاد العناصر ذات أسماء العلامات 'footer' و 'nav'
for tag_name in excluded_tagNames:
for unwanted_tag in soup.find_all(tag_name):
unwanted_tag.extract()
# معالجة الحساء للحفاظ على hrefs في علامات التبويب
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
الخطوة التالية هي تحديد كائنات Pydantic التي سنقوم بتسخيرها من الصفحة. يجب إنشاء كائنين:
Activity
: هذا كائن Pydantic يمثل جميع بيانات الوصف الوصفي للنشاط، مع تحديد سماته وأنواع البيانات. لقد على بعض الحقول بـOptional
في حالة عدم توافرها لجميع الأنشطة. توفير وصف، وأمثلة، وأي بيانات وصفية سيساعد نموذج الذكاء الاصطناعي الكبير (LLM) على تحديد السمة بشكل أفضل.ActivityScraper
: هذا هو الغلاف البيانى المحيط بـActivity
. الهدف من هذا الكائن هو ضمان فهم LLM بأنه يجب أن يقوم بتجزئة العديد من الأنشطة.
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")
أخيرًا، لدينا تكوين LLM. سنستخدم مكتبة LangChain، التي توفر أدوات ممتازة للبدء.
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.
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
الخطوة الأخيرة هي استدعاء السلسلة واسترداد النتائج.
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
هذا هو مظهر البيانات. يستغرق قطع صفحة الويب كاملة 46 ثانية.
[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='€')
...
]
عرض توضيحي ومستودع كامل
I have created a quick demo using Streamlit available here.
في الجزء الأول، يتم تعريفك بالنموذج. يمكنك إضافة العديد من الصفوف كما تحتاج وتحديد الاسم والنوع ووصف كل سمة. سيتم تلقائيًا توليد نموذج Pydantic ليتم استخدامه في مكون تجزئة الويب.
الجزء التالي يتيح لك إدخال URL وتجزئة كافة البيانات عن طريق النقر على الزر في صفحة الويب. سيظهر زر تنزيل عندما ينتهي التجزئة، مما يتيح لك تنزيل البيانات بتنسيق JSON.
لا تتردد في اللعب به!
الخاتمة
LLM يوفر إمكانات جديدة لاستخراج البيانات بكفاءة من البيانات غير المنظمة مثل المواقع الإلكترونية، الملفات النصية، إلخ. تشغيل تجزئة الويب تلقائيًا من قبل LLM لن يوفر الوقت فحسب بل سيضمن جودة البيانات المستردة.
ومع ذلك، إرسال HTML الأولي إلى LLM يمكن أن يزيد من تكلفة الأحرف ويجعله غير فعال. نظرًا لأن HTML غالبًا ما يشمل علامات وسمات ومحتويات مختلفة، يمكن أن ترتفع التكلفة بسرور.
ولذلك، من الحاسم توخي التحضير وتنظيف HTML، مع التخلص من جميع البيانات التعريفية الزائدة والمعلومات غير المستخدمة. ستساعد هذه الطريقة في استخدام LLM كمستخرج للبيانات من المواقع أثناء الحفاظ على تكلفة متوسطة.
الأداة المناسبة للعمل المناسب!
Source:
https://dzone.com/articles/enhancing-web-scraping-with-large-language-models