Przewodnik po skrobaniu danych z lotów Google za pomocą Pythona

Komentarze: 0

Jeśli chodzi o planowanie podróży, analizę konkurencji lub cele badawcze, skrobanie informacji związanych z lotami z Google Flights może przynieść znaczące spostrzeżenia. Oto samouczek krok po kroku, jak skrobać informacje o lotach za pomocą bibliotek Python, Playwright i lxml.

Konfiguracja środowiska

Przed przystąpieniem do procesu skrobania upewnij się, że masz zainstalowane niezbędne biblioteki Python:

pip install playwright
Pip install lxml

Aby korzystać z Playwright, należy również zainstalować pliki binarne przeglądarki:

playwright install chromium

Proces skrobania krok po kroku

Skupimy się na wyodrębnianiu danych dotyczących lotów ze strony wyników wyszukiwania Google Flights.

Krok 1. Zrozumienie struktury strony

Aby skutecznie skrobać dane z Google Flights, należy zapoznać się ze strukturą HTML witryny. Oto, jak można użyć Chrome DevTools do sprawdzania elementów i pobierania niezbędnych wyrażeń XPath do skrobania:

  1. Otwórz Chrome DevTools klikając prawym przyciskiem myszy na stronie Google Flights i wybierając "Inspect" lub użyj skrótu Ctrl+Shift+I (Windows/Linux) lub Cmd+Option+I (Mac).
  2. Sprawdź elementy, najeżdżając kursorem na różne części strony. Spowoduje to podświetlenie struktury HTML w DevTools. Kliknij na konkretne elementy, aby wyświetlić ich atrybuty, które są kluczowe dla tworzenia dokładnych wyrażeń XPath.
  3. Pobierz wyrażenia XPath, klikając prawym przyciskiem myszy żądany element w panelu Elementy, wybierając opcję "Kopiuj", a następnie wybierając opcję "Kopiuj XPath". Spowoduje to skopiowanie wyrażenia XPath bezpośrednio do schowka, gotowego do użycia w skrypcie skrobiącym.

Lista użytych wyrażeń 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

Uwaga: Ta ścieżka XPath zwraca wiele elementów, z których każdy odpowiada pojedynczemu lotowi.

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

Krok 2. Wysyłanie żądań HTTP i wyodrębnianie zawartości strony za pomocą Playwright

Używamy Playwright do interakcji ze stroną internetową i wyodrębniania jej zawartości. Takie podejście pomaga obsługiwać dynamiczną zawartość, którą może załadować JavaScript.

Korzystanie z Playwright pomaga obsługiwać dynamiczną zawartość ładowaną przez JavaScript. Uruchamia bezgłową przeglądarkę, nawiguje do adresu URL i wyodrębnia zawartość strony.

from playwright.sync_api import sync_playwright

# Adres URL strony wyszukiwania lotów Google
url = "https link"

def get_page_content(url):
    """Fetches the HTML content of the given URL using Playwright."""
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=True)  # Uruchom przeglądarkę w trybie bezgłowym
        context = browser.new_context()  # Utwórz nowy kontekst przeglądarki
        page = context.new_page()  # Otwórz nową stronę
        page.goto(url)  # Przejście do określonego adresu URL
        content = page.content()  # Pobierz zawartość strony
        browser.close()  # Zamknij przeglądarkę
    return content

# Pobieranie zawartości strony
page_content = get_page_content(url)

Krok 3. Wyodrębnianie wspólnych szczegółów za pomocą XPath

Następnie analizujemy zawartość HTML odpowiedzi za pomocą lxml, aby wyodrębnić typowe szczegóły lotu, takie jak daty wylotu i powrotu.

from lxml import html

# Tworzenie parsera
tree = html.fromstring(page_content)

# Wyodrębnianie typowych szczegółów lotu przy użyciu XPath
from_location = tree.xpath('//input[@aria-label="Where from?"]/@value')[0]  # Pobierz lokalizację "od"
to_location = tree.xpath('//input[@aria-label="Where to?"]/@value')[0]  # Uzyskaj lokalizację "do"
departure_date = tree.xpath('//input[@placeholder="Departure"]/@value')[0]  # Uzyskaj datę odlotu
return_date = tree.xpath('//input[@placeholder="Return"]/@value')[0]  # Uzyskaj datę powrotu

Krok 4. Wyodrębnianie określonych danych lotu przy użyciu lxml

Następnie analizujemy zawartość HTML, aby wyodrębnić określone informacje o locie na podstawie zidentyfikowanych wyrażeń XPath.

# Zainicjuj pustą listę do przechowywania szczegółów lotu
flights = []

# Wyodrębnij elementy lotu z przeanalizowanego kodu HTML za pomocą XPath
flight_elements = tree.xpath('//li[@class="pIav2d"]')

# Pętla przechodzi przez każdy element lotu i wyodrębnia szczegóły
for flight in flight_elements:
    # Wyodrębnij nazwę linii lotniczej
    airway = flight.xpath('.//div[@class="sSHqwe tPgKwe ogfYpf"]/span/text()')[0].strip()
    
    # Wyodrębnianie szczegółów lotu, takich jak międzylądowania
    details = flight.xpath('.//span[@class="mv1WYe"]/@aria-label')[0]
    
    # Wyodrębnij czas odlotu
    departure = flight.xpath('.//span[@jscontroller="cNtv4b"]/span/text()')[0].strip()
    
    # Wyodrębnij czas przybycia
    arrival = flight.xpath('.//span[@jscontroller="cNtv4b"]/span/text()')[1].strip()
    
    # Wyodrębnij całkowity czas podróży
    travel_time = flight.xpath('.//div[@class="gvkrdb AdWm1c tPgKwe ogfYpf"]/text()')[0].strip()
    
    # Wyodrębnij cenę lotu
    price = flight.xpath('.//div[@class="U3gSDe"]/div/div[2]/span/text()')[0].strip()

    # Dołącz wyodrębnione szczegóły do listy lotów jako słownik
    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
    })

Krok 5. Zapisywanie danych do CSV

Na koniec używamy wbudowanego modułu CSV Pythona, aby zapisać wyodrębnione dane do pliku CSV w celu dalszej analizy.

import csv

# Definiowanie ścieżki pliku CSV
csv_file = 'google_flights.csv'

# Definiowanie nazw pól CSV
fieldnames = ['Airway', 'Details', 'Departure', 'Arrival', 'Travel Time', 'Price', 'From', 'To', 'Departure Date', 'Return Date']

# Zapisywanie danych do pliku 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}")

Składanie wszystkiego razem

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

# Adres URL strony wyszukiwania lotów Google
url = "https link"

def get_page_content(url):
    """Pobiera zawartość HTML podanego adresu URL za pomocą Playwright."""
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)  # Uruchom przeglądarkę w trybie headful
        context = browser.new_context()  # Utwórz nowy kontekst przeglądarki
        page = context.new_page()  # Otwórz nową stronę
        page.goto(url)  # Przejście do określonego adresu URL
        page.wait_for_timeout(10000)  # Poczekaj 10 sekund, aby upewnić się, że strona załaduje się w całości.
        content = page.content()  # Pobierz zawartość strony
        browser.close()  # Zamknij przeglądarkę
    return content

# Pobieranie zawartości strony
page_content = get_page_content(url)

# Parsowanie zawartości HTML przy użyciu lxml
tree = html.fromstring(page_content)

# Wyodrębnianie szczegółów wyszukiwania lotów
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]

# Inicjalizacja listy do przechowywania szczegółów lotu
flights = []

# Wyodrębnij elementy lotu z przeanalizowanego kodu 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()

    # Dołącz szczegóły lotu do listy
    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
    })

# Zdefiniuj ścieżkę pliku CSV
csv_file = 'google_flights.csv'

# Definiowanie nazw pól CSV
fieldnames = ['Airway', 'Details', 'Departure', 'Arrival', 'Travel Time', 'Price', 'From', 'To', 'Departure Date', 'Return Date']

# Zapisywanie wyodrębnionych szczegółów lotu do pliku CSV
with open(csv_file, mode='w', newline='', encoding='utf-8') as file:
    writer = csv.DictWriter(file, fieldnames=fieldnames)
    writer.writeheader()  # Zapisz wiersz nagłówka
    for flight in flights:
        writer.writerow(flight)  # Zapisz szczegóły każdego lotu

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

Aby zmniejszyć ryzyko wykrycia podczas skrobania danych, zaleca się wprowadzanie opóźnień między żądaniami i korzystanie z serwerów proxy. Wdrożenie opóźnień pomaga naśladować ludzką interakcję, utrudniając stronom internetowym wykrywanie zautomatyzowanych działań scrapingowych. W przypadku wyboru serwera proxy zaleca się stosowanie dynamicznych serwerów proxy, ponieważ oferują one wysoki poziom zaufania i są mniej podatne na blokowanie ze względu na ich dynamiczny charakter. Alternatywnie, można użyć puli statycznych serwerów proxy ISP, które zapewniają stabilne i szybkie połączenie, zwiększając niezawodność procesu pozyskiwania danych. Strategie te pomagają uniknąć środków ochronnych stosowanych przez strony internetowe w celu identyfikacji i blokowania botów scrapingowych.

Komentarze:

0 komentarze