Como extrair dados do IMDB utilizando Python

Comentários: 0

No mundo de hoje, a extração de dados de plataformas sociais online, como o IMDB, pode ser um caminho eficaz para coletar informações relacionadas a filmes muito necessárias para fins de pesquisa ou diversão. Neste tutorial, nós vamos fazer o scraping dos Top 250 filmes no IMDB usando Python e extrair detalhes como títulos de filmes, resumos de filmes, classificações, gêneros e muito mais.

Ao fazer scraping de sites como o IMDB, é crucial simular o comportamento de um usuário real para minimizar o risco de deteção e garantir a recuperação bem-sucedida de dados. Aqui estão algumas estratégias que podem ser empregadas:

  1. Evitar o bloqueio de IP: Os sites geralmente limitam o número de solicitações que podem ser feitas a partir de um único endereço IP para evitar a raspagem. Ao utilizar proxies, pode distribuir os seus pedidos por vários endereços IP, reduzindo o risco de ser bloqueado.
  2. Garantir o anonimato: Os proxies mascaram seu endereço IP real, o que não só ajuda a proteger sua privacidade, mas também torna mais difícil para os sites rastrearem as atividades de raspagem de volta para você.
  3. Cumpra os limites de velocidade: A distribuição de solicitações por meio de vários proxies pode ajudar a gerenciar a frequência de suas consultas, mantendo-se dentro dos limites de taxa do site e reduzindo a probabilidade de acionar medidas anti-raspagem.
  4. Desviar suspeitas do servidor: A incorporação de cabeçalhos que imitam os de um navegador típico, como User-Agent, pode fazer com que suas solicitações de raspagem pareçam mais com solicitações normais do usuário. Isso pode impedir que o servidor sinalize suas atividades como suspeitas.

Passo 1: Preparando o Scraper

Para este tutorial, usaremos a biblioteca requests do Python para baixar o conteúdo da Web, lxml para analisar HTML e, opcionalmente, a biblioteca json para manipular dados formatados quando necessário. Primeiro, instale as bibliotecas necessárias.

Instalando as bibliotecas

Antes de começar, você precisa instalar as bibliotecas Python necessárias. Execute o seguinte comando no seu terminal para as instalar:


pip install requests lxml

Estas bibliotecas serão utilizadas para efetuar pedidos HTTP, analisar o conteúdo HTML e processar os dados extraídos.

Configurando cabeçalhos de solicitação HTTP

Para fazer com que nossas solicitações se assemelhem às de um navegador da Web real, é crucial configurar os cabeçalhos HTTP de acordo. Aqui está um exemplo de como você pode configurar esses cabeçalhos no seu script:


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',  # Cabeçalho "Não rastrear
    '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)

Configuração de Proxies

Os proxies são úteis para raspagem em larga escala. Eles ajudam a evitar o bloqueio, distribuindo suas solicitações por vários IPs. Veja como você pode incluir um 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)

Substitua "your_proxy_server" pelos detalhes reais do proxy aos quais você tem acesso. Isso garante que seu endereço IP não seja exposto e ajuda a evitar o bloqueio.

Passo 2: Analisando o conteúdo HTML

Depois de buscar o conteúdo da página da Web, precisamos analisá-lo para extrair detalhes do filme. Usaremos lxml para analisar o HTML e json para lidar com os dados estruturados:


from lxml.html import fromstring
import json

# Analisar a resposta HTML
parser = fromstring(response.text)

# Extrair os dados JSON-LD (dados estruturados) da etiqueta de script
raw_data = parser.xpath('//script[@type="application/ld+json"]/text()')[0]
json_data = json.loads(raw_data)

# Agora temos dados de filmes estruturados no formato JSON

Passo 3: Extraindo detalhes do filme

A página IMDB Top 250 inclui dados estruturados incorporados no HTML, que podem ser facilmente acessados usando XPath e analisados como JSON. Vamos extrair detalhes do filme, como nome, descrição, classificações, géneros e muito mais:


movies_details = json_data.get('itemListElement')

# Percorrer os dados do filme
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']
    
    # Acrescentar os dados de cada filme à lista
    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
    })

Passo 4: Armazenando os dados

Depois que os dados são extraídos, é importante armazená-los em um formato fácil de analisar. Nesse caso, vamos salvá-los em um arquivo CSV usando a biblioteca pandas:


import pandas as pd

# Converter a lista de filmes para um DataFrame do pandas
df = pd.DataFrame(movies_data)

# Guardar os dados num ficheiro CSV
df.to_csv('imdb_top_250_movies.csv', index=False)

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

Código Completo

Aqui está o código completo para raspar os 250 melhores filmes do IMDB:


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

# Definir cabeçalhos para o pedido
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',
}

# Opcionalmente, configure proxies
proxies = {
    "http": "http://your_proxy_server",
    "https": "https://your_proxy_server"
}

# Enviar o pedido para a página IMDB Top 250
response = requests.get('https://www.imdb.com/chart/top/', headers=headers, proxies=proxies)

# Analisar a resposta HTML
parser = fromstring(response.text)

# Extrair os dados JSON-LD
raw_data = parser.xpath('//script[@type="application/ld+json"]/text()')[0]
json_data = json.loads(raw_data)

# Extrair detalhes do filme
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
    })

# Guardar os dados num ficheiro 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")

Considerações éticas

Antes de fazer scraping de qualquer site, é importante considerar questões éticas e legais:

  • Respeitar o Robots.txt: Verifique o arquivo robots.txt do IMDB para ver quais partes do site são permitidas para raspagem. Sempre aderir às políticas do site.
  • Evite sobrecarregar o servidor: Raspe dados de forma responsável, limitando a frequência de suas solicitações para evitar colocar carga desnecessária no servidor.
  • Respeitar os Termos de Serviço: Certifique-se de que a raspagem não viola os termos de serviço do IMDB.

Esteja sempre atento às regras e use a raspagem da Web para fins legítimos.

Comentários:

0 Comentários