Meteen naar de inhoud

Hoe u Yelp.com kunt webscrapen: de ultieme gids van 3000 woorden voor het extraheren van bedrijfsvermeldingen, recensies en andere gegevens

Yelp is een van de grootste crowdsourced beoordelingsplatforms op internet. Met meer dan 200 miljoen beoordelingen van restaurants, bars, salons, winkels en andere bedrijven in meer dan 30 landen bevat het een goudmijn aan gegevens voor analisten, onderzoekers, ondernemers en meer.

Maar is het mogelijk om deze gegevens te extraheren via webscraping? Absoluut!

In deze uitgebreide gids van meer dan 3000 woorden deel ik alles wat je nodig hebt om een ​​webschraper te bouwen die met Python enorme datasets uit Yelp kan extraheren.

Hier is een kort overzicht van wat we zullen behandelen:

  • Het opzetten van onze Python webscraping-omgeving
  • Het vinden en extraheren van alle bedrijven die aan een zoekopdracht voldoen
  • Belangrijke details zoals naam, adres en telefoonnummers van bedrijfsprofielpagina's schrapen
  • Het extraheren van alle beoordelingen voor een bedrijf, inclusief beoordelingen, gebruikersgegevens enz.
  • Botdetectie vermijden via proxy's, vertragingen en andere trucs

Dus zet je schrap en laten we gaan schrapen!

Een Python Web Scraping-omgeving opzetten

Voordat we Yelp kunnen schrapen, moeten we een Python-omgeving opzetten met de vereiste afhankelijkheden.

Er zijn een paar belangrijke pakketten die we moeten installeren:

Aanvragen – om HTTP-verzoeken naar de servers van Yelp te sturen

Mooie soep – om gegevens uit de HTML-pagina's van Yelp te parseren en te extraheren

Scrapy – (optioneel) een raamwerk voor het bouwen van schrapers

Ik raad aan om een ​​virtuele omgeving te maken voordat je deze installeert:

python -m venv scraping-env
source scraping-env/bin/activate

Nu kunnen we de pakketten installeren:

pip install requests beautifulsoup4 scrapy

Dat is het voor afhankelijkheden. We hebben ook geldige headers nodig, zodat de servers van Yelp denken dat onze verzoeken afkomstig zijn van een echte browser:

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36"
}

De sleutel is het overtuigen User-Agent koptekst. Ik raad aan om meerdere browsergebruikersagenten te roteren om echt verkeer verder na te bootsen.

En we zijn klaar om te beginnen met schrapen!

Bedrijven vinden op Yelp

Onze eerste uitdaging is het ontdekken van bedrijfsprofiel-URL's van Yelp die we kunnen scrapen. Yelp biedt geen openbare API of sitemap die we hiervoor kunnen opvragen.

We zullen dus hun zoekfunctionaliteit moeten reverse-engineeren om bedrijven te vinden die overeenkomen met een zoekterm of locatie.

Laten we een typische zoekopdracht analyseren:

https://www.yelp.com/search?find_desc=restaurants&find_loc=San+Francisco

Dit retourneert een gepagineerde reeks bedrijven die voldoen aan onze zoekcriteria. Elke pagina bevat 10 bedrijfsvermeldingen.

Om ALLE overeenkomende bedrijven te extraheren, moeten we:

  1. Haal de eerste pagina op om het totale aantal bedrijven te bekijken
  2. Blader door alle pagina's door de waarde te verhogen start parameter

Hier ziet u hoe we deze pagineringslogica in Python kunnen implementeren:

import requests
from urllib.parse import urlencode
from bs4 import BeautifulSoup

search_url = "https://www.yelp.com/search?"

params = {
  "find_desc": "restaurants",
  "find_loc": "San Francisco"  
}

search_url += urlencode(params)

print("Fetching first page")
first_page = requests.get(search_url, headers=headers)
soup = BeautifulSoup(first_page.content, "html.parser")

businesses = soup.select(".businessName") 
total = int(soup.select_one(".pagination-results-window").text.split()[0].replace(‘,‘, ‘‘))
print(f"Found {total} businesses")

# Calculate pages needed to cover all businesses
num_pages = math.ceil(total / 10)

print(f"Scraping {num_pages} pages...")

for page in range(0, num_pages):

  # Update start param 
  params["start"] = page * 10
  page_url = search_url + "&" + urlencode(params)

  # Fetch page
  print(f"Page {page+1}/{num_pages}")
  page = requests.get(page_url, headers=headers)

  # Extract businesses
  page_soup = BeautifulSoup(page.content, "html.parser")
  businesses.extend(page_soup.select(".businessName"))

print(f"Found {len(businesses)} businesses!")

Laten we dit opsplitsen:

  • We beginnen met de basiszoek-URL en zoekparameters
  • Haal de eerste pagina op om het totale aantal bedrijven te bekijken
  • Bereken het aantal pagina's dat nodig is voor alle bedrijven
  • Blader door de pagina's die het updaten start param
  • Op elke pagina extraheert u de bedrijfsvermeldingen en voegt u deze toe aan de hoofdlijst

In mijn test werd dit geëxtraheerd 6,000 restaurantvermeldingen in San Francisco – niet slecht voor 30 regels Python!

Met wat extra aanpassingen zou je er een zakelijke schraper van Yelp voor een hele stad of land van kunnen maken.

Bedrijfsprofielpagina's schrapen

Nu we bedrijfsprofiel-URL's kunnen ontdekken, is onze volgende stap het bezoeken van elke URL en het extraheren van belangrijke details, zoals:

  • Naam
  • Adres
  • Telefoon
  • Openingstijden
  • Omschrijving
  • Foto's
  • En meer ...

De bedrijfspagina's van Yelp worden dynamisch weergegeven, maar de onderliggende HTML is eenvoudig genoeg om te parseren met BeautifulSoup.

Laten we een voorbeeldfragment bekijken:



<p>
  <strong>Phone:</strong> 
  415-387-2147
</p>

<p>
  <strong>Address:</strong>
  1345 9th Ave, San Francisco, CA 94122
</p>

<!-- And so on... -->

We kunnen elk stukje informatie extraheren met een aantal goed geplaatste CSS-selectors:

from bs4 import BeautifulSoup
import requests

business_url = "https://www.yelp.com/biz/burma-superstar-san-francisco"

page = requests.get(business_url, headers=headers)
soup = BeautifulSoup(page.content, "html.parser")

name = soup.select_one("h1").text
phone = soup.find("strong", string="Phone:").next_sibling.strip() 
address = soup.find("strong", string="Address:").next_sibling.strip()

hours = {}
for day in soup.select(".day-hours"):
   day_name = day.select_one(".day-name").text
   hours[day_name] = day.select_one(".hours").text

print(name)
print(phone) 
print(address)
print(hours)

# Burma Superstar
# 415-387-2147
# 1345 9th Ave, San Francisco, CA 94122
# {‘Mon‘: ‘11:30am–3pm, 5–9:30pm‘, ‘Tue‘: ‘11:30am–3pm, 5–9:30pm‘...}

De belangrijkste punten zijn:

  • Te gebruiken select_one om enkelvoudige elementen zoals naam, telefoon enz. te extraheren.
  • Voor geneste gegevens zoals uren, loop door en bouw een woordenboek
  • Voeg aan CSS-selectors tags en klassen toe om ze uniek te maken

Met deze schrapende bouwstenen kunnen we tientallen velden van elke profielpagina extraheren naar een gestructureerd Python-woordenboek of JSON-object.

Enkele andere velden die u misschien wilt schrappen, zijn onder meer:

  • Categorietags zoals 'Mexicaans', 'Brunch' etc.
  • Keukentags zoals 'Burger', 'Sushi', 'Koffie' etc.
  • COVID-veiligheidsmaatregelen
  • Prijsbereik
  • Buurt
  • lengte-en breedtegraad
  • En meer ...

Als u hier creatief aan de slag gaat, kunt u uitgebreide Yelp-datasets bouwen met honderden velden die u indien nodig kunt analyseren.

Reviews schrappen van Yelp-bedrijfspagina's

Recensies zijn de kroonjuwelen van de gegevens van Yelp. Ze bieden ongelooflijke inzichten in het consumentensentiment, trends, demografische gegevens en meer.

Helaas worden recensies niet rechtstreeks in de HTML geladen. Ze worden dynamisch opgehaald via JavaScript-aanroepen.

We moeten deze verzoeken onderscheppen en nabootsen om beoordelingsgegevens te extraheren.

Laten we een bedrijfspagina openen en netwerkverzoeken monitoren in de browsertools:

Yelp beoordeelt netwerkverzoek

Aha – we kunnen zien dat beoordelingen worden geladen vanaf een URL zoals:

https://www.yelp.com/biz/{business_id}/reviews

Waar {business_id} is uniek voor elk bedrijf. We kunnen het uit de HTML van de bedrijfspagina halen.

Recensies zijn gepagineerd via de start parameter. We volgen dus dezelfde pagineringsstrategie:

  1. Haal de eerste pagina op om het totale aantal beoordelingen te bekijken
  2. Doorloop alle pagina's door te verhogen start

Hier is een script om alle beoordelingen voor een bedrijf te extraheren:

import json
import requests 

business_id = "WavvLdfdP6g8aZTtbBQHTw" # Extract this from HTML

review_url = f"https://www.yelp.com/biz/{business_id}/review_feed?rl=en&q=&sort_by=relevance_desc"

print("Fetching first page")
first_page = requests.get(review_url, headers=headers)
data = json.loads(first_page.text)

total = data["pagination"]["totalResults"]
print(f"Found {total} reviews")

reviews = data["reviews"]

for page in range(total//20 + 1): # 20 reviews per page

  print(f"Fetching page {page+1}/{math.ceil(total/20)}")
  next_page = f"{review_url}&start={page*20}"
  page_data = requests.get(next_page, headers=headers).json()

  reviews.extend(page_data["reviews"])

print(f"Scraped {len(reviews)} reviews!")

Boom! We hebben nu het volledige beoordelingscorpus voor een bedrijf met gegevens zoals:

{
   "id": "xAG4O7l-t1ubiIsO4cXMYg",
   "rating": 5,
   "user": {
      "id": "rpOyqD_893cqmDAtJLbdog",
      "profile_url": "https://www.yelp.com/user_details?userid=rpOyqD_893cqmDAtJLbdog",
      "name": "Sarah K.",
      "location": "Los Angeles, CA", 
      //...
   },
   "text": "This place is incredible! The sushi melts in your mouth and the...",
    //...
}

Het analyseren van deze gegevens kan sterke signalen opleveren over het klantsentiment op verschillende locaties, demografische gegevens, soorten keukens en meer.

Botdetectie vermijden

Nu we scrapers voor bedrijven en recensies hebben gebouwd, is het tijd om alles samen te voegen.

Eén probleem: als we de servers van Yelp belasten met duizenden verzoeken, worden we snel geblokkeerd.

Yelp maakt gebruik van geavanceerde botdetectiesystemen om misbruik te voorkomen, waaronder:

  • Gebruikslimieten – beperk hoe snel u pagina's kunt opvragen
  • CAPTCHA’s – daag gebruikers uit om te verifiëren dat ze een mens zijn
  • IP-verboden – blokkeer onrechtmatige IP-adressen

Hier zijn enkele tips om blokkades te voorkomen terwijl je Yelp op grote schaal schrapt:

Gebruik proxy's

Door verkeer via een grote verzameling residentiële IP's te leiden, kunnen we scrapers maskeren en eenvoudige IP-verboden vermijden.

Hier ziet u hoe u proxy's kunt gebruiken met de module Verzoeken:

from proxy_list import proxies 

# Rotate proxy per request
proxy = random.choice(proxies)

requests.get(url, headers=headers, proxies={"http": proxy, "https": proxy}) 

Ik zou aanraden om een ​​zwembad te hebben tenminste 10,000 proxy's uit verschillende IP-bereiken om veilig te zijn.

Voeg willekeurige vertragingen toe

Door gevarieerde vertragingen tussen verzoeken toe te voegen, wordt organisch menselijk gedrag nagebootst:

from random import randint

# Add random delay between 2s and 6s
time.sleep(randint(2, 6))

Streef naar een gemiddelde van 3-5 seconden tussen pagina's. Sneller zal rode vlaggen oproepen.

Gebruik een headless browser

Voor meer anonimiteit kunt u een headless browser zoals Selenium gebruiken om JavaScript weer te geven en beveiligingen te omzeilen.

Zorg ervoor dat u de browservingerafdruk en proxy per sessie wijzigt.

Los CAPTCHA's op met 2Captcha

Als u toch een CAPTCHA tegenkomt, kunnen services zoals 2Captcha deze automatisch oplossen om door te gaan met schrapen.

De meeste diensten rekenen ongeveer $ 2 per 1000 opgeloste CAPTCHA's, wat de moeite waard is om grote schrapers te schalen.

Respecteer accountbeperkingen

Houd uw accountstatuspagina in de gaten. Als je scrape-percentage te agressief is, kan Yelp tijdelijke gebruikslimieten opleggen.

Houd uw verzoeken in de gaten en ga terug als fouten aangeven dat u een gebruiksdrempel nadert.

Yelp schrappen: volgende stappen

En dat omvat de kerntechnieken voor het verzamelen van bedrijfsvermeldingen, profielen en recensies van Yelp!

De gegevens die u kunt extraheren, bieden talloze mogelijkheden:

  • Analyseer het consumentenvertrouwen in alle demografische categorieën
  • Volg trends en opkomende soorten keukens
  • Bouw voorspellende modellen voor zakelijke succesfactoren
  • Optimaliseer uw eigen SEO en reputatie
  • Voer een breed marktonderzoek uit
  • Identificeer advertentiemogelijkheden

Vergeet niet om de Servicevoorwaarden van Yelp na te leven, het verzoekvolume te beperken en te voorkomen dat er privégebruikersgegevens worden opgehaald.

Ik hoop dat je deze handleiding nuttig vond! Neem gerust contact op als u nog vragen heeft.

Veel plezier met schrapen!

Tags:

Doe mee aan het gesprek

Uw e-mailadres wordt niet gepubliceerd. Verplichte velden zijn gemarkeerd *