Скрапинг данных с Yelp с использованием Python

Комментарии: 0

Извлечение информации с Yelp предоставляет полезные данные о местных ресторанах, включая их названия, URL-адреса, типы кухни и рейтинги. В этом руководстве показано, как скрапить данные из результатов поиска на Yelp с использованием библиотек Python, таких как requests и lxml. Также будут рассмотрены методы работы с прокси, управление HTTP-заголовками и извлечение данных через XPath.

Шаг 1: Подготовка среды

Перед началом скрапинга установите Python и необходимые библиотеки:

pip install requests
pip install lxml

Эти библиотеки необходимы для отправки HTTP-запросов на Yelp, парсинга HTML-контента и извлечения нужной информации.

Шаг 2: Отправка запроса на Yelp

Для начала выполните GET-запрос к странице результатов поиска на Yelp, чтобы получить HTML-контент. Пример кода:

import requests

# URL страницы поиска Yelp
url = "Ссылка HTTPS"

# Отправка GET-запроса для получения HTML-контента
response = requests.get(url)

# Проверка успешности запроса
if response.status_code == 200:
    print("Successfully fetched the page content")
else:
    print("Failed to retrieve the page content")

Важность HTTP-заголовков

При отправке запросов на веб-сайт очень важно включать соответствующие HTTP-заголовки. Заголовки могут содержать метаданные о запросе, такие как юзер агент пользователя, который идентифицирует браузер или инструмент, отправляющий запрос. Включение этих заголовков может помочь избежать блокировки или ограничения скорости со стороны целевого веб-сайта.

Вот как можно настроить заголовки:

headers = {
    'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
    'accept-language': 'en-IN,en;q=0.9',
    'cache-control': 'no-cache',
    'dnt': '1',
    'pragma': 'no-cache',
    'priority': 'u=0, i',
    'sec-ch-ua': '"Not)A;Brand";v="99", "Google Chrome";v="127", "Chromium";v="127"',
    'sec-ch-ua-mobile': '?0',
    'sec-ch-ua-platform': '"Linux"',
    'sec-fetch-dest': 'document',
    'sec-fetch-mode': 'navigate',
    'sec-fetch-site': 'none',
    'sec-fetch-user': '?1',
    'upgrade-insecure-requests': '1',
    'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36',
}

response = requests.get(url, headers=headers)

Реализация ротации прокси

При скрапинге большого объема страниц ваш IP-адрес может быть заблокирован целевым сайтом. Чтобы избежать этого, рекомендуется использовать прокси-сервера.

Для данного руководства рекомендуется применить динамические прокси-сервера с автоматической ротацией. Вам необходимо лишь настроить параметры прокси-сервера.

proxies = {
    'http': 'http://username:password@proxy-server:port',
    'https': 'https://username:password@proxy-server:port'
}

response = requests.get(url, headers=headers, proxies=proxies)

Шаг 3: Парсинг HTML-контента с помощью lxml

Получив HTML-контент, следующим шагом будет его парсинг и извлечение соответствующих данных. Для этой цели мы будем использовать библиотеку lxml.

from lxml import html

# Парсинг HTML-контента с помощью lxml
parser = html.fromstring(response.content)

Определение элементов для парсинга

Нам нужно выделить отдельные данные о ресторанах на странице результатов поиска. Эти элементы можно идентифицировать с помощью выражений XPath. На Yelp записи обычно находятся в элементе div с определенным атрибутом data-testid.

# Извлечение элементов каждого ресторана
elements = parser.xpath('//div[@data-testid="serp-ia-card"]')[2:-1]

Использование XPath для извлечения данных

XPath представляет собой эффективный инструмент для навигации и выбора узлов из HTML-документа. В данном руководстве мы применим выражения XPath для извлечения информации о названии ресторана, его URL-адресе, типе кухни и рейтинге для каждого элемента списка ресторанов.

Ниже приведены специфические XPath выражения для каждого элемента данных:

  1. Название ресторана: .//div[@class="businessName__09f24__HG_pC y-css-ohs7lg"]/div/h3/a/text()
  2. Ссылка на ресторан: .//div[@class="businessName__09f24__HG_pC y-css-ohs7lg"]/div/h3/a/@href
  3. Кухня: .//div[@class="priceCategory__09f24___4Wsg iaPriceCategory__09f24__x9YrM y-css-2hdccn"]/div/div/div/a/button/span/text()
  4. Рейтинг: .//div[@class="y-css-9tnml4"]/@aria-label

Шаг 4: Извлечение данных из списка ресторанов

После получения HTML-содержимого и обработки возможных блокировок IP-адресов можно приступить к извлечению данных из каждого ресторана.

restaurants_data = []

# Перебираем каждую запись ресторана
for element in elements:
    # Получаем название ресторана
    name = element.xpath('.//div[@class="businessName__09f24__HG_pC y-css-ohs7lg"]/div/h3/a/text()')[0]

    # Получаем URL ресторана
    url = element.xpath('.//div[@class="businessName__09f24__HG_pC y-css-ohs7lg"]/div/h3/a/@href')[0]

    # Получаем информацию о кухне
    cuisines = element.xpath('.//div[@class="priceCategory__09f24___4Wsg iaPriceCategory__09f24__x9YrM y-css-2hdccn"]/div/div/div/a/button/span/text()')

    # Получаем рейтинг
    rating = element.xpath('.//div[@class="y-css-9tnml4"]/@aria-label')[0]

    # Создаем словарь для хранения данных о ресторане
    restaurant_info = {
        "name": name,
        "url": url,
        "cuisines": cuisines,
        "rating": rating
    }

    # Добавляем данные ресторана в список
    restaurants_data.append(restaurant_info)

Шаг 5: Сохранение данных в формате JSON

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

import json

# Сохраняем данные в файл JSON
with open('yelp_restaurants.json', 'w') as f:
    json.dump(restaurants_data, f, indent=4)

print("Data extraction complete. Saved to yelp_restaurants.json")

Финальная версия кода

import requests
from lxml import html
import json

# URL страницы поиска Yelp
url = "Ссылка HTTPS"

# Настройка заголовков для имитации запроса из браузера
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
    'Accept-Language': 'en-US,en;q=0.5'
}

# Настройка прокси
proxies = {
    'http': 'http://username:password@proxy-server:port',
    'https': 'https://username:password@proxy-server:port'
}

# Отправка GET-запроса для получения HTML-содержимого
response = requests.get(url, headers=headers, proxies=proxies)

# Проверка успешности запроса
if response.status_code == 200:
    print("Successfully fetched the page content")
else:
    print("Failed to retrieve the page content")

# Парсинг HTML-содержимого с помощью lxml
parser = html.fromstring(response.content)

# Извлечение элементов каждого ресторана
elements = parser.xpath('//div[@data-testid="serp-ia-card"]')[2:-1]

# Инициализация списка для сохранения извлеченных данных
restaurants_data = []

# Итерация по каждому элементу ресторана
for element in elements:
    # Извлечение названия ресторана
    name = element.xpath('.//div[@class="businessName__09f24__HG_pC y-css-ohs7lg"]/div/h3/a/text()')[0]

    # Извлечение URL ресторана
    url = element.xpath('.//div[@class="businessName__09f24__HG_pC y-css-ohs7lg"]/div/h3/a/@href')[0]

    # Извлечение кухни
    cuisines = element.xpath('.//div[@class="priceCategory__09f24___4Wsg iaPriceCategory__09f24__x9YrM y-css-2hdccn"]/div/div/div/a/button/span/text()')

    # Извлечение рейтинга
    rating = element.xpath('.//div[@class="y-css-9tnml4"]/@aria-label')[0]

    # Создание словаря для сохранения данных
    restaurant_info = {
        "name": name,
        "url": url,
        "cuisines": cuisines,
        "rating": rating
    }

    # Добавление информации о ресторане в список
    restaurants_data.append(restaurant_info)

# Сохранение данных в файл JSON
with open('yelp_restaurants.json', 'w') as f:
    json.dump(restaurants_data, f, indent=4)

print("Data extraction complete. Saved to yelp_restaurants.json")

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

Комментарии:

0 комментариев