使用requests爬取Zomato餐厅用户评论代码运行过慢如何解决?
问题诊断
你的实现逻辑存在3个核心问题,这也是请求耗时、拿不到完整评论的原因:
- 动态类名不可靠:你用来定位评论的
sc-1hez2tp-0 sc-eomEcv kOjze是前端框架自动生成的哈希类名,网站每次版本更新都会变更,根本无法作为稳定的定位依据,就算请求成功也大概率匹配不到正确的元素。 - 静态请求只能获取首屏内容:Zomato的评论默认只在页面初次加载时返回前5-10条,剩余评论需要用户滚动页面才会触发异步请求加载,你直接用
requests.get只能拿到首屏的少量评论,不可能获取全量数据。 - 反爬策略拦截:Zomato对普通爬虫请求有严格的校验规则,你使用的User-Agent是2017年的老旧版本,很容易被识别为爬虫,触发限速、拦截机制,就会出现请求耗时过长的问题。
调整方案
你可以按照优先级选择以下方案优化:
- 直接调用评论接口获取数据
打开浏览器控制台的「网络」面板,筛选Fetch/XHR类型的请求,手动滚动页面加载更多评论,就能找到Zomato用来返回评论数据的后端接口,接口返回的是结构化的JSON数据,不需要解析HTML,获取效率更高。请求时替换为最新的浏览器User-Agent,携带对应请求头即可快速拿到全量评论。 - 用动态渲染工具模拟用户操作
如果无法定位到评论接口,可以使用Playwright、Selenium这类模拟浏览器运行的工具,自动模拟页面滚动操作,触发所有评论加载完成后再解析页面内容。定位元素时不要使用动态哈希类名,优先选择带有review、comment等固定语义的属性、标签文本特征做匹配。 - 增加反爬规避配置
- 替换老旧的User-Agent为最新的浏览器UA
- 每次请求之间添加1-3秒的随机延时,避免请求频率过高被拦截
- 若触发验证码校验,可以搭配代理IP轮换机制降低被封风险
优化后示例参考(基于接口思路)
import requests import time import random # 替换为你自己从浏览器中复制的最新请求头,包括UA、Cookie、Referer等 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', 'Referer': 'https://www.zomato.com/mumbai/joeys-pizza-malad-west/reviews' } # 评论接口的分页参数,根据实际接口规则调整 page = 1 all_reviews = [] while True: # 替换为你找到的真实评论接口地址,调整分页参数 api_url = f"https://www.zomato.com/webroutes/reviews/loadMore?res_id=xxx&page={page}" resp = requests.get(api_url, headers=headers, timeout=10) data = resp.json() # 没有更多评论时终止循环 if not data.get("reviews"): break all_reviews.extend([rev["review_text"] for rev in data["reviews"]]) page += 1 # 随机延时规避反爬 time.sleep(random.uniform(1, 3))
内容的提问来源于stack exchange,提问作者pratik patil
相关产品推荐
相关产品推荐

