파이썬을 사용한 Google 항공편 데이터 스크래핑 가이드

댓글: 0

여행 계획, 경쟁사 분석 또는 연구 목적의 경우 Google 항공편에서 항공편 관련 정보를 스크랩하면 상당한 인사이트를 얻을 수 있습니다. 다음은 Python, Playwright 및 lxml 라이브러리를 사용하여 항공편 정보를 스크랩하는 방법에 대한 단계별 자습서입니다.

환경 설정하기

스크래핑 프로세스를 시작하기 전에 필요한 Python 라이브러리가 설치되어 있는지 확인하세요:

pip install playwright
Pip install lxml

Playwright를 사용하려면 브라우저 바이너리도 설치해야 합니다:

playwright install chromium

단계별 스크래핑 프로세스

Google 항공편 검색 결과 페이지에서 항공편 데이터를 추출하는 데 중점을 두겠습니다.

1단계. 웹사이트 구조 이해하기

Google 항공편에서 데이터를 효과적으로 스크랩하려면 웹사이트의 HTML 구조를 숙지해야 합니다. 다음은 Chrome 개발자 도구를 사용하여 요소를 검사하고 스크래핑에 필요한 XPath 표현식을 검색하는 방법입니다:

  1. Google 항공편 페이지를 마우스 오른쪽 버튼으로 클릭하고 '검사'를 선택하여 Chrome 개발자 도구를 열거나 Ctrl+Shift+I(Windows/Linux) 또는 Cmd+Option+I(Mac) 단축키를 사용하세요.
  2. 페이지의 다른 부분 위로 마우스를 가져가서 요소를 검사합니다. 그러면 개발자 도구에서 HTML 구조가 강조 표시됩니다. 특정 요소를 클릭하면 정확한 XPath 표현식을 만드는 데 중요한 속성을 볼 수 있습니다.
  3. 요소 패널에서 원하는 요소를 마우스 오른쪽 버튼으로 클릭하고 "복사"를 선택한 다음 "XPath 복사"를 선택하여 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를 사용합니다. 이 접근 방식은 자바스크립트가 로드할 수 있는 동적 콘텐츠를 처리하는 데 도움이 됩니다.

Playwright를 사용하면 JavaScript가 로드하는 동적 콘텐츠를 처리하는 데 도움이 됩니다. 헤드리스 브라우저를 실행하고 URL로 이동한 다음 페이지 콘텐츠를 추출합니다.

from playwright.sync_api import sync_playwright

# Google 항공편 검색 페이지의 URL
url = "https link"

def get_page_content(url):
    """Playwright를 사용하여 지정된 URL의 HTML 콘텐츠를 가져옵니다."""
    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를 사용하여 공통 세부 정보 추출

다음으로, lxml을 사용하여 응답의 HTML 콘텐츠를 구문 분석하여 출발 및 귀국 날짜와 같은 일반적인 항공편 세부 정보를 추출합니다.

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 = []

# XPath를 사용하여 구문 분석된 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
    })

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

# Google 항공편 검색 페이지의 URL
url = "https link"

def get_page_content(url):
    """Playwright를 사용하여 지정된 URL의 HTML 콘텐츠를 가져옵니다."""
    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)

# lxml을 사용하여 HTML 콘텐츠 구문 분석
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 댓글