Bỏ để qua phần nội dung

Cách sử dụng Web Scrape Yelp.com: Hướng dẫn 3000 từ cơ bản để trích xuất danh sách doanh nghiệp, đánh giá và dữ liệu khác

Yelp là một trong những nền tảng đánh giá có nguồn gốc từ cộng đồng lớn nhất trên web. Với hơn 200 triệu bài đánh giá về nhà hàng, quán bar, thẩm mỹ viện, cửa hàng và các doanh nghiệp khác trên hơn 30 quốc gia, nó chứa đựng một kho dữ liệu vàng cho các nhà phân tích, nhà nghiên cứu, doanh nhân, v.v.

Nhưng liệu có thể trích xuất dữ liệu này thông qua việc quét web không? Tuyệt đối!

Trong hướng dẫn toàn diện hơn 3000 từ này, tôi sẽ chia sẻ mọi thứ bạn cần để xây dựng một công cụ quét web có thể trích xuất các tập dữ liệu khổng lồ từ Yelp bằng Python.

Dưới đây là tóm tắt nhanh về những gì chúng tôi sẽ đề cập:

  • Thiết lập môi trường quét web Python của chúng tôi
  • Tìm và trích xuất tất cả các doanh nghiệp phù hợp với truy vấn tìm kiếm
  • Quét các chi tiết chính như tên, địa chỉ, số điện thoại từ các trang hồ sơ doanh nghiệp
  • Trích xuất tất cả các đánh giá cho một doanh nghiệp bao gồm xếp hạng, chi tiết người dùng, v.v.
  • Tránh bị phát hiện bot thông qua proxy, độ trễ và các thủ thuật khác

Vì vậy, hãy thắt dây an toàn và bắt đầu cạo!

Thiết lập môi trường quét web Python

Trước khi có thể cạo Yelp, chúng ta cần thiết lập môi trường Python với các phần phụ thuộc cần thiết.

Có một số gói chính chúng ta cần cài đặt:

yêu cầu – để gửi yêu cầu HTTP đến máy chủ của Yelp

ĐẹpSúp – để phân tích và trích xuất dữ liệu từ các trang HTML của Yelp

Trị liệu – (tùy chọn) một khung để xây dựng các máy cạp

Tôi khuyên bạn nên tạo một môi trường ảo trước khi cài đặt những thứ này:

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

Bây giờ chúng ta có thể cài đặt các gói:

pip install requests beautifulsoup4 scrapy

Đó là nó cho sự phụ thuộc. Chúng tôi cũng cần các tiêu đề hợp lệ để máy chủ của Yelp cho rằng các yêu cầu của chúng tôi đến từ một trình duyệt thực:

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"
}

Điều quan trọng là thiết lập một thuyết phục User-Agent tiêu đề. Tôi khuyên bạn nên luân phiên nhiều tác nhân người dùng trình duyệt để bắt chước lưu lượng truy cập thực hơn nữa.

Và chúng tôi đã sẵn sàng để bắt đầu cạo!

Tìm doanh nghiệp trên Yelp

Thử thách đầu tiên của chúng tôi là khám phá các URL hồ sơ doanh nghiệp của Yelp để thu thập. Yelp không cung cấp API công khai hoặc sơ đồ trang web mà chúng tôi có thể truy vấn về vấn đề này.

Vì vậy, chúng tôi sẽ phải đảo ngược chức năng tìm kiếm của họ để tìm các doanh nghiệp phù hợp với cụm từ tìm kiếm hoặc vị trí.

Hãy phân tích một truy vấn tìm kiếm điển hình:

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

Điều này trả về một tập hợp các doanh nghiệp được phân trang phù hợp với tiêu chí tìm kiếm của chúng tôi. Mỗi trang chứa 10 danh sách doanh nghiệp.

Để trích xuất TẤT CẢ các doanh nghiệp phù hợp, chúng tôi cần:

  1. Tìm nạp trang đầu tiên để có được tổng số doanh nghiệp
  2. Lặp lại qua tất cả các trang bằng cách tăng start tham số

Đây là cách chúng ta có thể triển khai logic phân trang này trong Python:

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!")

Hãy chia nhỏ điều này:

  • Chúng tôi bắt đầu với URL tìm kiếm cơ sở và thông số tìm kiếm
  • Tìm nạp trang đầu tiên để nhận tổng số doanh nghiệp
  • Tính toán số trang cần thiết để bao gồm tất cả các doanh nghiệp
  • Lặp lại qua các trang cập nhật start tiền của tôi
  • Trên mỗi trang, trích xuất danh sách doanh nghiệp và thêm vào danh sách chính

Trong thử nghiệm của tôi, điều này được trích xuất 6,000 danh sách nhà hàng ở San Francisco – không tệ với 30 dòng Python!

Với một số chỉnh sửa bổ sung, bạn có thể biến công cụ này thành công cụ quét doanh nghiệp Yelp cho toàn bộ thành phố hoặc quốc gia.

Quét các trang hồ sơ doanh nghiệp

Bây giờ chúng ta có thể khám phá các URL hồ sơ doanh nghiệp, bước tiếp theo của chúng ta là truy cập từng URL và trích xuất các chi tiết chính như:

  • Họ tên
  • Địa Chỉ
  • Số điện thoại
  • Giờ mở cửa
  • Mô tả
  • Hình ảnh
  • Và hơn thế nữa…

Các trang kinh doanh của Yelp được hiển thị động nhưng HTML cơ bản đủ đơn giản để phân tích cú pháp bằng BeautifulSoup.

Hãy xem một đoạn ví dụ:



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

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

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

Chúng tôi có thể trích xuất từng bit thông tin bằng một số bộ chọn CSS được đặt hợp lý:

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‘...}

Các điểm chính là:

  • Sử dụng select_one để trích xuất các phần tử số ít như tên, số điện thoại, v.v.
  • Đối với dữ liệu lồng nhau như giờ, lặp lại và xây dựng từ điển
  • Bộ chọn CSS tiền tố với các thẻ và lớp để đảm bảo tính duy nhất

Với các khối xây dựng cóp nhặt này, chúng tôi có thể trích xuất hàng chục trường từ mỗi trang hồ sơ vào một từ điển Python có cấu trúc hoặc đối tượng JSON.

Một số lĩnh vực khác mà bạn có thể muốn xem xét việc cạo bao gồm:

  • Các thẻ danh mục như 'Mexico', 'Brunch', v.v.
  • Các thẻ ẩm thực như 'Burger', 'Sushi', 'Cà phê', v.v.
  • Các biện pháp an toàn phòng chống dịch bệnh COVID
  • Phạm vi giá
  • Vùng lân cận
  • kinh độ vĩ độ
  • Và hơn thế nữa…

Sáng tạo ở đây cho phép bạn xây dựng bộ dữ liệu Yelp mở rộng với hàng trăm trường để phân tích nếu cần.

Quét các bài đánh giá từ các trang kinh doanh của Yelp

Các bài đánh giá là viên ngọc quý trong dữ liệu của Yelp. Họ cung cấp những hiểu biết sâu sắc đáng kinh ngạc về tâm lý, xu hướng, nhân khẩu học của người tiêu dùng và hơn thế nữa.

Thật không may, các bài đánh giá không được tải trực tiếp vào HTML. Chúng được tìm nạp động thông qua lệnh gọi JavaScript.

Chúng tôi sẽ cần chặn và bắt chước những yêu cầu này để trích xuất dữ liệu đánh giá.

Hãy mở một trang kinh doanh và theo dõi các yêu cầu mạng trong các công cụ trình duyệt:

Yelp đánh giá yêu cầu mạng

Aha – chúng ta có thể thấy các bài đánh giá được tải từ một URL như:

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

Ở đâu {business_id} là duy nhất cho mỗi doanh nghiệp. Chúng tôi có thể trích xuất nó từ HTML của trang kinh doanh.

Đánh giá được phân trang thông qua start tham số. Vì vậy, chúng tôi sẽ thực hiện theo chiến lược phân trang tương tự:

  1. Tìm nạp trang đầu tiên để nhận tổng số đánh giá
  2. Lặp lại qua tất cả các trang bằng cách tăng dần start

Đây là đoạn script để trích xuất tất cả các đánh giá cho một doanh nghiệp:

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!")

Bùm! Hiện tại, chúng tôi có toàn bộ kho dữ liệu đánh giá về một doanh nghiệp có dữ liệu như:

{
   "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...",
    //...
}

Việc phân tích dữ liệu này có thể cung cấp những tín hiệu mạnh mẽ về cảm tính của khách hàng ở các vị trí, nhân khẩu học, loại hình ẩm thực, v.v.

Tránh bị phát hiện Bot

Bây giờ chúng ta đã xây dựng được các công cụ thu thập dữ liệu cho doanh nghiệp và đánh giá, đã đến lúc kết hợp tất cả lại với nhau.

Một vấn đề - nếu chúng tôi bắt đầu tấn công máy chủ của Yelp với hàng nghìn yêu cầu, chúng tôi sẽ nhanh chóng bị chặn.

Yelp sử dụng các hệ thống phát hiện bot tiên tiến để ngăn chặn hành vi lạm dụng, bao gồm:

  • Giới hạn sử dụng – giới hạn tốc độ bạn có thể yêu cầu các trang
  • CAPTCHA – thách thức người dùng xác minh họ là con người
  • Cấm IP – chặn các địa chỉ IP lạm dụng

Dưới đây là một số mẹo để tránh bị chặn khi quét Yelp trên quy mô lớn:

Sử dụng proxy

Bằng cách định tuyến lưu lượng truy cập thông qua một nhóm lớn các IP dân cư, chúng tôi có thể che giấu những kẻ lừa đảo và tránh các lệnh cấm IP dễ dàng.

Đây là cách sử dụng proxy với mô-đun Yêu cầu:

from proxy_list import proxies 

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

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

Tôi khuyên bạn nên có một nhóm ít nhất là 10,000 proxy từ các dải IP khác nhau để được an toàn.

Thêm độ trễ ngẫu nhiên

Việc thêm các độ trễ khác nhau giữa các yêu cầu giúp bắt chước hành vi tự nhiên của con người:

from random import randint

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

Đặt mục tiêu đạt mức trung bình 3-5 giây giữa các trang. Nhanh hơn nữa sẽ giương cờ đỏ.

Sử dụng trình duyệt không đầu

Để tăng tính ẩn danh, bạn có thể sử dụng trình duyệt không có giao diện người dùng như Selenium để hiển thị JavaScript và bỏ qua các biện pháp bảo vệ.

Chỉ cần đảm bảo thay đổi dấu vân tay và proxy của trình duyệt mỗi phiên.

Giải CAPTCHA bằng 2Captcha

Nếu bạn nhấn CAPTCHA, các dịch vụ như 2Captcha có thể tự động giải quyết chúng để tiếp tục thu thập dữ liệu.

Hầu hết các dịch vụ đều tính phí khoảng 2 USD cho mỗi 1000 CAPTCHA được giải, điều này đáng giá để mở rộng quy mô các trình dọn dẹp lớn.

Tôn trọng các giới hạn của tài khoản

Theo dõi trang trạng thái tài khoản của bạn. Nếu tỷ lệ thu thập dữ liệu của bạn quá cao, Yelp có thể thực thi các giới hạn sử dụng tạm thời.

Tăng tốc độ yêu cầu của bạn và dừng lại nếu lỗi cho thấy bạn sắp đạt đến ngưỡng sử dụng.

Cạo Yelp: Các bước tiếp theo

Và điều đó bao gồm các kỹ thuật cốt lõi để tìm kiếm danh sách, hồ sơ và đánh giá doanh nghiệp của Yelp!

Dữ liệu bạn có thể trích xuất sẽ mở ra vô số khả năng:

  • Phân tích tâm lý người tiêu dùng theo nhân khẩu học
  • Theo dõi xu hướng và các loại hình ẩm thực mới nổi
  • Xây dựng mô hình dự đoán các yếu tố thành công của doanh nghiệp
  • Tối ưu hóa SEO và danh tiếng của riêng bạn
  • Tiến hành nghiên cứu thị trường rộng rãi
  • Xác định cơ hội quảng cáo

Chỉ cần nhớ tuân theo Điều khoản dịch vụ của Yelp, giới hạn khối lượng yêu cầu và tránh trích xuất bất kỳ dữ liệu riêng tư nào của người dùng.

Tôi hy vọng bạn thấy hướng dẫn này hữu ích! Hãy liên hệ nếu bạn có bất kỳ câu hỏi nào khác.

Chúc mừng cạo!

tags:

Tham gia vào cuộc đối thoại

Chúng tôi sẽ không công khai email của bạn. Các ô đánh dấu * là bắt buộc *