# Priceline Hotel Reviews Scraper (`scrapyx/priceline-reviews-scraper`) Actor

Extracts the full verified-guest review history for any hotel on Priceline.com by hotel URL, with pros/cons text, per-category scores and traveller type.

- **URL**: https://apify.com/scrapyx/priceline-reviews-scraper.md
- **Developed by:** [Ibnu Adzim](https://apify.com/scrapyx) (community)
- **Categories:** Travel, Marketing, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.49 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Priceline Hotel Reviews Scraper

Extracts the full verified-guest review history for any hotel listed on Priceline.com — just give it the hotel page link.

### Why use this actor

- No account, no login, and no API key needed — works on public hotel pages only.
- Returns **every** guest review up to your chosen limit, not just the handful shown on the page: separate "liked" and "disliked" text, the guest's score, traveller type (couple, family, business, solo…), their home city, and the review date.
- Also returns Priceline's own rating breakdown per hotel — Location, Staff, Cleanliness and Overall scores, plus the score-band and traveller-type filter counts.
- Choose the review order: most recent, highest score, or lowest score — useful when you only care about the newest feedback or the complaints.
- Stable, flat JSON that drops straight into a spreadsheet, database, or analysis pipeline.
- Every hotel you submit gets at least one output row — including a clear diagnostic reason on the rare rows that couldn't be fetched, so nothing silently disappears from your results.

### How it works

1. You give the actor one or more Priceline hotel page links (or bare hotel IDs).
2. For each hotel, it reads that hotel's review history, 100 reviews at a time, until it reaches your limit or runs out of reviews.
3. Results are streamed to your dataset as they finish, with automatic retries when Priceline is temporarily unresponsive.
4. You export the finished dataset as JSON, CSV, or Excel straight from the Apify Console — no scrapers, browsers, or blocks to babysit.

### Input

```json
{
  "hotelUrls": [
    "https://www.priceline.com/hotel-deals/en-us/P3000001947/H41914/the-biltmore-los-angeles.ssp"
  ],
  "maxReviewsPerHotel": 300,
  "sortBy": "MOST_RECENT",
  "maxConcurrency": 3,
  "proxyConfiguration": { "useApifyProxy": false }
}
```

| Field | Type | Description |
|---|---|---|
| `hotelUrls` | array of strings | Priceline hotel page URLs. Both the public hotel-deals page (`.../H41914/<slug>.ssp`) and the booking page (`/relax/at/41914/...`) work, and a bare hotel ID such as `41914` is also accepted. |
| `maxReviewsPerHotel` | integer | Stop after this many reviews per hotel. Reviews are fetched 100 at a time, so this maps directly to how much work each hotel costs. Set to `0` to fetch every review. Default `300`. |
| `sortBy` | string | `MOST_RECENT`, `HIGHEST_SCORE`, or `LOWEST_SCORE`. Default `MOST_RECENT`. |
| `maxConcurrency` | integer | How many hotels to process at the same time. Default `3`. |
| `proxyConfiguration` | object | Proxy settings. Off by default; Residential is recommended for large production runs. |

### Output

Each hotel produces one **summary** row plus one **review** row per guest review. Real examples from a live run:

**Summary row** (`recordType: "SUMMARY"`):

```json
{
  "_input": "https://www.priceline.com/hotel-deals/en-us/P3000001947/H41914/the-biltmore-los-angeles.ssp",
  "_source": "S1-graphql-getreviewsbyhotelids",
  "_scrapedAt": "2026-08-10T18:13:22Z",
  "recordType": "SUMMARY",
  "hotelId": "41914",
  "totalReviews": 770,
  "totalPages": 8,
  "reviewSummary": {
    "scores": [
      { "type": "LOCATION", "label": "Location", "score": "8.6" },
      { "type": "STAFF", "label": "Staff", "score": "8.4" },
      { "type": "CLEANLINESS", "label": "Cleanliness", "score": "8.3" },
      "… 1 more"
    ],
    "total": { "count": "2062", "label": "2,062 Reviews" }
  },
  "filterSummary": {
    "sortOptions": [
      { "value": "MOST_RECENT", "label": "Most Recent" },
      { "value": "HIGHEST_SCORE", "label": "Highest Review" },
      { "value": "LOWEST_SCORE", "label": "Lowest Review" }
    ],
    "filters": [
      {
        "filterType": "RATING",
        "title": "Score",
        "options": [
          { "count": 1095, "label": "9-10", "value": "9,10", "sublabel": "(1095)" },
          { "count": 574, "label": "7-8", "value": "7,8", "sublabel": "(574)" },
          { "count": 203, "label": "5-6", "value": "5,6", "sublabel": "(203)" },
          "… 2 more"
        ]
      }
    ]
  }
}
```

**Review row** (`recordType: "REVIEW"`):

```json
{
  "_input": "https://www.priceline.com/hotel-deals/en-us/P3000001947/H41914/the-biltmore-los-angeles.ssp",
  "_source": "S1-graphql-getreviewsbyhotelids",
  "_scrapedAt": "2026-08-10T18:13:22Z",
  "recordType": "REVIEW",
  "hotelId": "41914",
  "positiveRemark": "Level of service, best I've ever experienced ",
  "negativeRemark": "There was a very loud concert venue across the street making it very hard to sleep\nAlso parking is limited and expensive \nFood is way overpriced ",
  "genericText": null,
  "scores": [
    { "type": "OVERALL", "score": "10", "label": "Overall" }
  ],
  "reviewerInfo": {
    "name": "Michelle",
    "travelerType": { "type": "COUPLE", "label": "Traveling as a Couple" },
    "location": "North Las Vegas, NV"
  },
  "reviewId": "3966872680",
  "entryDate": "Jul 2026"
}
```

When the input isn't a recognisable Priceline hotel link, the actor still emits one row for that input with a clear reason:

```json
{
  "_input": "https://example.com/not-priceline",
  "_source": "none",
  "_scrapedAt": "2026-08-10T18:13:22Z",
  "recordType": "ERROR",
  "_error": "invalid_input",
  "_errorDetail": "Expected a priceline.com hotel URL (e.g. https://www.priceline.com/hotel-deals/en-us/P3000001947/H41914/<slug>.ssp or https://www.priceline.com/relax/at/41914/...) or a bare hotel id such as 41914."
}
```

| Field | Type | Description |
|---|---|---|
| `_input` | string | The hotel URL or ID you submitted. |
| `_source` | string | Which internal strategy produced this row. `"none"` on a failed row. |
| `_scrapedAt` | string | UTC timestamp of when this row was produced. |
| `recordType` | string | `"SUMMARY"`, `"REVIEW"`, or `"ERROR"`. |
| `hotelId` | string | Priceline's numeric hotel ID. |
| `totalReviews` | integer | How many written reviews this hotel has in total (summary row). |
| `reviewSummary` | object | Priceline's own category scores plus the site-wide review count (summary row). |
| `filterSummary` | object | Available sort options and the score/traveller-type filter counts (summary row). |
| `positiveRemark` | string | What the guest liked. `null` when they left none. |
| `negativeRemark` | string | What the guest disliked. `null` when they left none. |
| `genericText` | string | Free-form comment when the guest didn't split it into likes/dislikes. |
| `scores` | array | The guest's own score(s) for this stay. |
| `reviewerInfo` | object | Reviewer first name, traveller type, and home location. |
| `reviewId` | string | Priceline's stable ID for this review — safe to de-duplicate on. |
| `entryDate` | string | Month and year the review was posted, e.g. `"Jul 2026"`. |
| `_error` | string | Present only on rows that couldn't be fetched, e.g. `invalid_input`, `hotel_not_found`. |
| `_errorDetail` | string | Human-readable detail for the error, present only alongside `_error`. |

### Notes / limits

- `totalReviews` (reviews with written text — what this actor returns) is smaller than the site-wide count in `reviewSummary.total.count`, which also counts score-only ratings with no text. Both are reported so you can see the difference.
- Reviewer names are first names only and locations are city-level — that is all Priceline publishes.
- `entryDate` has month precision (`"Jul 2026"`), not a full date.
- A `partial_*` error row means pagination stopped partway through a hotel after already returning some real reviews — you still get what was fetched, plus a diagnostic explaining why it stopped early.

### Other actors in this collection

| Actor | What it returns |
|---|---|
| HolidayCheck Hotel Reviews Scraper | Guest reviews for hotels listed on HolidayCheck (.de/.at/.ch) |
| Agoda Reviews Scraper | Guest reviews for hotels listed on Agoda.com |
| Booking.com Reviews Scraper | Guest reviews for hotels listed on Booking.com |
| Trip.com Reviews Scraper | Guest reviews for hotels listed on Trip.com |
| Orbitz Hotel Reviews Scraper | Guest reviews for hotels listed on Orbitz.com |
| Viator Reviews Scraper | Guest reviews for tours/activities listed on Viator |
| GetYourGuide Reviews Scraper | Guest reviews for tours/activities listed on GetYourGuide |

# Actor input Schema

## `hotelUrls` (type: `array`):

Priceline hotel page URLs. Both the public hotel-deals page (.../H41914/<slug>.ssp) and the booking page (/relax/at/41914/...) work, and a bare hotel id such as 41914 is also accepted.

## `maxReviewsPerHotel` (type: `integer`):

Stop paginating a hotel after this many reviews. Reviews are fetched 100 at a time, so this maps directly to request count. Set to 0 for unlimited (fetch every review).

## `sortBy` (type: `string`):

Review ordering. These are exactly the options Priceline's own review widget offers.

## `maxConcurrency` (type: `integer`):

Maximum number of hotels processed in parallel.

## `proxyConfiguration` (type: `object`):

Proxy settings. Priceline's bot defence (PerimeterX) was cleared by TLS-fingerprint rotation alone during recon, without any proxy — but Residential is recommended for large production runs from shared platform IPs.

## Actor input object example

```json
{
  "hotelUrls": [
    "https://www.priceline.com/hotel-deals/en-us/P3000001947/H41914/the-biltmore-los-angeles.ssp"
  ],
  "maxReviewsPerHotel": 300,
  "sortBy": "MOST_RECENT",
  "maxConcurrency": 3,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `items` (type: `string`):

One row per scraped record. See the dataset's default view for field definitions.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "hotelUrls": [
        "https://www.priceline.com/hotel-deals/en-us/P3000001947/H41914/the-biltmore-los-angeles.ssp"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapyx/priceline-reviews-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "hotelUrls": ["https://www.priceline.com/hotel-deals/en-us/P3000001947/H41914/the-biltmore-los-angeles.ssp"] }

# Run the Actor and wait for it to finish
run = client.actor("scrapyx/priceline-reviews-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "hotelUrls": [
    "https://www.priceline.com/hotel-deals/en-us/P3000001947/H41914/the-biltmore-los-angeles.ssp"
  ]
}' |
apify call scrapyx/priceline-reviews-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapyx/priceline-reviews-scraper"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/FgNfr2ynEKj5uAKfO/builds/Q5eTg30koSlP0w1BI/openapi.json
