Tổng Quan Về Dự Án Thu Thập Dữ Liệu
Việc khai thác thông tin từ danh sách 250 bộ phim hàng đầu trên Douban là một bài tập thực hành phổ biến giúp lập trình viên nắm vững kỹ thuật web scraping bằng Python. Quy trình này bao gồm việc gửi yêu cầu HTTP, phân tích cú pháp HTML và lưu trữ dữ liệu có cấu trúc.
Thiết Lập Môi Trường Phát Triển
Để bắt đầu, người dùng cần cài đặt các thư viện hỗ trợ xử lý HTTP, phân tích DOM và thao tác dữ liệu. Ba gói chính cần thiết là requests, beautifulsoup4 và pandas. Thực thi lệnh sau trong terminal:
pip install requests beautifulsoup4 pandas
Phân Tích Cấu Trúc Trang Đích
Trang danh sách TOP250 (https://movie.douban.com/top250) sử dụng cơ chế phân trang thông qua tham số URL. Mỗi trang hiển thị 25 bản ghi, tổng cộng 10 trang cho toàn bộ danh sách. Các điểm kỹ thuật cần lưu ý:
- Quy luật URL: Tham số
startxác định vị trí bắt đầu, ví dụ?start=0,?start=25,?start=50. - Cấu trúc DOM: Thông tin từng phim được gói trong thẻ
<div class="item">, chứa các trường như tên phim, điểm số và số lượng bình chọn.
Triển Khai Mã Nguồn Crawler
Đoạn mã dưới đây tổ chức logic thành các hàm riêng biệt để xử lý việc tải nội dung, trích xuất thông tin và lưu vào file CSV. Biến và cấu trúc hàm đã được tùy chỉnh để tối ưu hóa quy trình.
import requests
from bs4 import BeautifulSoup
import pandas as pd
import time
def load_url_content(target_link):
client_headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}
try:
server_response = requests.get(target_link, headers=client_headers, timeout=10)
server_response.encoding = 'utf-8'
if server_response.status_code == 200:
return server_response.text
else:
print(f"Lỗi truy cập: {server_response.status_code}")
return None
except Exception as e:
print(f"Ngoại lệ xảy ra: {e}")
return None
def extract_movie_info(html_content):
dom_parser = BeautifulSoup(html_content, 'html.parser')
movie_blocks = dom_parser.find_all('div', class_='item')
record_list = []
for block in movie_blocks:
try:
film_name = block.find('span', class_='title').get_text(strip=True)
score_value = block.find('span', class_='rating_num').get_text(strip=True)
star_div = block.find('div', class_='star')
vote_spans = star_div.find_all('span')
vote_count = vote_spans[-1].get_text(strip=True).replace('人评价', '') if vote_spans else '0'
record_list.append({
'title': film_name,
'rating': score_value,
'votes': vote_count
})
except AttributeError:
continue
return record_list
def run_spider():
all_data = []
base_link = "https://movie.douban.com/top250"
for page_index in range(10):
offset = page_index * 25
current_url = f"{base_link}?start={offset}"
print(f"Đang xử lý: {current_url}")
html = load_url_content(current_url)
if html:
data = extract_movie_info(html)
all_data.extend(data)
time.sleep(1) # Tránh gửi yêu cầu quá nhanh
if all_data:
df = pd.DataFrame(all_data)
df.to_csv('douban_top250.csv', index=False, encoding='utf-8-sig')
print("Hoàn tất lưu dữ liệu vào douban_top250.csv")
if __name__ == "__main__":
run_spider()