Скрапинг данных Google Flights с использованием Python

Комментарии: 0

Скрапинг данных о рейсах с Google Flights может оказаться крайне полезным для планирования путешествий, анализа конкурентов или исследований в сфере туризма. Далее представлено пошаговое руководство для извлечения информации о рейсах, используя библиотеки Python, Playwright и lxml.

Установка необходимых библиотек

Перед началом процесса скрапинга убедитесь, что установлены необходимые библиотеки Python:

pip install playwright
Pip install lxml

Для использования Playwright также необходимо установить бинарные файлы браузера. В данном случае мы установим только браузер Chromium:

playwright install chromium

Пошаговый процесс скрапинга

Мы сосредоточимся на извлечении данных о рейсах со страницы результатов поиска Google Flights.

Шаг 1. Понимание структуры сайта

Для извлечения данных с Google Flights важно понимать HTML-структуру сайта. Используя инструменты разработчика Chrome (Chrome DevTools), можно проверять элементы и находить необходимые для скрапинга выражения XPath.

  1. Открытие Chrome DevTools: кликните правой кнопкой мыши на странице Google Flights и выберите "Inspect" или нажмите Ctrl+Shift+I (Windows/Linux) или Cmd+Option+I (Mac).
  2. Инспекция элементов: наведите курсор на различные элементы на странице, чтобы выделить и проверить HTML-структуру. Далее кликните на элементы, чтобы увидеть их атрибуты, которые можно использовать для создания выражений XPath.
  3. Поиск выражений XPath: кликните правой кнопкой мыши на нужном элементе в панели Elements, выберите "Copy", а затем "Copy XPath", чтобы получить выражение XPath для этого элемента.

Список используемых выражений XPath:

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

Примечание: Это выражение XPath возвращает несколько элементов, каждый из которых соответствует отдельному рейсу.

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()

Шаг 2. Использование Playwright для отправки HTTP-запросов и извлечения содержимого страницы

Для взаимодействия со страницей и извлечения её содержимого мы применяем Playwright. Этот инструмент особенно эффективен для управления динамическим контентом, который загружается через JavaScript.

Playwright позволяет запустить браузер в режиме без использования графического интерфейса, перейти по указанному URL и извлечь содержимое страницы. Это делает его идеальным выбором для работы с сайтами, где содержимое динамически изменяется или подгружается после выполнения начального запроса.

from playwright.sync_api import sync_playwright

# URL страницы поиска Google Flights
url = "ссылка HTTPS"

def get_page_content(url):
    """ Извлекает HTML-содержимое указанного URL-адреса с помощью Playwright."""
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=True)  # Запуск браузера в режиме без графического интерфейса
        context = browser.new_context()  # Создание нового контекста браузера
        page = context.new_page()  # Открытие новой страницы
        page.goto(url)  # Переход по указанному URL
        content = page.content()  # Получение содержимого страницы
        browser.close()  # Закрытие браузера
    return content

# Получение содержимого страницы
page_content = get_page_content(url)

Шаг 3. Извлечение общих данных рейса с помощью XPath

Далее мы анализируем HTML-содержимое ответа с использованием lxml, чтобы извлечь общие детали рейса, такие как даты отправления и возвращения.

from lxml import html

# Создание парсера
tree = html.fromstring(page_content)

# Извлечение общих данных рейса с использованием XPath
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]  # Получение даты возвращения

Шаг 4. Извлечение конкретных данных о рейсах с использованием lxml

Далее анализируем HTML-содержимое для извлечения конкретной информации о рейсах на основе определенных выражений XPath.

# Инициализация списка для хранения деталей рейсов
flights = []

# Извлечение данных о рейсе из проанализированного HTML с использованием XPath
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()

    # Добавление извлеченных данных в список рейсов в виде словаря
    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
    })

Шаг 5. Сохранение данных в файл CSV

Наконец, мы используем встроенный в Python модуль CSV для сохранения извлеченных данных в файл CSV для дальнейшего анализа.

import csv

# Определение пути к файлу CSV
csv_file = 'google_flights.csv'

# Определение названий полей для CSV
fieldnames = ['Airway', 'Details', 'Departure', 'Arrival', 'Travel Time', 'Price', 'From', 'To', 'Departure Date', 'Return Date']

# Запись данных в файл 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}")

Финальный код

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

# URL страницы поиска рейсов Google Flights
url = "link with https"

def get_page_content(url):
    """ Извлекает HTML-содержимое указанного URL-адреса с помощью Playwright."""
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)  # Запуск браузера в обычном режиме
        context = browser.new_context()  # Создание нового контекста браузера
        page = context.new_page()  # Открытие новой страницы
        page.goto(url)  # Переход на указанный URL
        page.wait_for_timeout(10000)  # Ожидание 10 секунд для полной загрузки страницы
        content = page.content()  # Получение содержимого страницы
        browser.close()  # Закрытие браузера
    return content

# Получение содержимого страницы
page_content = get_page_content(url)

# Разбор HTML-содержимого с использованием lxml
tree = html.fromstring(page_content)

# Извлечение информации о поиске рейсов
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]

# Инициализация списка для хранения данных о рейсах
flights = []

# Извлечение данных о рейсах из проанализированного HTML
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()

    # Добавление данных в список
    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
    })

# Определение пути к файлу CSV
csv_file = 'google_flights.csv'

# Определение названий полей для CSV
fieldnames = ['Airway', 'Details', 'Departure', 'Arrival', 'Travel Time', 'Price', 'From', 'To', 'Departure Date', 'Return Date']

# Запись извлеченных данных в файл 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}")

Чтобы минимизировать риск обнаружения в процессе скрапинга, рекомендуется использовать задержки между запросами и применять прокси. Эти меры помогают обходить системы защиты, предназначенные для блокировки автоматизированных скриптов скрапинга. В качестве прокси лучше выбирать резидентские динамические прокси-сервера, поскольку они обладают высоким уровнем доверия и не подвержены блокировкам. Также можно использовать пул статических ISP прокси, которые обеспечат высокую скорость и стабильность соединения в процессе извлечения данных.

Комментарии:

0 комментариев