Web Scraping实践:Python爬取Yelp评分混入冗余数据如何修正
问题原因
你使用的span类是Yelp全站通用的样式类,会命中页面所有带该样式的评分元素,包括「你可能也感兴趣」推荐区域的商户评分,因此会抓取到冗余数据。
修复后的代码
import urllib.request from bs4 import BeautifulSoup rating = [] # 58条评论最多6页即可爬取完成,减少无效请求 for i in range(0, 6): url = "https://www.yelp.com/biz/snow-show-flushing?osq=ice%20cream%20shop&start="+str(10*i) ourUrl = urllib.request.urlopen(url) soup = BeautifulSoup(ourUrl,'html.parser') # 定位页面唯一的用户评论区容器,直接排除所有非评论区域内容 review_section = soup.find(id="reviews") # 没有更多评论区时直接终止循环,避免报错 if not review_section: break # 仅在评论区内部查找评分元素 for r in review_section.find_all('span',{'class':"display--inline__373c0__1gaV4 border-color--default__373c0__1yxBb"}): per_rating = r.div.get('aria-label') # 额外校验评分格式,进一步过滤异常值 if per_rating and "star rating" in per_rating: rating.append(per_rating)
核心调整点
- 新增专属区域定位:通过页面唯一的
reviewsid锁定评论区域,所有推荐区、广告区的内容直接被排除,从根源解决冗余数据问题 - 优化循环逻辑:根据总评论数调整循环上限,新增无评论区自动终止的判断,减少无效请求和空值报错
- 新增内容校验:只保留符合评论评分格式的内容,进一步过滤可能的异常数据
可选更高稳定性方案
如果后续Yelp更新样式类导致原有选择器失效,可以改用单条评论前缀匹配的方式,抗更新能力更强:
# 替换原有评分查找逻辑即可 for review in review_section.find_all("li", class_=lambda x: x and x.startswith("review__")): rating_ele = review.find("div", attrs={"aria-label": lambda x: x and "star rating" in x}) if rating_ele: rating.append(rating_ele.get("aria-label"))
内容的提问来源于stack exchange,提问作者Hongteng Wang
相关产品推荐
相关产品推荐

