MIT License

项目介绍

AWeirdDev/flights 是一个托管在 GitHub 上的开源项目,主要使用 Python 编写,采用 MIT License 许可证,目前获得 2.1k 个 Star、258 次 Fork。

仓库全名
AWeirdDev/flights
开源许可证
MIT License
Star 数
2.1k
Fork 数
258
未关闭 Issue
20

README 摘要

Made possible with support from SearchApi Made possible with support from RapidProxy ✈️ fast-flights The fast and strongly-typed Google Flights scraper (API) implemented in Python. Based on Base64-encoded Protobuf string. Documentation (v3) • Issues • PyPi (v3) What's New v2.0 – New (much more succinct) API, fallback support for Playwright serverless functions, and documentation! v2.2 – Now supports local playwright…

完整内容见 GitHub 原始 README 或本页 。

常见问题

flights 用什么语言开发?

主要使用 Python 编写,采用 MIT License 许可证,目前有 2.1k 个 Star。

flights 可以免费商用吗?

仓库采用 MIT License 许可证,可免费使用与修改,商业使用请遵守许可证条款(例如保留版权声明与许可声明)。

如何获取 flights 的源码?

可以直接克隆仓库:git clone https://github.com/AWeirdDev/flights.git,默认分支为 dev;安装与运行步骤见仓库 README。

flights 最近还在维护吗?

仓库最近一次更新为 2 周前,当前有 20 个未关闭 Issue;Star 数为 2.1k,可作为社区活跃度的参考。

关于

GitHub 原始描述(英文)

Fast, robust Google Flights scraper (API) for Python. (Probably)

描述取自 GitHub 官方 API,保持仓库作者书写的原文。

简要分析

热度分
2653
价值分
1352
活跃状态
活跃

语言占比

Python

Release

README


✈️ fast-flights

The fast and strongly-typed Google Flights scraper (API) implemented in Python. Based on Base64-encoded Protobuf string.

Documentation (v3) • Issues • PyPi (v3)

$ pip install fast-flights
What's New
  • v2.0 – New (much more succinct) API, fallback support for Playwright serverless functions, and documentation!
  • v2.2 – Now supports local playwright for sending requests.
  • v3.0rc0 – Uses JavaScript data instead.
  • v3.0 – Polished new API! I suppose.

At a glance

from fast_flights import (
    FlightQuery,
    Passengers, 
    create_query, 
    get_flights
)

query = create_query(
    flights=[
        FlightQuery(
            date="YYYY-MM-DD",   # change the date
            from_airport="MYJ",  # three-letter name
            to_airport="TPE",    # three-letter name
        ),
    ],
    seat="economy",  # business/economy/first/premium-economy
    trip="one-way",  # multi-city/one-way/round-trip
    passengers=Passengers(adults=1),
    language="zh-TW",
)
res = get_flights(query)

Search filters

FlightQuery supports filters for each flight leg:

flight = FlightQuery(
    date="YYYY-MM-DD",
    from_airport="MYJ",
    to_airport="TPE",
    max_stops=1,
    airlines=["JL", "ONEWORLD"],
    earliest_departure_hour=7,
    latest_departure_hour=18,
    earliest_arrival_hour=10,
    latest_arrival_hour=23,
    max_duration_minutes=720,
    connecting_airports=["HND", "NRT"],
    min_layover_minutes=60,
    max_layover_minutes=240,
    less_emissions_only=True,
)

Filters for the whole search are passed to create_query:

query = create_query(
    flights=[flight],
    currency="USD",
    max_price=1500,
    carry_on_bags=1,
    checked_bags=1,
    hide_separate_and_self_transfer=True,
    exclude_basic_economy=True,
)

Hours use local airport time on a 0–23 clock. Duration and layover values use minutes, and max_price uses the selected currency. Google currently applies the first leg’s airline filter to the whole search.

Integrations

If you’d like, you can use integrations.

SearchApi Sponsored

If you want better consistency and richer data, consider using SearchApi.

from fast_flights.integrations import SearchApi, SearchApiResult

result: SearchApiResult = get_flights(
    ...,
    integration=SearchApi()
)

# rich data!
result.flights
result.cheaper_alternatives
result.price_insights
result.booking_options
...

RapidProxy Sponsored

Usually, you’ll need a proxy to avoid bot detection from Google. RapidProxy provides reliable residential proxy solutions with 90M+ IPs worldwide, smart IP rotation, sticky sessions, and non-expiring traffic. Ideal for web scraping, automation, and large-scale data collection. For more information, see Setting Up RapidProxy.

Setting Up RapidProxy
Setting Up RapidProxy

RapidProxy offers two proxy types, both supporting HTTP, HTTPS, and SOCKS5, with “dynamic residential” and “static residential” types.

To get started, you’ll need to first log in to the RapidProxy dashboard, and choose the proxy product you need.

  1. Config: Pick the region, proxy type and connection mode.
  2. The dashboard gives you the connection details.
  3. Record the required fields.

You’ll need:

  • HOST - Proxy host
  • PORT - Port
  • USERNAME - Username for authentication
  • PASSWORD - Password for authentication

The connection format is HOST:PORT:USERNAME:PASSWORD.

Normally, you’ll want to store this in a .env file or just the environment:

RAPIDPROXY_HOST=HOST
RAPIDPROXY_PORT=PORT
RAPIDPROXY_USERNAME=USERNAME
RAPIDPROXY_PASSWORD=PASSWORD

Since get_flights() supports proxy out of the box, you can just use it:

import os

PROXY_URL = (
   f"http://{os.environ['RAPIDPROXY_USERNAME']}:"
   f"{os.environ['RAPIDPROXY_PASSWORD']}@"
   f"{os.environ['RAPIDPROXY_HOST']}:"
   f"{os.environ['RAPIDPROXY_PORT']}"
)

results = get_flights(..., proxy=PROXY_URL)

The rest is the same, and now you have a working proxy.

For more information:

Bright Data

Use the BrightData integration to protect your IP.

from fast_flights.integrations import BrightData

result = get_flights(
    ..., 
    integration=BrightData(zone="...")
)

# ... same as normal queries

Roadmap

  • Use JavaScript data instead of traditional HTML parsing
  • Add support for integrations
  • Dangerously use Google’s GetShoppingResults internal API. Get ready to get banned.

Contributing

Contributing is welcomed! A few notes though:

  1. please no ai slop. i am not reading all that.
  2. im really busy with life; im not a full-time reddit mod.

How it’s made

The other day, I was making a chat-interface-based trip recommendation app and wanted to add a feature that can search for flights available for booking. My personal choice is definitely Google Flights since Google always has the best and most organized data on the web. Therefore, I searched for APIs on Google.

🔎 Search
google flights api

The results? Bad. It seems like they discontinued this service and it now lives in the Graveyard of Google.

🧏‍♂️ duffel.com
Google Flights API: How did it work & what happened to it?

The Google Flights API offered developers access to aggregated airline data, including flight times, availability, and prices. Over a decade ago, Google announced the acquisition of ITA Software Inc. which it used to develop its API. However, in 2018, Google ended access to the public-facing API and now only offers access through the QPX enterprise product.

That’s awful! I’ve also looked for free alternatives but their rate limits and pricing are just 😬 (not a good fit/deal for everyone).


However, Google Flights has their UI – flights.google.com. So, maybe I could just use Developer Tools to log the requests made and just replicate all of that? Undoubtedly not! Their requests are just full of numbers and unreadable text, so that’s not the solution.

Perhaps, we could scrape it? I mean, Google allowed many companies like Serpapi to scrape their web just pretending like nothing happened… So let’s scrape our own.

🔎 Search
google flights api scraper pypi

Excluding the ones that are not active, I came across hugoglvs/google-flights-scraper on Pypi. I thought to myself: “aint no way this is the solution!”

I checked hugoglvs’s code on GitHub, and I immediately detected “playwright,” my worst enemy. One word can describe it well: slow. Two words? Extremely slow. What’s more, it doesn’t even run on the 🗻 Edge because of configuration errors, missing libraries… etc. I could just reverse try.playwright.tech and use a better environment, but that’s just too risky if they added Cloudflare as an additional security barrier 😳.

Life tells me to never give up. Let’s just take a look at their URL params…

https://www.google.com/travel/flights/search?tfs=CBwQAhoeEgoyMDI0LTA1LTI4agcIARIDVFBFcgcIARIDTVlKGh4SCjIwMjQtMDUtMzBqBwgBEgNNWUpyBwgBEgNUUEVAAUgBcAGCAQsI____________AZgBAQ&hl=en
Param Content My past understanding
hl en Sets the language.
tfs CBwQAhoeEgoyMDI0LTA1LTI4agcIARID… What is this??? 🤮🤮

I removed the ?tfs= parameter and found out that this is the control of our request! And it looks so base64-y.

If we decode it to raw text, we can still see the dates, but we’re not quite there — there’s too much unwanted Unicode text.

Or maybe it’s some kind of a data-storing method Google uses? What if it’s something like JSON? Let’s look it up.

🔎 Search
google’s json alternative

🐣 Result
Solution: The Power of Protocol Buffers

LinkedIn turned to Protocol Buffers, often referred to as protobuf, a binary serialization format developed by Google. The key advantage of Protocol Buffers is its efficiency, compactness, and speed, making it significantly faster than JSON for serialization and deserialization.

Gotcha, Protobuf! Let’s feed it to an online decoder and see how it does:

🔎 Search
protobuf decoder

🐣 Result
protobuf-decoder.netlify.app

I then pasted the Base64-encoded string to the decoder and no way! It DID return valid data!

annotated, Protobuf Decoder screenshot

I immediately recognized the values — that’s my data, that’s my query!

So, I wrote some simple Protobuf code to decode the data.

syntax = "proto3"

message Airport {
    string name = 2;
}

message FlightInfo {
    string date = 2;
    Airport dep_airport = 13;
    Airport arr_airport = 14;
}

message GoogleSucks {
    repeated FlightInfo = 3;
}

It works! Now, I won’t consider myself an “experienced Protobuf developer” but rather a complete beginner.

I have no idea what I wrote but… it worked! And here it is, fast-flights.


© 2024-2026 AWeirdDev, and all the awesome people

评论

暂无评论