使用 Python 的 Google Flights 数据抓取指南

评论: 0

当涉及旅行计划、竞争分析或研究目的时,从 Google Flights 搜刮与航班相关的信息可以产生重要的洞察力。以下是关于如何使用 Python、Playwright 和 lxml 库刮擦航班信息的分步教程。

设置环境

在开始搜索之前,请确保您已安装必要的 Python 库:

pip install playwright
Pip install lxml

要使用 Playwright,还需要安装浏览器二进制文件:

playwright install chromium

逐步刮削过程

我们将重点从 Google Flights 搜索结果页面提取航班数据。

步骤 1.了解网站结构

要有效地从 Google Flights 搜刮数据,必须熟悉网站的 HTML 结构。以下是如何使用 Chrome DevTools 检查元素并检索必要的 XPath 表达式以进行搜刮的方法:

  1. 右键单击 Google Flights 页面并选择 "检查",或使用快捷键 Ctrl+Shift+I (Windows/Linux) 或 Cmd+Option+I (Mac),打开 Chrome DevTools。
  2. 通过将鼠标悬停在页面的不同部分来检查元素。这将突出显示 DevTools 中的 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 与网页交互并提取其内容。这种方法有助于处理 JavaScript 可能加载的动态内容。

使用 Playwright 可帮助处理 JavaScript 加载的动态内容。它会启动一个无头浏览器,导航到 URL 并提取页面内容。

from playwright.sync_api import sync_playwright

# 谷歌航班搜索页面的 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 提取特定飞行数据

然后,我们根据确定的 XPath 表达式解析 HTML 内容,提取特定的航班信息。

# 初始化一个空列表,用于存储航班详细信息
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

# 谷歌航班搜索页面的 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 评论