перейти к содержанию

Как парсить бизнес-данные и обзоры YellowPages.com

Привет всем!

Хотите извлечь данные с YellowPages.com? Хотите получить списки компаний, контактную информацию и отзывы?

В этом подробном руководстве я поделюсь всем, что вам нужно для создания надежного веб-парсера YellowPages с использованием Python.

В конце концов вы сможете собирать огромные объемы бизнес-данных с YellowPages быстрее, чем пролистывать распечатанную телефонную книгу!

Давайте начнем.

Зачем очищать данные YellowPages?

Первый вопрос: зачем вообще парсить YellowPages?

Вот некоторые из наиболее часто используемых случаев:

  • Бизнес-аналитика – Соберите базы данных компаний, местоположений, категорий и т. д. Отлично подходит для исследования рынка.

  • Лидогенерация – Извлекайте контактные данные, такие как адреса электронной почты и номера телефонов, для продаж.

  • SEO – Используйте бизнес-категории, ключевые слова и ссылки для анализа конкурентов.

  • Анализ настроений – Изучите отзывы клиентов о восприятии продукта/бренда.

  • Обогащение данных – Расширьте существующие CRM и маркетинговые данные с помощью дополнительных полей.

Фактически, в BrightLocal опрос97% потребителей заявили, что читают онлайн-обзоры, изучая местные предприятия. Таким образом, все эти обзорные данные на YellowPages могут дать чрезвычайно ценную информацию.

Суть в том, что на YellowPages есть масса бизнес-данных, которые при правильном использовании могут дать вам конкурентное преимущество.

Теперь давайте посмотрим, как его извлечь.

Настройка скребка

Чтобы продолжить, вам понадобится:

  • Питон – В этом руководстве я буду использовать Python 3.6+, но Python 2.7+ также должен работать.
  • Редактор кода - Предложенный: Visual Studio Code, бесплатный и отлично работает
  • Библиотеки Python:

Вы можете легко установить эти библиотеки с помощью pip:

pip install requests bs4 pandas

И это все, что касается зависимостей!

Единственное, что вам может понадобиться, это IP-адреса прокси о чем мы расскажем позже, чтобы избежать блокировки при очистке масштаба.

Теперь приступим к написанию нашего парсера!

Первый шаг — найти реальные предприятия, которые можно очистить.

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

Например, поиск «Японские рестораны в Сан-Франциско» приведет нас к:

https://www.yellowpages.com/search?search_terms=Japanese+Restaurants&geo_location_terms=San+Francisco+CA

Главное, на что следует обратить внимание, это то, что поисковый запрос и местоположение передаются как параметры URL.

Давайте напишем функцию для генерации этих URL-адресов поиска:

import requests

def search_url(query, location):

  url = ‘https://www.yellowpages.com/search‘

  params = {
    ‘search_terms‘: query,
    ‘geo_location_terms‘: location
  }

  return requests.Request(‘GET‘, url, params=params).prepare().url

Здесь мы используем превосходный Запросы библиотека для подготовки запроса GET, который позволяет нам создать URL-адрес поиска из любых ключевых слов и местоположений.

Давайте попробуем:

print(search_url(‘Japanese Restaurants‘, ‘San Francisco, CA‘))

# https://www.yellowpages.com/search?search_terms=Japanese+Restaurants&geo_location_terms=San+Francisco%2C+CA

Работает отлично! С помощью этой функции мы теперь можем легко создавать URL-адреса для поиска любой компании на YellowPages.

Теперь давайте посмотрим на парсинг и анализ страниц результатов.

Парсинг результатов поиска

Каждая страница результатов поиска YellowPages содержит около 30 списков компаний.

Вот фрагмент того, как выглядит HTML:

<div class="result">

  <div class="business-name">
    <a href="/ru/biz/ichiraku-ramen-san-francisco-3">Ichiraku Ramen</a>  
  </div>

  <div class="phones">
    (415) 563-6866
  </div>

</div>

Учитывая страницу HTML, мы хотим извлечь название компании, номер телефона, адрес и т. д.

Для анализа HTML в Python мы воспользуемся чрезвычайно полезным КрасивыйСуп библиотека.

Вот как мы можем анализировать результаты поиска:

from bs4 import BeautifulSoup

def parse_results(html):

  soup = BeautifulSoup(html, ‘html.parser‘)

  businesses = []

  for result in soup.select(‘.result‘):

    name = result.select_one(‘.business-name‘).text
    phone = result.select_one(‘.phones‘).text

    business = {
      ‘name‘: name,
      ‘phone‘: phone
    }

    businesses.append(business)

  return businesses

Мы тут:

  1. Инициализируйте BeautifulSoup с помощью HTML
  2. Перебрать каждый .result DIV
  3. Внутри извлеките имя и телефон с помощью селекторов CSS.
  4. Сохраните в диктовке и добавьте в наш список

Чтобы проверить это, мы можем передать пример HTML:

# Load sample HTML 
with open(‘results.html‘) as f:
  html = f.read()

data = parse_results(html)

print(data[0][‘name‘]) # Ichiraku Ramen

Идеальный! С parse_results() теперь мы можем извлекать структурированные данные с любой страницы результатов поиска.

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

import requests

url = search_url(‘Restaurants‘, ‘Los Angeles, CA‘)

response = requests.get(url)
page1_data = parse_results(response.text) 

print(len(page1_data)) # 30 businesses

Это дает нам 30 компаний со страницы 1. Теперь нам нужно получить остальное!

Разбивка по страницам результатов поиска

Извлекать Найти в списках поиска, нам нужно пролистать страницы результатов.

По умолчанию на каждой странице отображается 30 компаний.

Глядя на HTML, мы видим, что общее количество результатов отображается следующим образом:

<div class="pagination-result-summary">
  1 - 30 of 2,347 results
</div>

Мы можем проанализировать это общее число результатов, вычислить количество необходимых страниц, а затем просмотреть каждую страницу, чтобы извлечь все предприятия.

Вот функция для реализации этого:

from math import ceil

def scrape_search(query, location):

  url = search_url(query, location)

  html = requests.get(url)

  # Get total businesses
  soup = BeautifulSoup(html.text, ‘html.parser‘)
  totals_text = soup.select_one(‘.pagination-result-summary‘).text 
  total = int(totals_text.split(‘of‘)[-1].strip().replace(‘,‘, ‘‘))

  print(f‘Found {total} businesses for {query} in {location}‘)

  # Calculate pages
  num_pages = ceil(total / 30)
  print(f‘Scraping {num_pages} pages...‘)

  businesses = []

  for page in range(1, num_pages+1):

    # Update page number parameter
    url = update_page_number(url, page)

    html = requests.get(url).text
    data = parse_results(html)

    businesses.extend(data)

  print(f‘Scraped {len(businesses)} businesses‘)

  return businesses

def update_page_number(url, page):

  # Update page=X parameter
  return url.split(‘&page=‘)[0] + f‘&page={page}‘ 

Мы тут:

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

Теперь мы можем запустить его, чтобы извлечь тысячи списков:

data = scrape_search(‘Restaurants‘, ‘Houston, TX‘)

print(len(data)) # 23,472 restaurants!

И вот оно — используя поиск и нумерацию страниц, мы можем собрать огромные объемы списков компаний на YellowPages.

Теперь давайте рассмотрим извлечение дополнительных данных с отдельных бизнес-страниц.

Парсинг страниц с перечнем компаний

С помощью нашего поискового парсера мы можем найти тысячи URL-адресов компаний для извлечения.

Например:

https://www.yellowpages.com/los-angeles-ca/mip/in-n-out-burger-4800228

Эти страницы со списком содержат гораздо больше данных, таких как часы работы, услуги, описания, обзоры и многое другое.

Наша цель — очистить такие поля, как:

  • Имя
  • Адрес
  • Телефон
  • Вебсайт
  • Рейтинг
  • Часов
  • Услуги
  • И т.д.

Давайте посмотрим, как анализировать эти страницы.

Во-первых, функция для получения HTML-кода страницы:

import requests

def get_listing(url):

  response = requests.get(url)
  return response.text

Затем мы можем проанализировать ключевые поля:

from bs4 import BeautifulSoup

def parse_listing(html):

  soup = BeautifulSoup(html, ‘html.parser‘)

  name = soup.select_one(‘h1.business-name‘).text.strip()

  fields = {
    ‘phone‘: soup.select_one(‘.phone‘).text,
    ‘website‘: soup.select_one(‘.website a‘)[‘href‘],
    ‘address‘: ‘\n‘.join([i.text for i in soup.select(‘.street-address‘)]),    
  }

  # Map category links to names 
  categories = []
  for link in soup.select(‘.categories a‘):
    categories.append(link.text)

  try:
    rating = soup.select_one(‘.star-rating‘)[‘aria-label‘]
  except:
    rating = None

  data = {
    ‘name‘: name,
    ‘categories‘: categories,
    ‘rating‘: rating    
  }
  data.update(fields)

  return data

Здесь мы извлекаем ключевые поля с помощью селекторов CSS. Я использовал try/except безопасно обрабатывать случаи, когда рейтинг отсутствует.

Давайте попробуем это на живом листинге:

url = ‘https://www.yellowpages.com/los-angeles-ca/mip/in-n-out-burger-4800228‘ 

html = get_listing(url)
data = parse_listing(html)

print(data[‘name‘]) # In-N-Out Burger
print(data[‘rating‘]) # Rated 4.7 out of 5

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

Есть еще много полей, которые мы могли бы извлечь, например, услуги, часы работы, описания и т. д. Но это охватывает основы.

Теперь давайте посмотрим на масштабирование нашего парсера с помощью прокси, чтобы избежать блоков.

Скребковое масштабирование с помощью прокси

Если при парсинге любого сайта вы отправите слишком много запросов с одного и того же IP, в конечном итоге вас заблокируют.

Чтобы масштабировать парсеры и избежать попадания в черный список, мы можем использовать прокси-серверы.

Прокси-серверы направляют ваши запросы через разные IP-адреса, предотвращая блокировку за спам.

Давайте обновим наш код для использования прокси:

import requests
from random import choice

# List of proxy IPs
proxies = [‘123.123.123.1:8080‘, ‘98.98.98.2:8000‘...]

def get_listing(url):

  proxy = choice(proxies)

  response = requests.get(
    url,
    proxies={‘http‘: proxy, ‘https‘: proxy}
  )

  return response.text

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

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

Некоторые доступные источники прокси включают в себя:

Используя всего лишь 1,000 прокси, вы можете легко получить более 100,000 XNUMX списков YellowPages в день.

Помимо бизнес-данных, YellowPages также содержит отзывы клиентов, которые мы можем извлечь.

Парсинг отзывов на YellowPages

Обзоры предоставляют чрезвычайно ценную информацию о настроениях для бизнеса.

Хорошая новость: обзоры YellowPages также общедоступны и их можно очистить!

Отзывы разбиты на страницы, как и результаты поиска. Вот как выглядит страница:

<span class="pagination-result-summary">
  1 - 20 of 172 reviews
</span>

<!-- Individual review -->
<article>
  <div class="review-title">
    Great service and prices!
  </div>

  <div class="review-body">
    I had a great experience here. The staff was very friendly and prices reasonable. Would recommend!
  </div>
</article>

Чтобы парсить отзывы, нам нужно:

  1. Анализ общего количества отзывов
  2. Пролистывать каждую страницу
  3. Извлеките название обзора, текст, автора и т. д.

Вот как мы можем это сделать:

from bs4 import BeautifulSoup

def parse_reviews(html):

  soup = BeautifulSoup(html, ‘html.parser‘)

  # Get total reviews
  total = int(soup.select_one(‘.pagination-result-summary‘).text.split()[0])

  reviews = []

  for review in soup.select(‘#reviews article‘):

    title = review.select_one(‘.review-title‘).text  
    body = review.select_one(‘.review-body‘).text

    data = {
      ‘title‘: title,
      ‘body‘: body
    }

    reviews.append(data)

  return {
    ‘total‘: total,
    ‘reviews‘: reviews
  }

Для разбивки на страницы мы можем повторно использовать нашу логику разбивки на страницы:

from math import ceil
from urllib.parse import urlencode

def scrape_reviews(url):

  page = 1
  reviews = []

  while True:

    page_url = f‘{url}?{urlencode({"page": page})}‘

    html = get_listing(page_url)
    data = parse_reviews(html)

    reviews.extend(data[‘reviews‘])

    if len(reviews) >= data[‘total‘]:
      break

    page += 1

  return reviews  

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

def scrape_listing(url):

  html = get_listing(url)

  data = parse_listing(html)

  # Get reviews
  data[‘reviews‘] = scrape_reviews(url)

  return data

И вот он у нас — наш полный парсер YellowPages!

Он способен извлекать бизнес-данные вместе с отзывами клиентов для полного контекста.

Полный код этого руководства по парсингу можно найти на странице GitHub.

Обзор

Парсинг YellowPages может предоставить ценные данные бизнес-аналитики в большом масштабе.

В этом руководстве вы узнали:

  • Парсинг поиска – Находите предприятия по категориям и местоположению
  • Результаты – Очистите все страницы поиска, чтобы получить полные списки
  • Анализ листинга – Извлечение таких полей, как имя, адрес, часы работы и т. д., с бизнес-страниц.
  • Обзор парсинга – Анализируйте отзывы клиентов, включая текст, рейтинги и многое другое.
  • Использование прокси – Направляйте запросы через прокси, чтобы избежать блокировки.

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

Я надеюсь, что это даст вам основу, которая поможет вам извлекать и использовать данные YellowPages в ваших собственных проектах.

Дайте мне знать, если у вас есть еще вопросы! Я всегда рад помочь коллегам-энтузиастам данных.

Продолжайте царапать!

Теги:

Присоединяйтесь к беседе

Ваш электронный адрес не будет опубликован. Обязательные поля помечены * *