
Cách xây dựng công cụ trích xuất dữ liệu web (Web Scraper) AI đơn giản bằng Python
Biến bất kỳ trang web nào thành công cụ hỏi đáp (QA) nhẹ, được hỗ trợ bởi mô hình ngôn ngữ lớn (LLM), bằng cách làm sạch mã HTML, chuyển đổi nội dung sang định dạng Markdown và đưa ra các câu trả lời tập trung, đồng thời giảm mức tiêu thụ token.
Cách xây dựng một công cụ trích xuất dữ liệu web AI đơn giản bằng Python - KDnuggets
Trích xuất dữ liệu web là quá trình thu thập thông tin từ các trang web một cách tự động. Một công cụ trích xuất dữ liệu thông thường thường chỉ trích xuất văn bản thô, các phần tử HTML hoặc toàn bộ nội dung trang. Tuy nhiên, khi xây dựng các tác nhân AI hoặc ứng dụng mô hình ngôn ngữ lớn (LLM), việc gửi toàn bộ trang web đến mô hình không phải lúc nào cũng là cách tiếp cận tốt nhất.
Một cách tốt hơn là trước tiên làm sạch trang, chuyển đổi nó sang định dạng Markdown, sau đó sử dụng LLM để hiểu nội dung và chỉ trả về câu trả lời mà người dùng cần. Điều này giúp đầu ra sạch hơn, dễ đọc hơn và dễ sử dụng hơn trong một quy trình làm việc khác.
Nó cũng giúp giảm mức sử dụng token. Thay vì chuyển một trang web lộn xộn đầy các liên kết điều hướng, nút, tập lệnh, chân trang và nội dung lặp lại, chúng ta chỉ gửi nội dung trang hữu ích đến mô hình. LLM sau đó trả về một câu trả lời tập trung ở định dạng Markdown thay vì đổ toàn bộ trang cho người dùng.
Trong hướng dẫn này, chúng ta sẽ xây dựng một công cụ trích xuất dữ dữ liệu web AI đơn giản bằng Python sử dụng Jupyter Notebook. Nó sẽ tìm nạp một trang web, làm sạch HTML, chuyển đổi nó sang Markdown, chấp nhận một truy vấn của người dùng và trả về một câu trả lời Markdown rõ ràng dựa trên nội dung trang.
# Thiết lập
Chúng ta sẽ sử dụng Jupyter Notebook cho dự án này. Nó giúp dễ dàng kiểm tra từng bước trước khi biến công cụ trích xuất dữ liệu thành một giao diện lập trình ứng dụng (API) hoặc ứng dụng phù hợp.
Bắt đầu bằng cách cài đặt các gói Python cần thiết:
!pip install requests beautifulsoup4 markdownify openai ftfy python-dotenv
Chúng ta sẽ sử dụng:
requests để tìm nạp trang web.
BeautifulSoup để loại bỏ các phần tử HTML gây nhiễu.
markdownify để chuyển đổi HTML sang Markdown.
OpenAI để trả lời truy vấn của người dùng.
ftfy để sửa văn bản bị hỏng hoặc lộn xộn.
python-dotenv để tải khóa API một cách an toàn.
Trong ô tiếp theo, nhập các thư viện cần thiết:
import os
import re
import requests
from bs4 import BeautifulSoup, Comment
from ftfy import fix_text
from markdownify import markdownify as markdownify_html
from openai import OpenAI
from dotenv import load_dotenv
from IPython.display import Markdown, display
Tiếp theo, đảm bảo khóa API OpenAI của bạn có sẵn dưới dạng biến môi trường. Cách an toàn hơn là tạo một tệp .env trong cùng thư mục với sổ ghi chép của bạn và thêm khóa của bạn vào đó:
OPENAI_API_KEY=your_api_key_here
Sau đó tải nó vào sổ ghi chép:
load_dotenv()
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
Bạn cũng có thể kiểm tra xem khóa đã được tải đúng cách chưa:
if not os.getenv("OPENAI_API_KEY"):
raise ValueError("OPENAI_API_KEY is missing. Add it to your .env file first.")
Đồng thời, hãy đảm bảo tài khoản nền tảng OpenAI của quý vị đã thiết lập thanh toán. Đối với các tài khoản API mới, quý vị có thể cần nạp tiền trả trước trước khi có thể thực hiện các lệnh gọi API. Nếu một mô hình không khả dụng trong tài khoản của quý vị, hãy sử dụng mô hình khác từ bảng điều khiển OpenAI của quý vị.
Bây giờ, hãy định nghĩa tên mô hình:
MODEL_NAME = "gpt-5.4-nano"
Chúng tôi đang sử dụng một mô hình nhỏ hơn ở đây vì tác vụ này không yêu cầu một mô hình suy luận lớn. Mục tiêu rất đơn giản: đọc nội dung trang web đã được làm sạch, hiểu truy vấn của người dùng và trả về một câu trả lời Markdown tập trung.
# Lấy nội dung trang web
Bây giờ chúng ta sẽ tạo hàm đầu tiên. Hàm này sẽ lấy nội dung trang web bằng cách sử dụng gói `requests` và trả về HTML thô.
def fetch_page(url: str) -> str:
"""
Tải nội dung HTML từ một trang web.
"""
headers = {
"User-Agent": "SimpleAIScraper/1.0"
}
response = requests.get(url, headers=headers, timeout=15)
response.raise_for_status()
return response.text
Tiêu đề User-Agent cho trang web biết rằng yêu cầu đến từ trình thu thập dữ liệu của chúng ta. Một số trang web chặn các yêu cầu không bao gồm User-Agent, vì vậy việc thêm một tiêu đề này giúp yêu cầu đáng tin cậy hơn một chút.
Chúng ta cũng sử dụng `timeout` để tránh chờ đợi vô thời hạn nếu trang web không phản hồi. Lệnh gọi `raise_for_status()` sẽ dừng mã nếu yêu cầu thất bại — ví dụ, nếu trang trả về lỗi 404 hoặc 500.
Bây giờ, hãy kiểm tra hàm với một trang web thực tế:
raw = fetch_page("https://www.olostep.com/")
print(raw[:500])
Thao tác này sẽ tải HTML thô từ trang web và in 500 ký tự đầu tiên.
Đầu ra HTML thô | Hình ảnh của Tác giả
Ở giai đoạn này, đầu ra vẫn sẽ trông lộn xộn vì nó chứa toàn bộ HTML của trang, bao gồm các thẻ, tập lệnh, phần tử bố cục và các nội dung khác mà chúng ta không cần.
# Làm sạch HTML
HTML thô từ một trang web thường chứa rất nhiều nội dung mà chúng ta không cần. Nó có thể bao gồm các tập lệnh, kiểu dáng, menu điều hướng, nút, biểu mẫu, tiêu đề, chân trang, cửa sổ bật lên và các phần tử bố cục khác.
Trước khi gửi nội dung trang đến LLM, chúng ta cần làm sạch HTML. Điều này giúp giảm nhiễu và làm cho Markdown cuối cùng dễ hiểu hơn nhiều đối với mô hình.
Chúng ta sẽ sử dụng BeautifulSoup để phân tích cú pháp HTML và loại bỏ các phần tử không cần thiết.
def clean_html(html):
html = fix_text(html)
soup = BeautifulSoup(html, "html.parser")
# Loại bỏ các thẻ gây nhiễu rõ ràng
for tag in soup([
"script", "style", "noscript", "svg", "img", "iframe",
"nav", "header", "footer", "aside", "form", "button"
]):
tag.decompose()
noise_words = [
"cursor",
"modal",
"popup",
"floating",
"signup",
"login",
"cookie",
"
Nguồn tin: KDnuggets — Tác giả: Abid Ali Awan. Bản dịch tiếng Việt do AI thực hiện, có thể có sai sót.