Google Flights Scraper avatar

Google Flights Scraper

Pricing

from $2.10 / 1,000 flight scrapeds

Go to Apify Store
Google Flights Scraper

Google Flights Scraper

πŸ”₯ Up to 30% OFF! Scrape Google Flights β€” no login. Airlines, price, duration, stops, layovers, departure/arrival times, CO2 emissions + round-trip & multi-city. Fast & reliable, pay per flight.

Pricing

from $2.10 / 1,000 flight scrapeds

Rating

0.0

(0)

Developer

Bruno

Bruno

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

11 days ago

Last modified

Categories

Share

πŸ”₯ Google Flights Scraper (Real Browser)

Pulls real flight itineraries and prices from Google Flights by driving an actual headless browser (Playwright/Chromium) through an Apify residential proxy β€” the same way a person would browse the site. A plain HTTP request to Google Flights gets blocked; this Actor renders the real page, waits for the results to actually appear, scrolls to load more, and reads them off the live DOM and Google's own accessibility labels.

Honesty first: if Google shows a CAPTCHA, a cookie-consent wall, or simply doesn't render results in time, this Actor reports exactly what it saw instead of guessing or inventing prices. It never fabricates a fare. Only public Google Flights data is read.

✨ What it gives you

  • πŸ’² Price (string + numeric amount + currency + fare type: round-trip / one-way)
  • πŸ›« Airlines (marketing carrier and the airline actually operating each codeshare)
  • πŸ•‘ Departure / arrival times, airport names + IATA codes, day of week, next-day arrival flag
  • ⏱️ Total duration (string and minutes) + number of stops / connections
  • πŸ” Per-layover detail: airport, city, layover length (+ minutes) and overnight flag
  • 🌱 CO2 emissions (kg) and how they compare to a typical flight (e.g. -12% / average)
  • πŸ† Computed cheapest and fastest flags across your result set, plus a rank
  • πŸ”— The Google Flights search URL, a scrapedAt timestamp, and the full rawText / ariaLabel
  • ✈️ One-way, round-trip and multi-city, sort by best / price / duration
  • 🧰 Optional flight numbers, aircraft type & amenities via per-card detail expansion

Input

{
"origin": "JFK",
"destination": "LAX",
"departDate": "2026-11-15",
"returnDate": "2026-11-22",
"adults": 1,
"cabinClass": "economy",
"currency": "USD",
"sortBy": "price",
"maxResults": 20,
"expandDetails": false,
"maxRequestRetries": 3,
"timeoutSecs": 60
}
  • origin / destination β€” IATA airport code or city name. Required.
  • departDate β€” YYYY-MM-DD. Required.
  • returnDate β€” YYYY-MM-DD, optional. Omit it for a one-way search.
  • legs β€” optional multi-city array; at least 2 objects, each { "origin", "destination", "date" }. When provided it takes priority over origin/destination/returnDate.
  • adults β€” passenger count, default 1.
  • cabinClass β€” economy / premium / business / first, default economy.
  • currency β€” 3-letter code Google should price in, default USD.
  • sortBy β€” best (Google's ranking, default) / price (cheapest first) / duration (fastest first).
  • maxResults β€” cap on itineraries returned, default 30.
  • expandDetails β€” true to also capture flight numbers / aircraft / amenities (slower), default false.
  • maxRequestRetries β€” retries with a fresh browser + proxy IP on a block/timeout, default 3.
  • timeoutSecs β€” how long to wait for results to render per attempt, default 60.

Multi-city example

{
"origin": "JFK", "destination": "JFK", "departDate": "2026-11-15",
"legs": [
{ "origin": "JFK", "destination": "LAX", "date": "2026-11-15" },
{ "origin": "LAX", "destination": "SEA", "date": "2026-11-20" },
{ "origin": "SEA", "destination": "JFK", "date": "2026-11-25" }
]
}

Output (one item per itinerary)

{
"origin": "JFK", "destination": "LAX", "departDate": "2026-11-15", "returnDate": "2026-11-22",
"cabinClass": "economy", "adults": 1, "currency": "USD", "tripType": "round-trip",
"price": "$347", "priceAmount": 347, "priceCurrencySymbolOrCode": "$", "priceFareType": "round trip",
"airline": "Delta", "airlines": ["Delta"], "operatingAirlines": [],
"departureTime": "6:00 AM", "arrivalTime": "9:25 AM", "departureArrival": "6:00 AM - 9:25 AM",
"departureAirportName": "John F. Kennedy International Airport",
"arrivalAirportName": "Los Angeles International Airport",
"departureDay": "Saturday, November 15", "arrivalDay": "Saturday, November 15", "arrivesNextDay": false,
"duration": "6 hr 25 min", "durationMinutes": 385,
"stops": "Nonstop", "stopsCount": 0, "connectionCount": 0, "connectionAirports": [], "layovers": [],
"originAirportCode": "JFK", "destinationAirportCode": "LAX", "routeAirports": "JFK-LAX",
"co2Emissions": "48 kg CO2e", "co2EmissionsKg": 48, "emissionsVsTypical": "-12%",
"isCheapestInResults": true, "isFastestInResults": true, "rank": 1,
"searchUrl": "https://www.google.com/travel/flights?...",
"scrapedAt": "2026-10-05T18:00:00.000Z",
"rawText": "6:00 AM ... Delta $347 ...",
"ariaLabel": "From 347 US dollars round trip total. Nonstop flight with Delta. ..."
}

A connecting itinerary adds entries to layovers, e.g.:

"layovers": [
{ "index": 1, "of": 1, "airport": "Fort Lauderdale-Hollywood International Airport",
"city": "Fort Lauderdale", "duration": "2 hr 10 min", "durationMinutes": 130, "overnight": false }
]

rawText and ariaLabel are kept on every row so you can verify or re-parse anything the field extraction missed β€” nothing is hidden.

If results couldn't be read, you'll get a single honest item instead, e.g.:

{ "error": "BLOCKED: Google served an anti-bot/CAPTCHA challenge page instead of flight results.", "url": "..." }

Other possible error values: NO_ITEMS_MATCHED (Google changed its markup), TIMEOUT (nothing rendered in time), NAVIGATION_FAILED, or a plain input-validation message.

How it works

  1. Launches real Chromium (Playwright) through Apify's RESIDENTIAL proxy (pinned to US by default, with automatic fallback if that's unavailable on the account).
  2. Opens
    https://www.google.com/travel/flights?...&q=Flights from {origin} to {destination} on {departDate}...
    β€” Google's own natural-language parser builds the search from that sentence, including round-trip / one-way / multi-city, passenger count and cabin class.
  3. Dismisses a cookie-consent interstitial if Google shows one.
  4. Waits for real priced itinerary list items to appear (not a fixed sleep), then scrolls / clicks "more flights" to pull in additional itineraries up to maxResults.
  5. Reads each rendered card's text and Google's rich aria-label and extracts every field with pattern matching β€” no guessing, no cached/sample data.
  6. On a block or render timeout it retries with a fresh browser + proxy IP (maxRequestRetries), and only reports an honest error once all retries are exhausted.

Notes

  • Google's markup is unlabeled/obfuscated and changes over time; extraction is regex/heuristic over rendered text and aria-labels. rawText/ariaLabel are always included as a source-of-truth backstop.
  • Residential proxy IPs and Google's bot-defenses mean an occasional run may still hit a CAPTCHA β€” when that happens the Actor tells you plainly rather than pretending to have data.
  • isCheapestInResults / isFastestInResults are computed within the results this run returned, not a claim about every fare in the world β€” the names say so on purpose.
  • adults and cabinClass are passed to Google Flights as part of the natural-language query (e.g. "...for 2 adults in business class"); this is Google's interpretation, not a hard API filter β€” always check cabinClass/adults echoed back against rawText if exact filtering matters.
  • flightNumbers / aircraftTypes / amenities only appear when expandDetails is true, and are best-effort for the first few results.

⭐ Enjoying this Actor?

A quick rating/review helps others find it. Found a query pattern Google didn't parse right? Open a ticket on the Issues tab.