Tripadvisor располагает одной из крупнейших коллекций пользовательских туристических данных в интернете: сотни миллионов отзывов, рейтинги и листинги отелей, ресторанов и достопримечательностей. Это делает платформу привлекательным источником для маркетинговых исследований, конкурентного бенчмаркинга и мониторинга репутации. Но у этого есть сложность: Tripadvisor рендерит большую часть контента с помощью JavaScript и жёстко защищается от автоматизированного трафика, поэтому обычный HTTP-запрос даёт вам почти пустую страницу и нередко блокировку.

В этом руководстве показано, как парсить Tripadvisor надёжным способом с помощью Python: маршрутизировать запросы через Crawlbase Smart AI Proxy, позволить ему рендерить страницу и ротировать IP-адреса, затем парсить возвращаемый HTML с помощью BeautifulSoup для извлечения названий, рейтингов, количества отзывов и местоположений из публичных листингов поиска. Весь код рабочий, и руководство ограничено только публичными данными.

Законно ли парсить Tripadvisor?

Скрапинг крупной коммерческой платформы находится в правовой серой зоне, и разрешённость зависит от условий использования Tripadvisor, вашей юрисдикции и того, что вы делаете с данными. Условия Tripadvisor ограничивают автоматизированный доступ, поэтому скрапинг может противоречить этим условиям вне зависимости от тщательности ваших инструментов. Ни один из приведённых здесь кодов не меняет этого; он просто делает техническую часть рабочей.

Несколько правил, которых стоит придерживаться. Собирайте только публичные данные: названия листингов, рейтинги, количество отзывов и местоположения, которые любой может видеть без аккаунта. Соблюдайте файл robots.txt Tripadvisor и его заявленные ожидания по скорости, держите объём запросов достаточно низким, чтобы не перегружать серверы. Отзывы, это пользовательский контент, связанный с реальными людьми, поэтому не публикуйте их оптом и не парсите ничего, что идентифицирует человека. Если вы планируете коммерческое переиспользование данных, получите разрешение или официальное соглашение о данных, а не предполагайте, что молчание означает согласие.

Это руководство намеренно ограничено публичными данными листинга, так как это та линия, которая делает работу правомерной. Оно не распространяется на что-либо за логином, данные аккаунтов или профилей, личные сообщения или любые попытки обойти аутентификацию. Если ваш проект требует большего, чем публичные листинги, правильный шаг, официальный API или соглашение о данных с Tripadvisor, а не более изощрённый скрапер.

Зачем парсить Tripadvisor

Публичные туристические настроения постоянно меняются, и один просмотр страницы показывает лишь то, как выглядит листинг прямо сейчас. Парсинг публичных листингов Tripadvisor позволяет отслеживать рейтинги, количество отзывов и позиции в рейтинге с течением времени, что и нужно большинству исследовательских задач. Несколько конкретных применений:

  • Market research. Выявляйте популярные направления и меняющиеся предпочтения клиентов, наблюдая за объёмом отзывов и рейтингами в категории.
  • Competitive analysis. Сравнивайте ваш отель, ресторан или достопримечательность с конкурентами по рейтингу и количеству отзывов на одном рынке.
  • Reputation monitoring. Отслеживайте, как меняется рейтинг вашего листинга, чтобы своевременно реагировать на его снижение.
  • Trend discovery. Агрегируйте тональность по многим листингам, чтобы выявить новые паттерны, которые никогда не раскроет одна страница.

Для инженера ценность, в структурированных данных: превращение отрисованной страницы поиска в чистые строки, которые можно запрашивать, строить на их основе графики или передавать в модель.

Почему обычный запрос здесь не работает

Если запросить URL Tripadvisor обычным HTTP-клиентом, вы, как правило, получите ответ со статусом 200 и почти без нужных данных. Здесь действуют два фактора. Во-первых, Tripadvisor рендерит листинги в браузере с помощью JavaScript, поэтому исходный HTML, это оболочка, которая заполняется только после запуска скриптов страницы. Во-вторых, Tripadvisor быстро выявляет автоматизированный трафик: IP-адреса датацентров и паттерны запросов, не похожие на настоящий браузер, подвергаются проверке или блокировке ещё до того, как загружается отрисованный контент.

Значит, рабочий скрапер Tripadvisor должен решать в одном запросе две задачи: браузер, который действительно рендерит страницу, и IP-адрес, который платформа воспринимает как реального посетителя. Можно собрать это самостоятельно с помощью headless-браузера и пула ротирующихся резидентских прокси, но поддержание их в рабочем состоянии, основная часть работы. Crawlbase Smart AI Proxy объединяет оба компонента в одном эндпоинте: вы направляете свой обычный HTTP-клиент через него, передаёте несколько параметров, и он рендерит страницу за доверенным ротирующимся IP-адресом и возвращает готовый HTML.

What the Smart AI Proxy is

Smart AI Proxy, это прямой прокси-эндпоинт на основе Crawling API Crawlbase. Вы продолжаете использовать requests (или любой клиент) как обычно и просто маршрутизируете через него. Под капотом он ротирует большой пул датацентровых и резидентских IP-адресов и может рендерить JavaScript, поэтому вы получаете мощь Crawling API без переписывания кода под новый SDK.

Настройка окружения

Вам потребуется Python 3.8 или новее. Проверьте версию, создайте виртуальное окружение для изоляции зависимостей проекта, затем установите три библиотеки, используемые в этом руководстве.

bash
python --version

python -m venv tripadvisor_env
source tripadvisor_env/bin/activate

pip install requests beautifulsoup4 pandas

В Windows активируйте окружение командой tripadvisor_env\Scripts\activate вместо строки с source. Три зависимости выполняют всю работу: requests делает HTTP-запросы, beautifulsoup4 парсит возвращаемый HTML, а pandas организует результаты и записывает их в файл.

Вам также потребуется аккаунт Crawlbase и токен доступа, который вы получите в дашборде после регистрации. Подставьте его в код везде, где указано YOUR_ACCESS_TOKEN.

Отправка запроса через Smart AI Proxy

Smart AI Proxy, это просто HTTP прокси-эндпоинт, поэтому вы настраиваете его так же, как любой прокси в requests. Поместите токен доступа в URL прокси, укажите его в обоих полях http и https и выполните обычный GET-запрос. Поскольку прокси завершает TLS за вас, передайте verify=False, чтобы пропустить локальные проверки сертификата.

python
import requests

proxy_url = "http://YOUR_ACCESS_TOKEN:@smartproxy.crawlbase.com:8012"
target_url = "https://www.tripadvisor.com/Search?q=london"

proxies = {"http": proxy_url, "https": proxy_url}

response = requests.get(target_url, proxies=proxies, verify=False)

print("Status:", response.status_code)
print(response.content[:500])

Этот единственный вызов, вся интеграция. Ваш код остаётся обычным requests; прокси берёт на себя ротацию IP-адресов и репутацию доверенного посетителя, которая не позволяет вам быть заблокированным при первом запросе.

Передача параметров Crawling API

Smart AI Proxy предоставляет те же элементы управления, что и Crawling API, через единственный заголовок запроса CrawlbaseAPI-Parameters. Параметры передаются в виде значения в формате строки запроса. Например, для геолокации запроса в США укажите параметр country:

python
import requests

proxy_url = "http://YOUR_ACCESS_TOKEN:@smartproxy.crawlbase.com:8012"
target_url = "https://www.tripadvisor.com/Search?q=london"

headers = {"CrawlbaseAPI-Parameters": "country=US"}
proxies = {"http": proxy_url, "https": proxy_url}

response = requests.get(target_url, headers=headers, proxies=proxies, verify=False)
print(response.content[:500])

Вы можете объединять несколько параметров с помощью & в одном значении заголовка, именно так вы включаете рендеринг JavaScript далее.

Рендеринг JavaScript-тяжёлых страниц

Tripadvisor загружает листинги на стороне клиента, поэтому без рендеринга вы снова получаете пустую оболочку. Включите headless-браузер с параметром javascript=true и добавьте page_wait для фиксированной задержки в миллисекундах после загрузки, чтобы поздно рендеримые элементы появились перед захватом страницы. Пяти секунд достаточно для начала; увеличьте значение, если результаты возвращаются неполными.

python
import requests

proxy_url = "http://YOUR_ACCESS_TOKEN:@smartproxy.crawlbase.com:8012"
target_url = "https://www.tripadvisor.com/Search?q=london"

headers = {"CrawlbaseAPI-Parameters": "javascript=true&page_wait=5000"}
proxies = {"http": proxy_url, "https": proxy_url}

response = requests.get(target_url, headers=headers, proxies=proxies, verify=False)
html_content = response.content.decode("utf-8")

print("Fetched", len(html_content), "characters of rendered HTML")

При включённом рендеринге JavaScript тело ответа теперь содержит заполненные листинги, а не пустой шаблон. Именно этот HTML вы передадите в BeautifulSoup.

Crawlbase TripAdvisor Scraper

Tripadvisor требует отрисованной страницы за доверенным IP-адресом, и Smart AI Proxy предоставляет оба компонента как прямой эндпоинт. Продолжайте использовать requests как обычно, передайте javascript=true, и он рендерит страницу в настоящем браузере, ротирует резидентские и датацентровые IP-адреса на стороне сервера и отдаёт готовый HTML, избавляя вас от необходимости самостоятельно управлять парком headless-браузеров и пулом прокси. Попробуйте на публичном поиске на бесплатном уровне.

Парсинг листингов поиска с помощью BeautifulSoup

Получив отрисованный HTML, загрузите его в BeautifulSoup и пройдитесь по карточкам результатов. Первая задача, найти контейнер, содержащий результаты поиска. Откройте страницу в браузере, щёлкните правой кнопкой мыши на результате и выберите «Просмотр кода», чтобы изучить живую разметку.

В представлении поиска Tripadvisor каждый листинг находится в элементе div с классом result, и они расположены внутри списка результатов, ключом которого служит атрибут data-widget-type="LOCATIONS". Выберите его и пройдитесь по карточкам:

python
from bs4 import BeautifulSoup

soup = BeautifulSoup(html_content, "html.parser")

search_results = soup.select(
    'div.search-results-list[data-widget-type="LOCATIONS"] div.result'
)

for result in search_results:
    # extract fields from each result here
    pass

Теперь сопоставьте каждое поле с его селектором. Инспекция карточки показывает, где находятся название, рейтинг, количество отзывов и местоположение:

  • Name находится в элементе <span> внутри div.result-title.
  • Rating находится в элементе span.ui_bubble_rating, значение хранится в атрибуте alt.
  • Review count, это текст ссылки a.review_count.
  • Location, это текст элемента div.address-text.
python
name_el = result.select_one("div.result-title span")
name = name_el.text.strip() if name_el else None

rating_el = result.select_one("span.ui_bubble_rating")
rating = rating_el["alt"] if rating_el else None

reviews_el = result.select_one("a.review_count")
reviews = reviews_el.text.strip() if reviews_el else None

location_el = result.select_one("div.address-text")
location = location_el.text.strip() if location_el else None
Selectors drift

Tripadvisor обновляет разметку без предупреждения, поэтому имена классов, такие как result-title и ui_bubble_rating, могут измениться. Воспринимайте приведённые выше селекторы как шаблон, а не как неизменный контракт. Когда поле возвращается как None, заново изучите страницу поиска в инструментах разработчика браузера и обновите селектор. Это обычное обслуживание для любого производственного скрапера, а не признак поломки.

Полный скрапер

Вот всё, объединённое в один рабочий файл. Он получает отрисованную страницу поиска через Smart AI Proxy, парсит каждый результат, собирает строки и выводит их в виде JSON.

python
import json
import requests
from bs4 import BeautifulSoup

proxy_url = "http://YOUR_ACCESS_TOKEN:@smartproxy.crawlbase.com:8012"
target_url = "https://www.tripadvisor.com/Search?q=london"

headers = {"CrawlbaseAPI-Parameters": "javascript=true&page_wait=5000"}
proxies = {"http": proxy_url, "https": proxy_url}


def parse_results(html):
    soup = BeautifulSoup(html, "html.parser")
    cards = soup.select(
        'div.search-results-list[data-widget-type="LOCATIONS"] div.result'
    )
    rows = []
    for result in cards:
        name_el = result.select_one("div.result-title span")
        rating_el = result.select_one("span.ui_bubble_rating")
        reviews_el = result.select_one("a.review_count")
        location_el = result.select_one("div.address-text")
        rows.append({
            "name": name_el.text.strip() if name_el else None,
            "rating": rating_el["alt"] if rating_el else None,
            "reviews": reviews_el.text.strip() if reviews_el else None,
            "location": location_el.text.strip() if location_el else None,
        })
    return rows


def main():
    response = requests.get(target_url, headers=headers, proxies=proxies, verify=False)
    html = response.content.decode("utf-8")
    rows = parse_results(html)
    print(json.dumps(rows, indent=2))


if __name__ == "__main__":
    main()

Как выглядит результат

Запустите скрипт командой python tripadvisor_scraper.py и получите массив структурированных объектов листинга. Сокращённый пример:

json
[
  {
    "name": "London Eye",
    "rating": "4.5 of 5 bubbles",
    "reviews": "89,766 reviews",
    "location": "Westminster Bridge Road, London, England, United Kingdom"
  },
  {
    "name": "Big Bus London Hop-On Hop-Off Tour and River Cruise",
    "rating": "4 of 5 bubbles",
    "reviews": "8,656 reviews",
    "location": "London, England, United Kingdom"
  },
  {
    "name": "North London Skydiving Centre",
    "rating": "5 of 5 bubbles",
    "reviews": "2,889 reviews",
    "location": "Block Fen Drove, Wimblington, Cambridgeshire, England, United Kingdom"
  }
]

Обработка пагинации

Одна страница результатов, это демонстрация; реальная задача обходит несколько страниц. Tripadvisor использует параметр запроса o (смещение) для перехода по страницам результатов поиска, увеличивая его на количество результатов на странице. Перебирайте диапазон, каждый раз увеличивая смещение, и собирайте строки в один список.

python
base_url = "https://www.tripadvisor.com/Search?q=london"
all_rows = []
offset = 0

for page in range(5):  # adjust to the number of pages you want
    target_url = f"{base_url}&o={offset}"
    response = requests.get(target_url, headers=headers, proxies=proxies, verify=False)
    html = response.content.decode("utf-8")
    all_rows.extend(parse_results(html))
    offset += 30  # results per page

print(f"Collected {len(all_rows)} listings")

Повторное использование функции parse_results из полного скрипта сохраняет логику извлечения в одном месте, чтобы каждая страница проходила через те же селекторы. Соблюдайте паузы между запросами в цикле; прокси ротирует IP-адреса за вас, но ровный ритм поддерживает работоспособность запуска на защищённом сайте.

Сохранение данных в Excel

Вывод в консоль удобен при итерации, но вам нужны данные на диске. С помощью pandas превращение строк в Excel-файл, который любой может открыть в таблице, занимает две строки кода.

python
import pandas as pd

df = pd.DataFrame(all_rows)
df.to_excel("tripadvisor_data.xlsx", index=False)
print("Saved tripadvisor_data.xlsx")

Каждый ключ объекта становится столбцом, и в итоге вы получаете аккуратный лист с именем, рейтингом, отзывами и местоположением. Если вы предпочитаете запрашивать данные с помощью SQL, запишите те же строки в таблицу SQLite; парсинг остаётся идентичным.

Как оставаться незаблокированным

Даже при обработке рендеринга и ротации IP-адресов Smart AI Proxy Tripadvisor отслеживает трафик, характерный для скраперов. Несколько привычек помогают поддерживать работоспособность запуска; они применимы к любой серьёзной коммерческой цели.

  • Дозируйте запросы. Бомбардировка одного поиска в тесном цикле, самый быстрый способ получить ограничение скорости. Распределяйте запросы и варьируйте поисковые запросы.
  • Используйте ротацию. Пул резидентских прокси распределяет запросы по множеству реальных пользовательских IP-адресов, чтобы ни один из них не превысил лимит скорости. Smart AI Proxy берёт это на себя; если вы строите собственный стек, именно в эту часть стоит вкладываться.
  • Читайте коды статусов. Запуск, который начинает возвращать проверки или ошибки, сигнализирует о том, что текущая скорость или уровень IP больше недостаточны. Воспринимайте эти ответы как сигнал, замедляйтесь и повторяйте попытку позже.

Более подробный план действий см. в руководстве по обходу блокировок при скрапинге.

Итоги

Ключевые выводы

  • Tripadvisor рендерится на стороне клиента. Обычный запрос возвращает почти пустую оболочку, поэтому необходимо рендерить страницу перед парсингом.
  • Smart AI Proxy, это готовое решение. Маршрутизируйте обычный requests через него, передайте javascript=true, и вы получаете рендеринг плюс ротацию IP-адресов в одном эндпоинте без нового SDK.
  • Настраивайте с помощью параметров. Передавайте параметры, такие как country и page_wait, через заголовок CrawlbaseAPI-Parameters для геолокации и ожидания контента.
  • BeautifulSoup выполняет извлечение. Сопоставьте название, рейтинг, отзывы и местоположение с текущими селекторами и ожидайте, что они со временем изменятся.
  • Работайте только с публичными данными. Соблюдайте условия использования и robots.txt Tripadvisor; никаких аккаунтов, персональных данных и массовой перепубликации отзывов.

Часто задаваемые вопросы

Законно ли парсить Tripadvisor?

Это зависит от условий использования Tripadvisor, вашей юрисдикции и цели, а его условия ограничивают автоматизированный доступ. Строго ограничивайтесь публичными данными листинга, такими как названия, рейтинги, количество отзывов и местоположения, соблюдайте robots.txt и заявленные ожидания по скорости и никогда не трогайте аккаунты, персональные данные или контент за логином. Отзывы, это пользовательский контент, связанный с реальными людьми, поэтому не публикуйте их оптом. Для коммерческого переиспользования получите разрешение или официальное соглашение о данных, а не полагайтесь на скрапер.

Почему обычный запрос не возвращает данные с Tripadvisor?

Потому что Tripadvisor рендерит листинги на стороне клиента с помощью JavaScript. Исходный HTML, это оболочка, которая заполняется только после запуска скриптов страницы в браузере, поэтому обычный HTTP-запрос возвращает статус 200 с пустыми полями. Чтобы получить реальные данные, необходимо сначала рендерить страницу, что делает параметр javascript=true Smart AI Proxy.

Как обработать динамическую загрузку контента на Tripadvisor?

Включите рендеринг JavaScript через Smart AI Proxy, передав javascript=true в заголовок CrawlbaseAPI-Parameters, и добавьте page_wait для выдержки нескольких секунд после загрузки, чтобы появились поздно рендеримые элементы. Это сочетание запускает страницу в настоящем headless-браузере перед возвратом HTML, поэтому динамические листинги присутствуют при парсинге BeautifulSoup.

Можно ли парсить несколько страниц результатов поиска Tripadvisor?

Да. Tripadvisor использует параметр смещения o для перехода по результатам поиска, поэтому вы перебираете диапазон, каждый раз увеличивая смещение на количество результатов на странице, и собираете строки в один список. Соблюдайте паузы в цикле вместо отправки запросов подряд и повторно используйте ту же функцию парсинга для каждой страницы.

Мои селекторы возвращают None. Что изменилось?

Почти наверняка изменилась разметка Tripadvisor. Имена классов, такие как result-title и ui_bubble_rating, меняются без предупреждения, поэтому селекторы, работавшие в прошлом месяце, могут сломаться. Заново изучите страницу поиска в инструментах разработчика браузера и обновите селекторы. Периодическое обслуживание селекторов, норма для любого производственного скрапера.

Разрешает ли Tripadvisor веб-скрапинг?

Условия Tripadvisor ограничивают автоматизированный доступ, поэтому широкого разрешения на скрапинг нет. При этом сбор публично видимых данных, таких как названия листингов, рейтинги, количество отзывов и местоположения, через такой инструмент, как Smart AI Proxy, является менее рискованным путём при ответственном подходе: оставайтесь на публичных данных, соблюдайте robots.txt и лимиты скорости и избегайте всего, что связано с отдельными пользователями.

Начать создавать

Обходите любой сайт в масштабе, без борьбы с инфраструктурой.

Crawlbase берёт на себя прокси, отпечатки и CAPTCHA, чтобы ваша команда выпускала конвейеры данных вместо поддержки обвязки краулинга. 1 000 запросов бесплатно, без карты.

Самообслуживание · Звонок отдела продаж не требуется · Доступны корпоративные объёмы краулинга