Guia para a recolha de dados do Google Flights com Python

Comentários: 0

Quando se trata de planeamento de viagens, análise de concorrência ou fins de pesquisa, a recolha de informações relacionadas com voos do Google Flights pode produzir informações significativas. Aqui está um tutorial passo a passo sobre como extrair informações de voos usando as bibliotecas Python, Playwright e lxml.

Configurando seu ambiente

Antes de mergulhar no processo de scraping, certifique-se de ter as bibliotecas Python necessárias instaladas:

pip install playwright
Pip install lxml

To use Playwright, you also need to install the browser binaries:

playwright install chromium

Processo de raspagem passo a passo

Vamos concentrar-nos na extração de dados de voos da página de resultados de pesquisa do Google Flights.

Passo 1. Entendendo a estrutura do site

Para extrair dados do Google Flights de forma eficaz, tem de se familiarizar com a estrutura HTML do Web site. Eis como pode utilizar o Chrome DevTools para inspecionar elementos e obter as expressões XPath necessárias para a recolha de dados:

  1. Abra o Chrome DevTools clicando com o botão direito do rato na página do Google Flights e selecionando "Inspecionar", ou utilize o atalho Ctrl+Shift+I (Windows/Linux) ou Cmd+Option+I (Mac).
  2. Inspecione os elementos passando o mouse sobre diferentes partes da página. Isso destacará a estrutura HTML no DevTools. Clique nos elementos específicos para ver seus atributos, que são cruciais para criar expressões XPath precisas.
  3. Recupere expressões XPath clicando com o botão direito do mouse no elemento desejado no painel Elementos, selecionando "Copiar" e, em seguida, escolhendo "Copiar XPath". Isso copia a expressão XPath diretamente para a área de transferência, pronta para ser usada no seu script de raspagem.

Lista de expressões XPath usadas:

From Location: //input[@aria-label="Where from?"]/@value
To Location: //input[@aria-label="Where to?"]/@value
Departure Date: //input[@placeholder="Departure"]/@value
Return Date: //input[@placeholder="Return"]/@value

Nota: Este XPath devolve múltiplos elementos, cada um correspondendo a um voo individual.

Flight Elements: //li[@class="pIav2d"]
Airway: .//div[@class="sSHqwe tPgKwe ogfYpf"]/span/text()
Details: .//span[@class="mv1WYe"]/@aria-label
Departure Time: .//span[@aria-describedby="gEvJbfc1583"]/span/text()
Arrival Time: .//span[@aria-describedby="gEvJbfc1584"]/span/text()
Travel Time: .//div[@class="gvkrdb AdWm1c tPgKwe ogfYpf"]/text()
Price: .//div[@class="YMlIz FpEdX"]/span/text()

Passo 2. Envio de solicitações HTTP e extração do conteúdo da página com o Playwright

Usamos o Playwright para interagir com a página da Web e extrair seu conteúdo. Essa abordagem ajuda a lidar com o conteúdo dinâmico que o JavaScript pode carregar.

O uso do Playwright ajuda a lidar com o conteúdo dinâmico carregado pelo JavaScript. Ele inicia um navegador sem cabeça, navega até o URL e extrai o conteúdo da página.

from playwright.sync_api import sync_playwright

# URL da página de pesquisa do Google Flights
url = "https link"

def get_page_content(url):
    """Obtém o conteúdo HTML do URL fornecido usando o Playwright."""
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=True)  # Iniciar o browser em modo headless
        context = browser.new_context()  # Criar um novo contexto de browser
        page = context.new_page()  # Abrir uma nova página
        page.goto(url)  # Navegar para o URL especificado
        content = page.content()  # Obter o conteúdo da página
        browser.close()  # Fechar o browser
    return content

# Obter o conteúdo da página
page_content = get_page_content(url)

Passo 3. Extraindo detalhes comuns usando XPath

Em seguida, analisamos o conteúdo HTML da resposta usando lxml para extrair detalhes comuns do voo, como datas de partida e retorno.

from lxml import html

# Criar o analisador
tree = html.fromstring(page_content)

# Extrair detalhes de voos comuns utilizando XPath
from_location = tree.xpath('//input[@aria-label="Where from?"]/@value')[0]  # Obter a localização "de
to_location = tree.xpath('//input[@aria-label="Where to?"]/@value')[0]  # Obter a localização "para
departure_date = tree.xpath('//input[@placeholder="Departure"]/@value')[0]  # Obter a data de partida
return_date = tree.xpath('//input[@placeholder="Return"]/@value')[0]  # Obter a data de regresso

Passo 4. Extrair dados de voo específicos usando lxml

Em seguida, analisamos o conteúdo HTML para extrair informações específicas sobre o voo com base nas expressões XPath identificadas.

# Inicializar uma lista vazia para armazenar os detalhes do voo
flights = []

# Extrair elementos de voo do HTML analisado usando XPath
flight_elements = tree.xpath('//li[@class="pIav2d"]')

# Percorrer cada elemento de voo e extrair pormenores
for flight in flight_elements:
    # Extrair o nome da companhia aérea
    airway = flight.xpath('.//div[@class="sSHqwe tPgKwe ogfYpf"]/span/text()')[0].strip()
    
    # Extrair detalhes do voo, tais como escalas
    details = flight.xpath('.//span[@class="mv1WYe"]/@aria-label')[0]
    
    # Extrair a hora de partida
    departure = flight.xpath('.//span[@jscontroller="cNtv4b"]/span/text()')[0].strip()
    
    # Extrair a hora de chegada
    arrival = flight.xpath('.//span[@jscontroller="cNtv4b"]/span/text()')[1].strip()
    
    # Extrair o tempo total de viagem
    travel_time = flight.xpath('.//div[@class="gvkrdb AdWm1c tPgKwe ogfYpf"]/text()')[0].strip()
    
    # Extrair o preço do voo
    price = flight.xpath('.//div[@class="U3gSDe"]/div/div[2]/span/text()')[0].strip()

    # Anexar os detalhes extraídos à lista de voos como um dicionário
    flights.append({
        'Airway': airway,
        'Details': details,
        'Departure': departure,
        'Arrival': arrival,
        'Travel Time': travel_time,
        'Price': price,
        'From': from_location,
        'To': to_location,
        'Departure Date': departure_date,
        'Return Date': return_date
    })

Passo 5. Salvando dados em CSV

Finalmente, usamos o módulo CSV embutido do Python para salvar os dados extraídos em um arquivo CSV para análise posterior.

import csv

# Definir o caminho do ficheiro CSV
csv_file = 'google_flights.csv'

# Definir nomes de campos CSV
fieldnames = ['Airway', 'Details', 'Departure', 'Arrival', 'Travel Time', 'Price', 'From', 'To', 'Departure Date', 'Return Date']

# Escrever dados num ficheiro CSV
with open(csv_file, mode='w', newline='', encoding='utf-8') as file:
    writer = csv.DictWriter(file, fieldnames=fieldnames)
    writer.writeheader()
    for flight in flights:
        writer.writerow(flight)

print(f"Data saved to {csv_file}")

Colocar tudo junto

from playwright.sync_api import sync_playwright
from lxml import html
import csv

# URL da página de pesquisa do Google Flights
url = "https link"

def get_page_content(url):
    """Obtém o conteúdo HTML do URL fornecido usando o Playwright."""
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)  # Iniciar o browser em modo headful
        context = browser.new_context()  # Criar um novo contexto de browser
        page = context.new_page()  # Abrir uma nova página
        page.goto(url)  # Navegar para o URL especificado
        page.wait_for_timeout(10000)  # Aguarde 10 segundos para garantir que a página carrega completamente
        content = page.content()  # Obter o conteúdo da página
        browser.close()  # Fechar o browser
    return content

# Obter o conteúdo da página
page_content = get_page_content(url)

# Analisar o conteúdo HTML utilizando lxml
tree = html.fromstring(page_content)

# Extrair detalhes da pesquisa de voos
from_location = tree.xpath('//input[@aria-label="Where from?"]/@value')[0]
to_location = tree.xpath('//input[@aria-label="Where to?"]/@value')[0]
departure_date = tree.xpath('//input[@placeholder="Departure"]/@value')[0]
return_date = tree.xpath('//input[@placeholder="Return"]/@value')[0]

# Inicializar uma lista para armazenar os detalhes do voo
flights = []

# Extrair elementos de voo do HTML analisado
flight_elements = tree.xpath('//li[@class="pIav2d"]')
for flight in flight_elements:
    airway = flight.xpath('.//div[@class="sSHqwe tPgKwe ogfYpf"]/span/text()')[0].strip()
    details = flight.xpath('.//span[@class="mv1WYe"]/@aria-label')[0]
    departure = flight.xpath('.//span[@jscontroller="cNtv4b"]/span/text()')[0].strip()
    arrival = flight.xpath('.//span[@jscontroller="cNtv4b"]/span/text()')[1].strip()
    travel_time = flight.xpath('.//div[@class="gvkrdb AdWm1c tPgKwe ogfYpf"]/text()')[0].strip()
    price = flight.xpath('.//div[@class="U3gSDe"]/div/div[2]/span/text()')[0].strip()

    # Anexar detalhes do voo à lista
    flights.append({
        'Airway': airway,
        'Details': details,
        'Departure': departure,
        'Arrival': arrival,
        'Travel Time': travel_time,
        'Price': price,
        'From': from_location,
        'To': to_location,
        'Departure Date': departure_date,
        'Return Date': return_date
    })

# Definir o caminho do ficheiro CSV
csv_file = 'google_flights.csv'

# Definir nomes de campos CSV
fieldnames = ['Airway', 'Details', 'Departure', 'Arrival', 'Travel Time', 'Price', 'From', 'To', 'Departure Date', 'Return Date']

# Escrever os detalhes de voo extraídos para um ficheiro CSV
with open(csv_file, mode='w', newline='', encoding='utf-8') as file:
    writer = csv.DictWriter(file, fieldnames=fieldnames)
    writer.writeheader()  # Escrever a linha de cabeçalho
    for flight in flights:
        writer.writerow(flight)  # Escrever os dados de cada voo

print(f"Data saved to {csv_file}")

Para reduzir o risco de deteção durante a raspagem de dados, é aconselhável incorporar atrasos entre os pedidos e utilizar proxies. A implementação de atrasos ajuda a imitar a interação humana, dificultando a deteção de actividades automatizadas de recolha de dados por parte dos sítios Web. Para a seleção de proxy, recomenda-se a utilização de proxies dinâmicos residenciais porque oferecem um elevado nível de confiança e têm menos probabilidades de serem bloqueados devido à sua natureza dinâmica. Em alternativa, pode utilizar um conjunto de proxies ISP estáticos, que fornecem uma ligação estável e rápida, aumentando a fiabilidade do seu processo de extração de dados. Estas estratégias ajudam a contornar as medidas de proteção que os sítios Web utilizam para identificar e bloquear os bots de raspagem.

Comentários:

0 Comentários