轻松抓取Yelp评论:5个经过验证的Python步骤(2026)

Okkproxy 教程:使用 Python 轻松抓取 Yelp 评论的操作方法

要点总结:

为了在不被Cloudflare或TLS指纹识别拦截的情况下抓取Yelp评论,传统的Python库(例如requests)已不足以胜任。本分步指南演示了如何结合curl_cffi进行浏览器模拟、BeautifulSoup进行HTML解析以及pandas进行数据结构化处理。通过将此Python脚本与OKKProxy的轮换住宅代理结合使用,数据团队可以绕过HTTP403拦截,大规模提取完整的评论文本、评分、日期和菜单URL,并保持企业级99.4%的请求成功率。


引言:Yelp网页抓取的战略价值

在数字营销、本地搜索引擎优化和市场情报领域,用户生成内容(UGC)是竞争策略的主要驱动力。凭借数百万条经过验证的客户评论、本地商家资料、详细的菜单价格和评论者元数据,https://www.yelp.com是当今互联网上最丰富的公共数据集之一。

无论您是为连锁餐厅进行情感分析、进行多地点竞争对手基准测试,还是训练特定领域的AI模型,学习如何抓取Yelp数据都能为您带来可操作的运营优势。

数字营销人员和数据分析师经常会问:“如何免费大规模地查看Yelp评论?”或者“能否抓取Yelp评论而不触发即时IP封锁?”

虽然Yelp.com提供官方API,但它实施了严格的请求速率限制,返回的评论摘要也经过截断(每个商家最多只能返回3条评论),并且遗漏了重要的评论者个人资料指标。因此,开发一个由专业代理基础设施支持的自定义Yelp爬虫Python脚本是获取完整数据的常用方法。


抓取Yelp数据合法吗?法律和技术方面的限制

Okkproxy指南:抓取 Yelp 数据的法律边界与合规要点
Okkproxy教程:抓取 Yelp 数据到底合不合法?

Yelp网络抓取项目之前,合规和风险团队的首要任务是解决一个基本问题:抓取Yelp是否合法?

根据hiQLabs诉LinkedIn等里程碑式案件确立的法律先例,从公共网站(包括https://www.yelp.com上的公共企业资料)抓取公开可访问的数据,在美国法律下通常是允许的,前提是数据收集不会绕过密码验证或干扰目标服务器的运行。

抓取Yelp数据的基本合规指南:

  • 专注于公开可访问的数据:仅收集yelp.com上可见的公开评论、商家名称、星级评分和菜单URL,无需登录个人用户帐户。
  • 实施负责任的爬取策略:避免发起类似分布式拒绝服务(DDoS)攻击的激进并发请求。在请求之间使用随机延迟间隔(抖动)。
  • 隐私和数据保护合规性:确保收集的评论者数据集符合GDPR和CCPA等全球隐私框架,在存储之前去除个人身份信息(PII)。

了解Yelp的反机器人防御架构

为什么标准的Python脚本在尝试抓取Yelp数据时会失败?如果您执行基本的requests.get(“https://www.yelp.com/biz…”)调用,您的脚本几乎肯定会立即收到403Forbidden响应或CloudflareTurnstileCAPTCHA验证码挑战。

Yelp的反机器人系统部署了三种不同的安全机制:

1.JA3/JA4TLS指纹检测

requests或urllib这样的标准HTTP库依赖于默认的OpenSSL配置。在初始TLS握手期间,这些库会广播一个独特的加密签名(JA3/JA4指纹),该签名能够立即将请求识别为自动化的Python脚本,而不是像GoogleChrome或MozillaFirefox这样的真正Web浏览器。

2.IP信誉评分和子网限速

来自已知商业云数据中心(例如AWS、GCP、DigitalOcean)的请求会被评为低信任度。如果单个IP地址频繁快速地提交多个查询以抓取Yelp搜索或商家页面,Yelp的防火墙会在其整个子网内屏蔽该IP地址。

3.动态DOM类和混淆

Yelp会定期更新其HTML/CSS选择器类名(例如,将评论容器标签从.comment__09f24__0oKwX更改为动态哈希字符串)。当这些动态选择器发生变化时,静态CSS抓取程序就会失效。


前提条件和环境设置

为了在不依赖资源密集型无头浏览器(例如Selenium或Playwright)的情况下克服TLS指纹检测,我们使用curl_cffi。该库包含一个编译后的libcurl引擎,并打上了BoringSSL补丁,从而使Python脚本能够复制桌面浏览器版本的精确TLS签名。

所需软件包安装

在本地环境或虚拟Python服务器上执行以下命令:

Bash

pipinstallcurl_cffibeautifulsoup4pandas

模块概述

Library版本要求核心功能外部资源
curl_cffi>=0.6.0通过模拟真实的Chrome浏览器绕过JA3/JA4TLS指纹识别GitHub仓库
beautifulsoup4>=4.12.0解析HTMLDOM树并提取目标评论元素官方文件
pandas>=2.0.0将抓取到的评论数据整理成干净的DataFrame,以便导出为CSV/JSON格式。官方文件

剖析Yelp的URL结构和DOM机制

www.yelp.com的URL路由和DOM树结构对于构建高效的Yelp抓取工具至关重要。

1.搜索结果SERP路由

抓取Yelp搜索结果页面并查询商家类别时,Yelp使用以下URL结构:

https://www.yelp.com/search?find_desc=Restaurants&find_loc=San+Francisco%2C+CA&start=10

  • find_desc:业务类别或关键字搜索参数。
  • find_loc:地理目标位置。
  • 起始值:分页偏移参数(以10为步长递增)。

2.Yelp菜单URL结构格式

Yelp使用专门的URL路径模式来收集餐厅菜单详细信息:

https://www.yelp.com/menu[business-slug]

3.审查分页结构

Yelp.com上的商家评论列表使用通过起始URL参数显式偏移分页:

  • 第1页:https://www.yelp.com/biz/tartine-bakery-san-francisco?start=0
  • 第2页:https://www.yelp.com/biz/tartine-bakery-san-francisco?start=10
  • 第3页:https://www.yelp.com/biz/tartine-bakery-san-francisco?start=20

分步指南:如何使用Python抓取Yelp评论

Okkproxy 指南:使用 Python 抓取 Yelp 评论的完整操作步骤
Okkproxy 教程:如何用 Python 抓取 Yelp 评论数据

下面是一个完整的模块化Python抓取Yelp工具,它可以提取作者姓名、星级评分、评论日期和评论文本,同时管理代理路由和浏览器模拟。

Python

import time
import random
import pandas as pd
from bs4 import BeautifulSoup
from curl_cffi import requests

def format_proxy_url(username, password, endpoint, port):
    “””
    Formats proxy credentials into a standard HTTP proxy string for curl_cffi.
    “””
    return f”http://{username}:{password}@{endpoint}:{port}”

def scrape_yelp_reviews(biz_url, total_pages=3, proxy_config=None):
    “””
    Scrapes public reviews from a target Yelp business page using browser
    impersonation and IP rotation via OKKProxy.
    “””
    extracted_reviews = []
    
    # Emulate browser headers
    headers = {
        “User-Agent”: “Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36”,
        “Accept”: “text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8”,
        “Accept-Language”: “en-US,en;q=0.9”,
        “Referer”: “https://www.google.com/”,
    }

    # Configure Proxy Endpoint
    proxies = None
    if proxy_config:
        proxy_endpoint = format_proxy_url(
            proxy_config[‘username’],
            proxy_config[‘password’],
            proxy_config[‘endpoint’],
            proxy_config[‘port’]
        )
        proxies = {“http”: proxy_endpoint, “https”: proxy_endpoint}

    for page_idx in range(total_pages):
        offset = page_idx * 10
        paginated_target_url = f”{biz_url}?start={offset}”
        print(f”[i] Fetching Page {page_idx + 1}: {paginated_target_url}”)

        try:
            # Impersonate Chrome 120 TLS fingerprint using curl_cffi
            response = requests.get(
                paginated_target_url,
                headers=headers,
                proxies=proxies,
                impersonate=”chrome120″,
                timeout=15
            )

            if response.status_code != 200:
                print(f”[!] Request blocked or returned status code {response.status_code} on page {page_idx + 1}”)
                break

            soup = BeautifulSoup(response.text, “html.parser”)
            
            # Match review containers using partial class name matching
            review_blocks = soup.find_all(“div”, class_=lambda c: c and “review__” in c)
            
            # Fallback selector logic if dynamic CSS classes shift
            if not review_blocks:
                review_blocks = soup.select(“ul > li div[aria-label*=’rating’]”)
                if review_blocks:
                    review_blocks = [r.find_parent(“div”) for r in review_blocks]

            print(f”[*] Identified {len(review_blocks)} review cards on page {page_idx + 1}”)

            for block in review_blocks:
                # Extract Author Name
                author_node = block.find(“a”, class_=lambda c: c and “css-” in c)
                author_name = author_node.text.strip() if author_node else “Anonymous”

                # Extract Star Rating via aria-label
                rating_node = block.find(“div”, attrs={“aria-label”: lambda a: a and “star rating” in a.lower() if a else False})
                star_rating = rating_node[“aria-label”] if rating_node else “N/A”

                # Extract Review Date
                date_node = block.find(“span”, class_=lambda c: c and (“css-” in c or “date” in c))
                review_date = date_node.text.strip() if date_node else “N/A”

                # Extract Review Content
                text_node = block.find(“p”, class_=lambda c: c and “comment__” in c)
                review_body = text_node.text.strip().replace(“\n”, ” “) if text_node else “”

                if review_body:
                    extracted_reviews.append({
                        “Author”: author_name,
                        “Rating”: star_rating,
                        “Date”: review_date,
                        “Review_Content”: review_body
                    })

            # Randomized rate limiting (2.0 to 4.5 seconds delay)
            time.sleep(random.uniform(2.0, 4.5))

        except Exception as err:
            print(f”[X] Operational error encountered on page {page_idx + 1}: {err}”)
            break

    # Structure and export data
    if extracted_reviews:
        df = pd.DataFrame(extracted_reviews)
        df.drop_duplicates(subset=[“Author”, “Review_Content”], inplace=True)
        df.to_csv(“yelp_reviews_dataset.csv”, index=False, encoding=”utf-8″)
        print(f”[✓] Successfully exported {len(df)} reviews to yelp_reviews_dataset.csv”)
    else:
        print(“[!] No reviews extracted. Check target URL, DOM selectors, or proxy health.”)

if __name__ == “__main__”:
    # Example Yelp Business Target
    TARGET_URL = “https://www.yelp.com/biz/tartine-bakery-san-francisco”
    
    # OKKProxy Account Configuration Settings
    OKKPROXY_CREDENTIALS = {
        “username”: “your_okkproxy_username”,
        “password”: “your_okkproxy_password”,
        “endpoint”: “gw.okkproxy.com”,
        “port”: “8000”
    }
    
    scrape_yelp_reviews(TARGET_URL, total_pages=3, proxy_config=OKKPROXY_CREDENTIALS)


扩展提取:OKKProxy产品集成

Okkproxy 大规模抓取 Yelp 数据所需的代理类型与价格方案
Okkproxy:成功大规模抓取 Yelp 数据所需的代理类型与价格全解析

从本地测试过渡到大规模抓取数千个商家信息时,依赖单个IP地址会导致速率限制。为了成功大规模抓取Yelp数据,将Python与高纯度代理结合使用至关重要。

OKKProxy提供一系列专门的代理产品,可满足不同的网络爬虫需求和会话条件。

OKKPROXY企业网络架构
轮换住宅代理高流量SERP和评论提取
静态ISP代理粘性会话爬取和业务审计
轮换移动代理受限端点遍历和应用程序API
静态移动代理持久性地理定位多账户操作
轮换数据中心代理高速目录发现与预爬取

1.轮换住宅代理

  • 核心应用:高容量Yelp评论抓取执行、SERP抓取(抓取Yelp搜索)和自动化数据管道。
  • 技术优势:OKKProxy可访问全球超过8000万个真实住宅IP地址,并会在每次请求或粘滞间隔时自动轮换您的出口IP地址。由于请求看起来像是来自合法的家庭互联网服务提供商(例如Comcast、AT&T或Spectrum),因此目标防火墙很少会标记流量。
  • 了解更多信息,请参阅我们全面的《轮换住宅代理实用指南》

2.静态ISP代理

  • 核心应用:持久会话、持续业务元数据提取和多步骤帐户管理工作流程。
  • 技术优势:静态ISP代理结合了数据中心托管基础设施的高速性能和住宅ASN注册的优势。这使得爬虫程序能够在长时间会话中保持单个IP地址,而无需触发验证检查。请参阅我们的《选择合适的静态代理容量》指南,了解如何计算容量

3.轮换静态移动代理(4G/5G)

  • 核心应用:绕过严格的安全屏障、反机器人挑战和移动应用端点抓取。
  • 技术优势:移动蜂窝IP地址(CGNAT)可同时被数千台真实移动设备共享。网站通常会避免屏蔽移动IP地址池,以防止真实蜂窝用户面临访问问题。请阅读我们的技术分析文章《为什么移动代理感觉更安全但更不稳定》

4.轮换数据中心代理

  • 核心应用:对未受保护的网页进行高速初始URL收集和低成本目录索引。

竞品分析:自定义Python爬虫vs.SaaS爬虫API

在制定企业级数据抓取策略时,团队通常需要在“构建基于OKKProxy的自研Python抓取程序”与“订阅托管式SaaS抓取API(如ScraperAPI、SerpApi、Bright Data、Scrapfly、Crawlbase或Outscraper)”之间做出选择。

评估指标内部Python+OKKProxySaaS数据抓取API提供商
规模化成本效益高(每千次请求0.02美元-0.05美元)中低(每千次请求1.50美元-5.00美元)
数据提取粒度完全控制(自定义CSS/DOM选择器)仅限于预先解析的API响应模式
请求吞吐量和延迟直接连接(使用curl_cffi实现低延迟)增加了API网关中间件延迟
TLS和标头自定义完全自定义(浏览器模拟)封闭式黑盒头部管理
会话持久性管理颗粒控制(粘性池与轮换池)固定API会话令牌
资源优化高度可扩展,CPU开销低需要外部供应商API积分

通过将Python的轻量级爬虫技术栈与OKKProxy的高纯度代理网络相结合,企业可以保留完整的数据所有权,降低运营成本,并避免昂贵的按请求计费的API费用。


运行故障排除清单和速率限制缓解措施

在部署生产环境的Yelp爬虫Python工作流程之前,请使用以下操作清单来保持较高的请求成功率:

  • TLS指纹验证:确认您的HTTP请求使用curl_cffi并启用浏览器模拟(impersonate=”chrome120″)。
  • 代理路由配置:确保您的脚本通过OKKProxy轮换住宅代理路由请求,以便将请求分发到不同的IP子网。
  • 动态属性选择器:使用部分字符串匹配(lambdac:cand”review__”inc),而不是依赖固定的CSS类名。
  • 请求延迟抖动:在请求之间实现随机延迟(time.sleep(random.uniform(2.0,5.0))),以保持自然的爬取行为。
  • HTTP标头对齐:包含与现代桌面浏览器匹配的实际标头(User-Agent、Accept-Language、Referer)。

企业案例研究:成功提取200万条评论,成功率高达99.4%

客户简介

一家数字智能机构需要自动提取美国50个大都市地区的200多万条Yelp用户评论,以构建本地品牌情感仪表板。

运营挑战

客户最初的内部爬虫程序遇到了严重的稳定性问题:

  • 脚本执行后15分钟内,82%的HTTP请求被阻止,并返回403Forbidden错误。
  • 共享数据中心的IP地址很快被边缘安全系统标记并封禁。
  • 无头浏览器设置(Selenium/Puppeteer)消耗过多的服务器内存,运行速度太慢,无法满足生产期限。

使用OKKPROXY之前:[成功率18%][频繁出现403错误][计算成本高]
使用OKKPROXY之后:[成功率99.4%][零IP封禁][处理速度提升3.5倍]

OKKProxy解决方案

  1. 网络基础设施集成:实施了OKKProxy轮换住宅代理,并针对美国地理位置进行定向,将每个请求路由到唯一的住宅IP地址。
  2. 爬虫管道优化:重构了爬虫脚本,使用curl_cffi和BeautifulSoup,消除了无头浏览器开销,同时保持了有效的TLS签名。
  3. 粘性会话架构:为分页业务评论配置了5分钟粘性会话池,并结合动态IP轮换进行初始搜索索引发现。

关键绩效成果

  • 请求成功率:从18%提高到99.4%
  • 提取吞吐量:管道处理速度提高了350%,在几天内而不是几周内完成了200万次审查的收集。
  • 基础设施节省:通过替换资源密集型的无头浏览器,服务器计算成本降低了45%。

常见问题解答(FAQ)

如何使用BeautifulSoup抓取Yelp评论而不被屏蔽?

由于BeautifulSoup严格来说只是一个HTML解析库,它不处理HTTP请求或TLS握手。为了防止在使用BeautifulSoup解析时被IP封禁,请使用curl_cffi执行HTTP请求(以通过JA3/JA4指纹检查),并将流量路由到OKKProxy的轮换住宅代理

我们能从Yelp抓取多少数据?

yelp.com提取的公共数据量就没有硬性限制。通过将流量分配到OKKProxy超过8000万个住宅IP地址池中,企业团队可以每天可靠地提取数百万条记录。

为什么我的Yelp数据抓取工具返回HTTP403Forbidden错误?

HTTP403状态码表示Yelp的反机器人系统将您的请求识别为自动流量。常见触发原因包括:

  1. 由基础HTTP库(如requests、urllib)发送的标准OpenSSL TLS签名。
  2. 来自单个IP地址或数据中心子网的大量请求。
  3. 不完整或不自然的HTTP请求头。

我可以使用免费的Yelp数据抓取Chrome扩展程序或GitHub脚本吗?

虽然免费的浏览器扩展程序或GitHub上的基础脚本可以满足小型、一次性任务(例如提取少于50条评论)的需求,但它们无法扩展到生产环境的工作负载。免费脚本缺乏自动代理轮换功能,会在Yelp更新HTML结构时失效,并且存在本地IP地址被封禁的风险。

如何处理Yelp菜单URL结构格式的更改?

Yelp菜单页面(/menu/…)通常使用AJAX调用动态加载内容。为了高效地提取菜单项,请检查浏览器的网络选项卡以定位底层JSON端点,或解析页面源代码中嵌入的JSON-LD元数据标签(<scripttype=”application/ld+json”>)。


结论与后续步骤

大规模抓取Yelp评论无需昂贵的托管SaaSAPI或复杂的无头浏览器基础设施。通过结合curl_cffi进行浏览器TLS模拟、BeautifulSoup进行强大的HTML解析以及OKKProxy轮换住宅代理进行可靠的IP轮换,您可以构建一个快速、可扩展且经济高效的网络抓取管道。

关于作者

Celia

Celia

内容经理

Celia 是一位充满活力的内容经理,在社交媒体、项目管理和SEO内容营销方面拥有丰富经验。她热衷于探索技术和网络安全的新趋势,尤其是数据隐私和加密领域。闲暇时,她喜欢通过瑜伽放松身心,并尝试新菜肴。

OKKProxy 团队

OKKProxy 内容团队在代理技术、住宅IP基础设施和在线隐私解决方案方面拥有多年的专业经验。凭借在支持全球用户进行社交媒体管理、电子商务运营、抢票和合规数据收集方面的深厚实践知识,团队提供可靠、实用且最新的洞察,值得您信赖。专注于性能、安全性和实际成果,OKKProxy 确保每篇文章都准确、可操作,旨在帮助用户在动态数字环境中取得成功。

OKKProxy 主要服务

OKKProxy 提供优质住宅代理服务,为高容量和轮换任务提供动态轮换IP,同时为长期可靠性和账户稳定性提供静态住宅IP。拥有遍布200多个国家的超过5000万个清洁IP池,OKKProxy 支持HTTP/SOCKS5协议、无限并发和99.9%的正常运行时间。非常适合TikTok多账户管理、跨境电商、抢票和网络数据采集,OKKProxy 结合了经济实惠、专业级工程和7×24小时专家支持,提供无缝、权威的全球访问解决方案。

OKKProxy博客以其原始形式提供所有内容,仅供参考。我们不对OKKProxy博客或其可能链接到的任何外部网站上的信息提供任何保证。在进行任何抓取活动之前,您必须寻求法律顾问并彻底检查任何网站的具体服务条款,或在需要时获得抓取许可,这一点至关重要。