Cách cạo dữ liệu IMDB bằng Python

Bình luận: 0

Trong thế giới ngày nay, việc trích xuất dữ liệu từ các nền tảng xã hội trực tuyến như IMDB có thể là một con đường hiệu quả để thu thập thông tin liên quan đến phim rất cần thiết cho mục đích nghiên cứu hoặc thưởng thức. Trong hướng dẫn này, chúng tôi sẽ đi bộ qua 250 bộ phim hàng đầu trên IMDB bằng Python và trích xuất các chi tiết như tiêu đề phim, tóm tắt phim, xếp hạng, thể loại, v.v.

Khi các trang web cạo như IMDB, điều quan trọng là phải mô phỏng hành vi của người dùng thực để giảm thiểu rủi ro phát hiện và đảm bảo truy xuất dữ liệu thành công. Dưới đây là một số chiến lược có thể được sử dụng:

  1. Tránh chặn IP: Các trang web thường giới hạn số lượng yêu cầu có thể được thực hiện từ một địa chỉ IP duy nhất để ngăn chặn việc cạo. Bằng cách sử dụng proxy, bạn có thể phân tán các yêu cầu của mình qua nhiều địa chỉ IP, giảm nguy cơ bị chặn.
  2. Đảm bảo tính ẩn danh: Proxy che giấu địa chỉ IP thực của bạn, điều này không chỉ giúp bảo vệ quyền riêng tư của bạn mà còn khiến các trang web khó theo dõi các hoạt động cào trở lại với bạn.
  3. Tuân thủ các giới hạn tốc độ: Phân phối các yêu cầu thông qua nhiều proxy có thể giúp quản lý tần suất truy vấn của bạn, ở trong giới hạn tốc độ của trang web và giảm khả năng kích hoạt các biện pháp chống xẹp.
  4. Bỏ qua nghi ngờ máy chủ: Kết hợp các tiêu đề bắt chước các tiêu đề của một trình duyệt điển hình, chẳng hạn như tác nhân người dùng, có thể làm cho các yêu cầu cạo của bạn xuất hiện giống như các yêu cầu người dùng thông thường. Điều này có thể ngăn máy chủ gắn cờ các hoạt động của bạn là đáng ngờ.

Bước 1: Chuẩn bị cái cào

Đối với hướng dẫn này, chúng tôi sẽ sử dụng thư viện yêu cầu của Python để tải xuống nội dung web, LXML để phân tích cú pháp HTML và tùy chọn thư viện JSON để xử lý dữ liệu được định dạng khi cần. Đầu tiên, cài đặt các thư viện cần thiết.

Cài đặt các thư viện

Trước khi bắt đầu, bạn cần cài đặt các thư viện Python cần thiết. Chạy lệnh sau trong thiết bị đầu cuối của bạn để cài đặt chúng:


pip install requests lxml

Các thư viện này sẽ được sử dụng để thực hiện các yêu cầu HTTP, nội dung phân tích HTML và xử lý dữ liệu được trích xuất.

Định cấu hình tiêu đề yêu cầu HTTP

Để làm cho các yêu cầu của chúng tôi giống với các yêu cầu từ một trình duyệt web thực sự, điều quan trọng là phải thiết lập các tiêu đề HTTP phù hợp. Dưới đây là một ví dụ về cách bạn có thể định cấu hình các tiêu đề này trong tập lệnh của mình:


import requests

headers = {
    'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
    'accept-language': 'en-IN,en;q=0.9',
    'cache-control': 'no-cache',
    'dnt': '1',  # Không theo dõi tiêu đề
    'pragma': 'no-cache',
    'sec-ch-ua': '"Google Chrome";v="129", "Not=A?Brand";v="8", "Chromium";v="129"',
    'sec-ch-ua-mobile': '?0',
    'sec-ch-ua-platform': '"Linux"',
    'sec-fetch-dest': 'document',
    'sec-fetch-mode': 'navigate',
    'sec-fetch-site': 'none',
    'sec-fetch-user': '?1',
    'upgrade-insecure-requests': '1',
    'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36',
}

response = requests.get('https://www.imdb.com/chart/top/', headers=headers)

Thiết lập proxy

Proxy rất hữu ích cho việc cạo quy mô lớn. Chúng giúp bạn tránh bị chặn bằng cách phân phối các yêu cầu của bạn trên nhiều IPS. Tại đây, cách bạn có thể bao gồm một proxy:


proxies = {
    "http": "http://your_proxy_server",
    "https": "https://your_proxy_server"
}

response = requests.get('https://www.imdb.com/chart/top/', headers=headers, proxies=proxies)

Thay thế "your_proxy_server" bằng các chi tiết proxy thực tế mà bạn có quyền truy cập. Điều này đảm bảo rằng địa chỉ IP của bạn không bị lộ và nó giúp tránh bị chặn.

Bước 2: Phân tích nội dung HTML

Sau khi tìm nạp nội dung trang web, chúng tôi cần phân tích nó để trích xuất chi tiết phim. Chúng tôi sẽ sử dụng LXML để phân tích HTML và JSON để xử lý dữ liệu có cấu trúc:


from lxml.html import fromstring
import json

# Phân tích phản hồi HTML
parser = fromstring(response.text)

# Trích xuất dữ liệu JSON-LD (dữ liệu có cấu trúc) từ thẻ tập lệnh
raw_data = parser.xpath('//script[@type="application/ld+json"]/text()')[0]
json_data = json.loads(raw_data)

# Bây giờ chúng tôi đã cấu trúc dữ liệu phim ở định dạng JSON

Bước 3: Trích xuất chi tiết phim

Trang Top 250 của IMDB bao gồm dữ liệu có cấu trúc được nhúng trong HTML, có thể dễ dàng truy cập bằng Xpath và được phân tích cú pháp dưới dạng JSON. Chúng tôi sẽ trích xuất các chi tiết phim như tên, mô tả, xếp hạng, thể loại, v.v.


movies_details = json_data.get('itemListElement')

# Vòng qua dữ liệu phim
movies_data = []
for movie in movies_details:
    movie_type = movie['item']['@type']
    url = movie['item']['url']
    name = movie['item']['name']
    description = movie['item']['description']
    image = movie['item']['image']
    bestRating = movie['item']['aggregateRating']['bestRating']
    worstRating = movie['item']['aggregateRating']['worstRating']
    ratingValue = movie['item']['aggregateRating']['ratingValue']
    ratingCount = movie['item']['aggregateRating']['ratingCount']
    contentRating = movie['item'].get('contentRating')
    genre = movie['item']['genre']
    duration = movie['item']['duration']
    
    # Nối dữ liệu của mỗi bộ phim vào danh sách
    movies_data.append({
        'movie_type': movie_type,
        'url': url,
        'name': name,
        'description': description,
        'image': image,
        'bestRating': bestRating,
        'worstRating': worstRating,
        'ratingValue': ratingValue,
        'ratingCount': ratingCount,
        'contentRating': contentRating,
        'genre': genre,
        'duration': duration
    })

Bước 4: Lưu trữ dữ liệu

Khi dữ liệu được trích xuất, điều quan trọng là lưu trữ nó theo định dạng mà dễ dàng phân tích. Trong trường hợp này, chúng tôi sẽ lưu nó vào tệp CSV bằng thư viện Pandas:


import pandas as pd

# Chuyển đổi danh sách các bộ phim thành một khung dữ liệu gấu trúc
df = pd.DataFrame(movies_data)

# Lưu dữ liệu vào tệp CSV
df.to_csv('imdb_top_250_movies.csv', index=False)

print("IMDB Top 250 movies data saved to imdb_top_250_movies.csv")

Hoàn thành Mã

Tại đây, mã hoàn chỉnh để cạo 250 bộ phim hàng đầu của IMDB:


import requests
from lxml.html import fromstring
import json
import pandas as pd

# Xác định tiêu đề cho yêu cầu
headers = {
    'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
    'accept-language': 'en-IN,en;q=0.9',
    'cache-control': 'no-cache',
    'dnt': '1',
    'pragma': 'no-cache',
    'sec-ch-ua': '"Google Chrome";v="129", "Not=A?Brand";v="8", "Chromium";v="129"',
    'sec-ch-ua-mobile': '?0',
    'sec-ch-ua-platform': '"Linux"',
    'sec-fetch-dest': 'document',
    'sec-fetch-mode': 'navigate',
    'sec-fetch-site': 'none',
    'sec-fetch-user': '?1',
    'upgrade-insecure-requests': '1',
    'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36',
}

# Tùy chọn, thiết lập proxy
proxies = {
    "http": "http://your_proxy_server",
    "https": "https://your_proxy_server"
}

# Gửi yêu cầu đến trang Top 250 của IMDB
response = requests.get('https://www.imdb.com/chart/top/', headers=headers, proxies=proxies)

# Phân tích phản hồi HTML
parser = fromstring(response.text)

# Trích xuất dữ liệu JSON-LD
raw_data = parser.xpath('//script[@type="application/ld+json"]/text()')[0]
json_data = json.loads(raw_data)

# Trích xuất chi tiết phim
movies_details = json_data.get('itemListElement')

movies_data = []
for movie in movies_details:
    movie_type = movie['item']['@type']
    url = movie['item']['url']
    name = movie['item']['name']
    description = movie['item']['description']
    image = movie['item']['image']
    bestRating = movie['item']['aggregateRating']['bestRating']
    worstRating = movie['item']['aggregateRating']['worstRating']
    ratingValue = movie['item']['aggregateRating']['ratingValue']
    ratingCount = movie['item']['aggregateRating']['ratingCount']
    contentRating = movie['item'].get('contentRating')
    genre = movie['item']['genre']
    duration = movie['item']['duration']
    
    movies_data.append({
        'movie_type': movie_type,
        'url': url,
        'name': name,
        'description': description,
        'image': image,
        'bestRating': bestRating,
        'worstRating': worstRating,
        'ratingValue': ratingValue,
        'ratingCount': ratingCount,
        'contentRating': contentRating,
        'genre': genre,
        'duration': duration
    })

# Lưu dữ liệu vào tệp CSV
df = pd.DataFrame(movies_data)
df.to_csv('imdb_top_250_movies.csv', index=False)
print("IMDB Top 250 movies data saved to imdb_top_250_movies.csv")

Cân nhắc đạo đức

Trước khi loại bỏ bất kỳ trang web nào, điều quan trọng là phải xem xét các vấn đề đạo đức và pháp lý:

  • Tôn trọng các robot.txt: Kiểm tra tệp robot.txt IMDB để xem phần nào của trang web được phép cạo. Luôn tuân thủ các chính sách của trang web.
  • Tránh quá tải máy chủ: Quét dữ liệu có trách nhiệm bằng cách giới hạn tần suất các yêu cầu của bạn để tránh đặt tải không cần thiết lên máy chủ.
  • Tôn trọng Điều khoản dịch vụ: Đảm bảo rằng Scraping không vi phạm các điều khoản dịch vụ của IMDB.

Luôn luôn chú ý đến các quy tắc và sử dụng quét web cho các mục đích hợp pháp.

Bình luận:

0 Bình luận