вступление

В этом сообщении блога мы рассмотрим процесс извлечения отзывов со страницы поиска Yelp Place с помощью Yelp Reviews API и языка программирования Python. Вы можете посмотреть полный код в онлайн-IDE (Replit).

Для успешного извлечения Yelp Reviews вам потребуется передать параметр place_id, этот параметр отвечает за отзывы с определенного места. Вы можете извлечь этот параметр из органических результатов. Взгляните на статью в блоге Scrape Yelp Filters, Ad and Organic Results with Python, в которой я подробно описал, как извлечь все необходимые данные.

Что будет очищено

Зачем использовать API?

Есть несколько причин, по которым может использоваться API, в частности наша:

  • Нет необходимости создавать парсер с нуля и поддерживать его.
  • Обходите блокировки от Google: разгадывайте CAPTCHA или разгадывайте IP-блокировки.
  • Платите за прокси и решатели CAPTCHA.
  • Не нужно использовать автоматизацию браузера.

SerpApi обрабатывает все на бэкэнде с быстрым временем отклика менее ~ 2,5 секунд (~ 1,2 секунды со скоростью Ludicrous) на запрос и без автоматизации браузера, что становится намного быстрее. Время отклика и показатели статуса отображаются на странице Статус SerpApi.

Полный код

Этот код извлекает все отзывы с места с разбиением на страницы:

from serpapi import GoogleSearch
import os, json

params = {
    # https://docs.python.org/3/library/os.html#os.getenv
    'api_key': os.getenv('API_KEY'),    # your serpapi api
    'engine': 'yelp',                   # SerpApi search engine 
    'find_desc': 'Coffee',              # query
    'find_loc': 'New York, NY, USA',    # location
    'start': 0                          # pagination
}

search = GoogleSearch(params)           # where data extraction happens on the SerpApi backend
results = search.get_dict()             # JSON -> Python dict

organic_results_data = [
    (result['title'], result['place_ids'][0]) 
    for result in results['organic_results']
]

yelp_reviews = []

for title, place_id in organic_results_data:
    reviews_params = {
        # https://docs.python.org/3/library/os.html#os.getenv
        'api_key': os.getenv('API_KEY'),    # your serpapi api
        'engine': 'yelp_reviews',           # SerpApi search engine 
        'place_id': place_id,               # Yelp ID of a place
        'start': 0                          # pagination
    }

    reviews_search = GoogleSearch(reviews_params)

    reviews = []

    # pagination
    while True:
        new_reviews_page_results = reviews_search.get_dict()

        if 'error' in new_reviews_page_results:
            break

        reviews.extend(new_reviews_page_results['reviews'])

        reviews_params['start'] += 10

    yelp_reviews.append({
        'title': title,
        'reviews': reviews
    })

print(json.dumps(yelp_reviews, indent=2, ensure_ascii=False))

Подготовка

Установить библиотеку:

pip install google-search-results

google-search-results — это пакет API SerpApi.

Код Пояснение

Импортировать библиотеки:

from serpapi import GoogleSearch
import os, json
  • GoogleSearchдля парсинга и парсинга результатов Google с помощью библиотеки веб-парсинга SerpApi.
  • osчтобы вернуть значение переменной среды (ключ SerpApi API).
  • jsonдля преобразования извлеченных данных в объект JSON.

В начале кода вам нужно сделать запрос, чтобы получить органические результаты. Затем из них будут извлечены названия и идентификаторы мест.

Параметры определены для генерации URL. Если вы хотите передать URL-адресу другие параметры, вы можете сделать это с помощью словаря params:

params = {
    # https://docs.python.org/3/library/os.html#os.getenv
    'api_key': os.getenv('API_KEY'),    # your serpapi api
    'engine': 'yelp',                   # SerpApi search engine 
    'find_desc': 'Coffee',              # query
    'find_loc': 'New York, NY, USA',    # location
    'start': 0                          # pagination
}

Затем мы создаем объект search, в котором данные извлекаются из серверной части SerpApi. В словаре results получаем данные из JSON:

search = GoogleSearch(params)   # data extraction on the SerpApi backend
results = search.get_dict()     # JSON -> Python dict

На данный момент первые 10 органических результатов хранятся в словаре results. Если вас интересуют все органические результаты с разбиением на страницы, ознакомьтесь с записью в блоге Очистить фильтры Yelp, рекламу и органические результаты с помощью Python.

В списке organic_results_data хранятся такие данные, как title и place_id, которые извлекаются из каждого органического результата. Эти данные понадобятся позже:

organic_results_data = [
    (result['title'], result['place_ids'][0]) 
    for result in results['organic_results']
]

📌Примечание: в списке result['place_ids'] есть два уникальных идентификатора. Вы можете использовать любой из них, обратившись к индексу 0 или 1. Например:

"place_ids": [
  "ED7A7vDdg8yLNKJTSVHHmg",
  "arabica-brooklyn"
]

Объявление списка yelp_reviews, куда будут добавлены извлеченные данные:

yelp_reviews = []

Затем вам нужно получить доступ к отзывам каждого места отдельно, повторяя список organic_results_data:

for title, place_id in organic_results_data:
    # data extraction will be here

Эти параметры определены для генерации URL для отзывов о текущем месте. Если вы хотите передать URL-адресу другие параметры, вы можете сделать это с помощью словаря reviews_params:

reviews_params = {
    # https://docs.python.org/3/library/os.html#os.getenv
    'api_key': os.getenv('API_KEY'),    # your serpapi api
    'engine': 'yelp_reviews',           # SerpApi search engine 
    'place_id': place_id,               # Yelp ID of a place
    'start': 0                          # pagination
}
  • api_keyParameter определяет используемый закрытый ключ SerpApi.
  • engineУстановите для параметра значение yelp_reviews, чтобы использовать механизм Yelp Reviews API.
  • place_idParameter определяет Yelp ID места. Каждое место имеет два уникальных идентификатора (например, ED7A7vDdg8yLNKJTSVHHmg и arabica-brooklyn), и вы можете использовать любой из них в качестве значения place_id. Для извлечения идентификаторов места вы можете использовать наш Yelp Search API.
  • startParameter определяет смещение результата. Он пропускает заданное количество результатов. Он используется для разбиения на страницы. (например, 0 (по умолчанию) — первая страница результатов, 10 — вторая страница результатов, 20 — третья страница результатов и т. д.).

📌Примечание: Вы также можете добавить другие Параметры API.

Затем мы создаем объект reviews_search, в котором данные извлекаются из серверной части SerpApi:

reviews_search = GoogleSearch(reviews_params)

Объявление списка reviews, куда будут добавляться извлеченные данные из текущего места:

reviews = []

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

while True:
    # pagination from current page

В словаре new_reviews_page_results получаем новый пакет данных в формате JSON:

new_reviews_page_results = reviews_search.get_dict()

Далее выполняется следующая проверка: если в объекте new_reviews_page_results текущей страницы есть error, выходим из цикла. Это нужно для того, чтобы цикл остановился, когда обзоры закончатся:

if 'error' in new_reviews_page_results:
    break

Расширение списка reviews новыми данными с этой страницы:

reviews.extend(new_reviews_page_results['reviews'])
# total_reviews = new_reviews_page_results['search_information']['total_results']
# user_name = new_reviews_page_results['reviews'][0]['user']['name']
# user_comment = new_reviews_page_results['reviews'][0]['comment']['text']
# review_date = new_reviews_page_results['reviews'][0]['date']

📌Примечание: в комментариях выше я показал, как извлекать определенные поля. Возможно, вы заметили new_reviews_page_results['reviews'][0]. Это индекс обзора, что означает, что мы извлекаем данные из первого обзора. new_reviews_page_results['reviews'][1] из второго обзора и так далее.

Параметр start увеличивается на 10, чтобы получить результаты со следующей страницы:

reviews_params['start'] += 10

После пагинации мы добавляем title и reviews с этого места в список yelp_reviews:

yelp_reviews.append({
    'title': title,
    'reviews': reviews
})

После получения всех данных они выводятся в формате JSON:

print(json.dumps(yelp_reviews, indent=2, ensure_ascii=False))

Выход

[
  {
    "title": "% Arabica",
    "reviews": [
      {
        "user": {
          "name": "Ruby C.",
          "user_id": "i7pw5JmqEFi_ooWZ-r9AzA",
          "link": "https://www.yelp.com/user_details?userid=i7pw5JmqEFi_ooWZ-r9AzA",
          "thumbnail": "https://s3-media0.fl.yelpcdn.com/photo/CccPdSignI0J5ThhwDJHAw/60s.jpg",
          "address": "Brooklyn, NY",
          "photos": 108,
          "reviews": 27
        },
        "comment": {
          "text": "Craving for coffee while wandering around Dumbo area. The red brickhouse of %Arabica came to my eyes which attracted me immediately.  If you visit Dumbo, go grab a coffee and watch sunset by the sea - I swear %Arabica will never disappoint you! Iced Latte w/ Oat MilkSignature iced drink plastic cup with % logo on it. The gradient layers of espresso and oat milk was such an art piece. Impressive coffee bean savor!  I will definitely consider purchasing their coffee beans. Hot LatteTulip latte art on paper cup. The mixing was good yet the petals pushed a little bit too forward.  My fam was so in love with their latte! My Recommendations:Any iced drink  (very instagrammable) Worth Returning? YES DEFINITELYFollow @nyc.bgoo on Instagram for more honest food reviews!",
          "language": "en"
        },
        "date": "11/16/2022",
        "rating": 5,
        "tags": [
          "4 photos"
        ],
        "photos": [
          {
            "link": "https://s3-media0.fl.yelpcdn.com/bphoto/dPT4qVtR030f-Tefnm4U-g/o.jpg",
            "caption": "Hot Latte",
            "uploaded": "November 16, 2022"
          },
          {
            "link": "https://s3-media0.fl.yelpcdn.com/bphoto/jQSW785FG28q0GA12xhr0g/o.jpg",
            "uploaded": "November 16, 2022"
          },
          {
            "link": "https://s3-media0.fl.yelpcdn.com/bphoto/vSTYMIMoyIJ3ucUmWi6bNA/o.jpg",
            "uploaded": "November 16, 2022"
          },
          {
            "link": "https://s3-media0.fl.yelpcdn.com/bphoto/_85T0OKir1l1VeEWeSpQvw/o.jpg",
            "caption": "Iced Latte w/ Oat Milk",
            "uploaded": "November 16, 2022"
          }
        ]
      },
      ... other reviews
    ]
  },
  ... other places
]

📌Примечание: отправляйтесь на детскую площадку для живой и интерактивной демонстрации.

Ссылки

Первоначально опубликовано на SerpApi: https://serpapi.com/blog/using-yelp-reviews-api-from-serpapi-with-python/

Присоединяйтесь к нам в Твиттере | "YouTube"

Добавьте Запрос функции💫 или Ошибку🐞