Hướng Dẫn Xây Dựng Tool Crawl Dữ Liệu Phim TOP250 Douban Với Python

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, beautifulsoup4pandas. 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ố start xá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()

Thẻ: python beautifulsoup4 requests Pandas web-scraping

Đăng vào ngày 20 tháng 5 lúc 18:19