Como extrair dados do Booking.com usando Python

Comentários: 0

Neste artigo, vamos demonstrar como recolher dados do site Booking.com com Python. Iremos obter informações que incluem, mas não se limitam a, nomes de hotéis, classificações, preços, endereços de localização e respectivas descrições. O código fornecido permite-lhe obter dados de páginas de hotéis analisando o conteúdo HTML e extraindo dados JSON incorporados.

Instalando as bibliotecas necessárias

Antes de executar o código para extrair dados do Booking.com, você precisará instalar as bibliotecas Python necessárias. Veja como você pode instalar as dependências necessárias:

  1. Requests Biblioteca: É utilizada para enviar pedidos HTTP ao sítio Web e obter o conteúdo HTML das páginas.
  2. LXML Biblioteca: É utilizada para analisar o conteúdo HTML e extrair dados utilizando XPath.
  3. JSON: Módulo Python incorporado utilizado para tratar dados JSON.
  4. CSV: Módulo Python incorporado utilizado para escrever dados recolhidos num ficheiro CSV.

Para instalar as bibliotecas necessárias, você pode usar pip:


pip install requests lxml

Estas são as únicas bibliotecas externas que precisa, e as restantes (json, csv) vêm pré-instaladas com o Python.

Entendendo a URL e a estrutura de dados

Ao extrair dados do Booking.com, é importante entender a estrutura da página da web e o tipo de dados que você deseja extrair. Cada página de hotel no Booking.com contém dados estruturados incorporados na forma de JSON-LD, um formato que permite a fácil extração de detalhes como nome, localização e preços. Iremos extrair estes dados.

Processo de raspagem passo a passo

Como o Booking.com é um site dinâmico e implementa medidas para combater ações automatizadas, usaremos cabeçalhos HTTP e proxies apropriados para garantir uma raspagem perfeita sem o risco de bloqueio.

Envio de pedidos HTTP com cabeçalhos

Os cabeçalhos imitam uma sessão de usuário em um navegador e impedem a deteção pelos sistemas anti-raspagem da Booking.com. Sem cabeçalhos configurados corretamente, o servidor pode identificar facilmente scripts automatizados, o que pode levar ao bloqueio de IP ou desafios de captcha.

Para evitar ser bloqueado pelos mecanismos anti-raspagem da Booking.com, usaremos cabeçalhos personalizados para simular um utilizador legítimo a navegar no site. Veja como você pode enviar uma solicitação HTTP com cabeçalhos adequados:


import requests
from lxml.html import fromstring

urls_list = ["https links"]

for url in urls_list:
    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',
        'priority': 'u=0, i',
        'sec-ch-ua': '"Chromium";v="130", "Google Chrome";v="130", "Not?A_Brand";v="99"',
        '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/130.0.0.0 Safari/537.36',
    }

    response = requests.get(url, headers=headers)

Importância dos proxies

O uso de proxies é necessário ao raspar sites como Booking.com, que aplicam limites rígidos de taxa de solicitação ou rastreiam endereços IP. Os proxies ajudam a distribuir a carga de pedidos por diferentes endereços IP, evitando bloqueios. Para este efeito, podem ser utilizados proxies gratuitos e serviços de proxy pagos com autenticação por nome de utilizador e palavra-passe ou endereço IP. No nosso exemplo, usamos a última opção.


proxies = {
    'http': '',
    'https': ''
}
response = requests.get(url, headers=headers, proxies=proxies)

Comparando o HTML e extraindo dados JSON

Depois de enviar a solicitação, analisamos o conteúdo HTML usando lxml para localizar os dados JSON-LD incorporados que contêm detalhes do hotel. Esta etapa extrai os dados estruturados da página da Web que incluem nomes de hotéis, preços, locais e muito mais.


parser = fromstring(response.text)

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

Extração de informações sobre o hotel

Quando tivermos os dados JSON analisados, podemos extrair campos relevantes, como nome do hotel, endereço, classificação e preço. Abaixo está o código para extrair as informações do hotel do JSON:


name = json_data['name']
location = json_data['hasMap']
priceRange = json_data['priceRange']
description = json_data['description']
url = json_data['url']
ratingValue = json_data['aggregateRating']['ratingValue']
reviewCount = json_data['aggregateRating']['reviewCount']
type_ = json_data['@type']
postalCode = json_data['address']['postalCode']
addressLocality = json_data['address']['addressLocality']
addressCountry = json_data['address']['addressCountry']
addressRegion = json_data['address']['addressRegion']
streetAddress = json_data['address']['streetAddress']
image_url = json_data['image']
room_types = parser.xpath("//a[contains(@href, '#RD')]/span/text()")

# Anexar os dados à lista all_data
all_data.append({
    "Name": name,
    "Location": location,
    "Price Range": priceRange,
    "Rating": ratingValue,
    "Review Count": reviewCount,
    "Type": type_,
    "Postal Code": postalCode,
    "Address Locality": addressLocality,
    "Country": addressCountry,
    "Region": addressRegion,
    "Street Address": streetAddress,
    "URL": url,
    "Image URL": image_url,
    "Room Types": room_types
})

Guardar os dados em CSV

Uma vez que os dados tenham sido extraídos, podemos salvá-los em um arquivo CSV para análise posterior:


# Depois de todos os URLs serem processados, escreva os dados num ficheiro CSV
with open('booking_data.csv', 'w', newline='') as csvfile:
    fieldnames = ["Name", "Location", "Price Range", "Rating", "Review Count", "Type", "Postal Code", 
                  "Address Locality", "Country", "Region", "Street Address", "URL", "Image URL", "Room Types"]
    
    writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
    
    # Escrever o cabeçalho
    writer.writeheader()
    
    # Escrever as linhas de dados
    writer.writerows(all_data)

Complete code

Eis o código completo que combina todas as secções:


import requests
from lxml.html import fromstring
import json
import csv

# Lista de URLs de hotéis a recolher
urls_list = [
    "Https link", 
    "Https link"
]

# Inicializar uma lista vazia para guardar todos os dados recolhidos
all_data = []

proxies = {
    'http': ''
}

# Percorrer cada URL para extrair dados
for url in urls_list:
    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',
        'priority': 'u=0, i',
        'sec-ch-ua': '"Chromium";v="130", "Google Chrome";v="130", "Not?A_Brand";v="99"',
        '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/130.0.0.0 Safari/537.36',
    }

    # Enviar o pedido para o sítio Web
    response = requests.get(url, headers=headers, proxies=proxies)
    
    # Analisar o conteúdo HTML
    parser = fromstring(response.text)
    
    # Extrair dados JSON incorporados
    embeded_jsons = parser.xpath('//script[@type="application/ld+json"]/text()')
    json_data = json.loads(embeded_jsons[0])

    # Extrair todos os detalhes do hotel do JSON
    name = json_data['name']
    location = json_data['hasMap']
    priceRange = json_data['priceRange']
    description = json_data['description']
    url = json_data['url']
    ratingValue = json_data['aggregateRating']['ratingValue']
    reviewCount = json_data['aggregateRating']['reviewCount']
    type_ = json_data['@type']
    postalCode = json_data['address']['postalCode']
    addressLocality = json_data['address']['addressLocality']
    addressCountry = json_data['address']['addressCountry']
    addressRegion = json_data['address']['addressRegion']
    streetAddress = json_data['address']['streetAddress']
    image_url = json_data['image']

    room_types = parser.xpath("//a[contains(@href, '#RD')]/span/text()")
    
    # Anexar os dados à lista all_data
    all_data.append({
        "Name": name,
        "Location": location,
        "Price Range": priceRange,
        "Rating": ratingValue,
        "Review Count": reviewCount,
        "Type": type_,
        "Postal Code": postalCode,
        "Address Locality": addressLocality,
        "Country": addressCountry,
        "Region": addressRegion,
        "Street Address": streetAddress,
        "URL": url,
        "Image URL": image_url,
        "Room Types": room_types
    })

# Depois de todos os URLs serem processados, escreva os dados num ficheiro CSV
with open('booking_data.csv', 'w', newline='') as csvfile:
    fieldnames = ["Name", "Location", "Price Range", "Rating", "Review Count", "Type", "Postal Code", 
                  "Address Locality", "Country", "Region", "Street Address", "URL", "Image URL", "Room Types"]
    
    writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
    
    # Escrever o cabeçalho
    writer.writeheader()
    
    # Escrever as linhas de dados
    writer.writerows(all_data)

print("Data successfully saved to booking_data.csv")

Este artigo mostrou como extrair dados de hotéis do Booking.com usando Python. Salientámos a importância de utilizar cabeçalhos HTTP e proxies adequados para contornar as medidas anti-rastreamento. Os dados extraídos podem ser guardados num ficheiro CSV para análise posterior. Ao fazer scraping de sites, verifique sempre os termos de serviço para evitar violações.

Comentários:

0 Comentários