Vấn đề
Bạn cần trích xuất các bảng HTML từ một trang web.
Giới thiệu
Internet (WWW) là nguồn thông tin lớn nhất ngày nay. Thông tin có thể truy xuất qua HTTP. Python cho phép tự động hóa việc lấy và xử lý thông tin này bằng thư viện chuẩn hoặc requests (dễ dùng hơn).
Bài viết minh họa parse HTML để lấy các bảng nhúng trong trang.
Cách thực hiện
1. Cài đặt thư viện
pip install requests pandas beautifulsoup4 tabulate
2. Tải trang web
import requests
site_url = "https://www.tutorialspoint.com/python/python_basic_operators.htm"
response = requests.get(site_url)
print(f"Response status: {response.status_code}") # 200 = thành công
3. Kiểm tra header và nội dung
print(response.request.headers) # Request headers
print(response.headers) # Response headers
print(response.text[:100]) # 100 ký tự đầu
4. Parse HTML với BeautifulSoup
from bs4 import BeautifulSoup
soup = BeautifulSoup(response.text, 'html.parser')
print(soup.title) # Thẻ ...
print(soup.title.string) # Chỉ nội dung text
5. Tìm bảng (table) đi kèm heading (h2-h6)
Các bảng thường có tiêu đề trong thẻ h2 đến h6. Chiến lược: tìm các thẻ heading, sau đó lấy table là sibling kế tiếp.
# Tìm thẻ heading đầu tiên (h2-h6)
tags = soup.find(lambda elm: elm.name in ["h2", "h3", "h4", "h5", "h6"])
# Duyệt các sibling sau nó
for sibling in tags.find_next_siblings():
if sibling.name == "table":
my_table = sibling
df = pd.read_html(str(my_table))
print(df[0]) # pd.read_html trả về list DataFrame
break
6. Chương trình hoàn chỉnh
import requests
import pandas as pd
from bs4 import BeautifulSoup
site_url = "https://www.tutorialspoint.com/python/python_basic_operators.htm"
response = requests.get(site_url)
print(f"Status: {response.status_code}")
soup = BeautifulSoup(response.text, 'html.parser')
print(f"Title: {soup.title.string}")
# Tìm tất cả heading
headings = soup.find_all(lambda elm: elm.name in ["h2", "h3", "h4", "h5", "h6"])
print(f"Headings found: {[h.get_text() for h in headings]}")
# Với mỗi heading, tìm table kế tiếp
for heading in headings:
for sibling in heading.find_next_siblings():
if sibling.name == "table":
df_list = pd.read_html(str(sibling))
for i, df in enumerate(df_list):
print(f"\n--- Table after '{heading.get_text()}' ---")
print(df.to_string())
break # Chỉ lấy table đầu tiên sau heading
Kết quả mẫu
Chương trình in ra các bảng: Toán tử số học, So sánh, Gán, Bitwise, Logic, Membership, Identity, Độ ưu tiên - mỗi bảng là một DataFrame Pandas.