Việc tự động hóa quá trình thu thập nội dung từ các trang web truyện chữ là một bài tập thực hành phổ biến để làm quen với kỹ thuật Web Scraping. Bằng cách sử dụng ngôn ngữ Python cùng các thư viện như requests và BeautifulSoup, chúng ta có thể dễ dàng trích xuất hàng ngàn chương truyện một cách nhanh chóng.
1. Thu thập danh sách liên kết các chương
Bước đầu tiên trong quá trình này là truy cập vào trang mục lục của bộ truyện để lấy toàn bộ URL của các chương đơn lẻ. Chúng ta sẽ sử dụng CSS Selector để định vị chính xác các thẻ chứa liên kết.
import requests
from bs4 import BeautifulSoup
def get_all_chapters(index_url):
# Gửi yêu cầu HTTP đến trang mục lục
response = requests.get(index_url)
response.encoding = 'utf-8' # Đảm bảo hiển thị đúng font chữ
soup = BeautifulSoup(response.text, 'lxml')
# Tìm tất cả các thẻ a trong cấu trúc danh sách chương
raw_links = soup.select('#list dl dd a')
base_domain = "http://www.biquge.com.tw"
processed_urls = []
for link in raw_links:
path = link.get('href')
# Hợp nhất path với domain để tạo URL hoàn chỉnh
full_path = base_domain + path
processed_urls.append(full_path)
return processed_urls
2. Trích xuất nội dung văn bản và lưu trữ
Sau khi có được danh sách URL, chương trình sẽ lặp qua từng liên kết để lấy tiêu đề chương và nội dung truyện, sau đó ghi trực tiếp vào tệp tin văn bản (txt).
def save_content(chapter_url, output_file):
res = requests.get(chapter_url)
res.encoding = 'utf-8'
soup = BeautifulSoup(res.text, 'lxml')
# Trích xuất tiêu đề chương từ thẻ h1
chapter_title = soup.find('div', class_='bookname').h1.get_text()
# Trích xuất nội dung truyện từ thẻ div có id content
chapter_body = soup.find('div', id='content').get_text()
# Ghi dữ liệu vào file bằng phương thức 'a' (append) để không ghi đè
with open(output_file, 'a', encoding='utf-8') as f:
f.write(f"\n{chapter_title}\n")
f.write("-" * 20 + "\n")
f.write(chapter_body + "\n")
3. Vận hành chương trình
Chúng ta kết hợp hai hàm trên vào luồng thực thi chính. Để tránh bị chặn bởi máy chủ, bạn có thể cân nhắc thêm các khoảng nghỉ (delay) giữa các lần gọi yêu cầu.
if __name__ == '__main__':
target_index = 'http://www.biquge.com.tw/18_18049/'
file_name = 'truyen_da_tai.txt'
all_links = get_all_chapters(target_index)
print(f"Tìm thấy {len(all_links)} chương. Đang bắt đầu tải dữ liệu...")
for url in all_links:
try:
save_content(url, file_name)
print(f"Hoàn thành: {url}")
except Exception as e:
print(f"Xảy ra lỗi tại {url}: {e}")
Tối ưu hóa với XPath
Mặc dù BeautifulSoup rất thân thiện, nhưng khi đối mặt với các cấu trúc HTML phức tạp hoặc yêu cầu hiệu năng cao hơn, sử dụng lxml kết hợp với XPath sẽ mang lại tốc độ xử lý vượt trội. XPath cho phép bạn truy vấn sâu vào các node với cú pháp ngắn gọn hơn.
Ví dụ, để lấy trực tiếp thuộc tính href của danh sách chương, bạn có thể sử dụng biểu thức:
# Sử dụng thư viện lxml.etree
# links = tree.xpath('//*[@id="list"]/dl/dd/a/@href')
Việc sử dụng XPath đặc biệt hiệu quả khi bạn muốn xác định các phần tử dựa trên thuộc tính class hoặc vị trí tương đối giữa các thẻ trong DOM.