Як зібрати дані з Google Flights

Як виконати вебскрапінг Google Flights за допомогою Python: покроковий посібник

Тут я покажу, як створити Google Flights вебскрапер на Python із бібліотекою Playwright. Ми пройдемо все крок за кроком: від налаштування середовища до отримання та збереження даних. Також поділюся порадами щодо розв’язання типових проблем вебскрапінгу, таких як Блокування IP-адрес та CAPTCHA, оскільки такі виклики часто виникають на популярних сайтах на кшталт Google Flights. Розберімося!

Навіщо збирати дані з Google Flights?

Збирання даних з Google Flights відкриває доступ до великого обсягу даних, пов’язаних із авіарейсами, які можна використовувати кількома способами:

  • Tracking Price Changes: Відстежуйте, як з часом змінюються ціни на авіарейси, щоб визначати найкращий час для бронювання.
  • Comparing Flight Options: Знаходьте рейси, що відповідають конкретним вимогам, наприклад без пересадок, з коротшими пересадками або бюджетні альтернативи.
  • Market Analysis: Для бізнесу відстеження даних по авіакомпаніях і маршрутах може дати уявлення про цінові стратегії та ринкові тенденції.
  • Environmental Impact: Витягуйте дані про викиди CO2, щоб оцінити екологічний вплив різних варіантів авіаперельотів.

Найкращі інструменти для автоматизованого збору даних Google Flights

Ось перелік різних інструментів, які допоможуть автоматизувати процес збирання даних і заощадити чимало часу, а також, можливо, ресурсів:

  1. Аналіз авіарейсів від kcelebi
  2. Вебскрапер Google Flights від Bright Data
  3. SerpApi

Let’s start by setting up the environment to build our custom Google Flights scraper.

Крок 1: Налаштування середовища Python

Перш ніж переходити до кодування, переконайтеся, що у вас чисте середовище Python. Найкраще використовувати віртуальне середовище, щоб ізолювати залежності.

Створіть і активуйте віртуальне середовище

Відкрийте термінал і виконайте такі команди:

# Create a virtual environment
python -m venv flights-scraper-env
# Activate the virtual environment
# On Windows:
.\flights-scraper-env\Scripts\activate
# On macOS/Linux:
source flights-scraper-env/bin/activate

Install Necessary Packages

Ми використаємо Playwright для взаємодії з сайтом Google Flights, оскільки він ефективно автоматизує дії на динамічних вебсторінках. Tenacity допоможе з механізмами повторних спроб, щоб підвищити надійність.

# Install required packages
pip install playwright tenacity asyncio
# Install Playwright's browser dependencies
playwright install chromium

Крок 2: Визначте структури даних

Щоб упорядкувати код, ми визначимо класи даних для зберігання параметрів пошуку та даних про рейси, які ми витягуємо.

from dataclasses import dataclass
from typing import Optional
@dataclass
class SearchParameters:
departure: str
destination: str
departure_date: str
return_date: Optional[str] = None
ticket_type: str = "В один бік"
@dataclass
class FlightData:
airline: str
departure_time: str
arrival_time: str
duration: str
stops: str
price: str
co2_emissions: str
emissions_variation: str
  • SearchParameters зберігає деталі, потрібні для пошуку рейсу.
  • FlightData зберігає інформацію про кожен рейс, зокрема авіакомпанію, часи, тривалість, пересадки, ціну та викиди CO2.

Крок 3: Створення класу вебскрапера для авіарейсів

Основна логіка нашого скрапера буде розміщена в класі FlightScraper, який ми створюватимемо поетапно.

Define CSS Selectors

Використання CSS-селекторів дає змогу націлюватися на конкретні елементи сторінки, щоб витягувати такі деталі, як назва авіакомпанії, час вильоту, ціна тощо.

class FlightScraper:
SELECTORS = {
"airline": "div.sSHqwe.tPgKwe.ogfYpf",
"departure_time": 'span[aria-label^="Departure time"]',
"arrival_time": 'span[aria-label^="Arrival time"]',
"duration": 'div[aria-label^="Total duration"]',
"stops": "div.hF6lYb span.rGRiKd",
"price": "div.FpEdX span",
"co2_emissions": "div.O7CXue",
"emissions_variation": "div.N6PNV",
}

Імітуйте заповнення пошукової форми

Ми використаємо асинхронні функції Playwright, щоб імітувати користувача, який заповнює параметри пошуку в Google Flights.

async def _fill_search_form(self, page, params: SearchParameters) -> None:
ticket_type_div = page.locator("div.VfPpkd-TkwUic[jsname='oYxtQd']").first
await ticket_type_div.click()
await page.locator("li").filter(has_text=params.ticket_type).nth(0).click()
from_input = page.locator("input[aria-label='Where from?']")
await from_input.fill(params.departure)
to_input = page.locator("input[aria-label='Where to?']")
await to_input.fill(params.destination)
date_input = page.locator("input[aria-label='Departure date']")
await date_input.fill(params.departure_date)

Завантажити всі доступні рейси

Google Flights часто вимагає, щоб користувачі натискали “Show more flights”, аби побачити всі варіанти. Автоматизуйте це циклом, який натискає цю кнопку, доки більше рейсів не відображатиметься.

async def _load_all_flights(self, page) -> None:
while True:
try:
more_button = await page.wait_for_selector(
'button[aria-label*="more flights"]', timeout=5000
)
if more_button:
await more_button.click()
await page.wait_for_timeout(2000)
else:
break
except:
break

Extract Flight Data

Коли всі рейси стануть видимими, пройдіться по елементах кожного рейсу та отримайте деталі за допомогою CSS selectors.

async def _extract_flight_data(self, page) -> list[FlightData]:
await page.wait_for_selector("li.pIav2d", timeout=30000)
flights = await page.query_selector_all("li.pIav2d")
flights_data = []
for flight in flights:
flight_info = {}
for key, selector in self.SELECTORS.items():
element = await flight.query_selector(selector)
flight_info[key] = await self._extract_text(element)
flights_data.append(FlightData(**flight_info))
return flights_data

Крок 4: Реалізуйте логіку повторних спроб для надійності

Щоб зробити наш скрапер стійкішим, ми реалізуємо механізм повторних спроб за допомогою бібліотеки tenacity, яка повторює виконання функції, якщо вона натрапляє на певні помилки.

from tenacity import retry, stop_after_attempt, wait_fixed
@retry(stop=stop_after_attempt(3), wait=wait_fixed(5))
async def search_flights(self, params: SearchParameters) -> list[FlightData]:
async with async_playwright() as p:
browser = await p.chromium.launch(headless=True)
context = await browser.new_context()
page = await context.new_page()
await page.goto("https://www.google.com/flights")
await self._fill_search_form(page, params)
flights = await self._extract_flight_data(page)
await browser.close()
return flights

Крок 5: Зберегти результати у JSON-файл

Після того як ви зібрали дані, збережіть їх у файлі JSON для зручного отримання й аналізу.

import json
from datetime import datetime
def save_results(self, flights: list[FlightData], params: SearchParameters) -> str:
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"flight_results_{params.departure}_{params.destination}_{timestamp}.json"
output_data = {
"search_parameters": vars(params),
"flights": [vars(flight) for flight in flights],
}
with open(filename, "w", encoding="utf-8") as f:
json.dump(output_data, f, indent=2, ensure_ascii=False)
return Використання curl_cffi для вебскрапінгу в Python - Data Journal

Крок 6: Запуск вебскрапера

Ось як ініціалізувати скрапер із прикладними параметрами пошуку.

import asyncio
async def main():
scraper = FlightScraper()
params = SearchParameters(
departure="LAX",
destination="JFK",
departure_date="2024–12–01",
ticket_type="В один бік"
)
try:
flights = await scraper.search_flights(params)
scraper.save_results(flights, params)
print("Рейси успішно зібрано.")
except Exception as e:
print(f"Error during flight search: {str(e)}")
if __name__ == "__main__":
asyncio.run(main())

Подолання типових викликів вебскрапінгу: блокування IP і CAPTCHA

Збирання даних у Google Flights має свої унікальні виклики. Ось як їх подолати:

  • IP Blocking: Використовуйте ротаційні проксі, щоб уникнути виявлення з боку антискрапінгових заходів Google.
  • CAPTCHAs: Упровадьте рішення для розв'язання CAPTCHA, наприклад Bright Data’s Web Unlocker, який може автоматично обходити CAPTCHA-виклики.

Conclusion

Збирання даних у Google Flights відкриває глибокі можливості для аналізу туристичних патернів, цін і варіантів авіаперельотів. Налаштувавши вебскрапер на Python із Playwright і дотримуючись кращих практик надійності, ви зможете витягувати цінні дані про рейси для особистого або бізнес-використання. Щоб підвищити ефективність під час масштабування, значно допомагають проксі та інструменти для обробки CAPTCHA. Цей посібник дав вам базові кроки, а з Python ваші можливості вебскрапінгу Google Flights практично безмежні!

Схожі записи