如何用BeautifulSoup检测HTML类并提取Yelp.fr星级评分?
解决Yelp.fr爬取星级与类存在检测的问题
嘿,我来帮你搞定这两个爬取Yelp商家信息的关键问题!下面分两部分给你拆解方案,结合你的代码逐一修正:
一、检测HTML中目标类是否存在
你当前代码里用soup.find_all()返回的是一个列表,直接调用.get_attribute()是错误的——这是Selenium WebElement的方法,BeautifulSoup的元素不支持。正确的检测方式有两种:
方式1:使用find()方法(推荐)
find()会返回第一个匹配的元素,找不到则返回None,直接用if判断即可:
# 定位商家评分的父div biz_rating_div = soup.find("div", class_="biz-rating biz-rating-large clearfix") if biz_rating_div: print("存在目标类") else: print("不存在目标类")
方式2:使用find_all()判断长度
如果需要找所有匹配的元素,通过判断列表长度是否大于0来检测:
etoiles = soup.find_all("div", class_="biz-rating biz-rating-large clearfix") if len(etoiles) > 0: print("存在目标类") else: print("不存在目标类")
二、提取商家星级评分
Yelp的星级有两种可靠的提取方式,优先用第一种,第二种作为备选:
方式1:从title属性提取(最直接)
星级对应的<i>标签里,title属性会直接显示类似"4.0 étoiles"或"3.5 étoiles"的文本,直接提取数字部分即可:
if biz_rating_div: # 找到内部的i-stars标签 star_tag = biz_rating_div.find("i", class_="i-stars") if star_tag: # 获取title属性文本 star_title = star_tag.get("title") # 提取数字部分(比如从"4.0 étoiles"中拿到4.0) rating = float(star_title.split()[0]) print(f"星级评分:{rating}")
方式2:从class属性解析(备用)
如果title属性失效,可以从class字符串里解析规律——比如i-stars--regular-4对应4星,i-stars--regular-3-half对应3.5星:
if biz_rating_div: star_tag = biz_rating_div.find("i", class_="i-stars") if star_tag: # 获取class列表 class_list = star_tag.get("class") # 找到包含星级信息的class项 star_class = [c for c in class_list if "i-stars--regular-" in c][0] # 拆分出星级部分 star_part = star_class.replace("i-stars--regular-", "") # 转换为数字:"4"→4.0,"3-half"→3.5 if "half" in star_part: rating = float(star_part.split("-")[0]) + 0.5 else: rating = float(star_part) print(f"星级评分:{rating}")
整合后的完整代码示例
结合你的初始代码,修正后如下(注意适配Python 3的语法,如果用Python 2可以去掉print的括号):
from selenium import webdriver from bs4 import BeautifulSoup CITIES = "la rochelle(17000)" places = "Bars" driver = webdriver.Chrome() driver.get(f"https://www.yelp.fr/search?find_desc={places}&find_loc={CITIES}") page = driver.page_source soup = BeautifulSoup(page, "lxml") # 检测目标类是否存在 biz_rating_div = soup.find("div", class_="biz-rating biz-rating-large clearfix") if biz_rating_div: print("目标类存在") # 提取星级(优先用title方式) star_tag = biz_rating_div.find("i", class_="i-stars") if star_tag: # 方式1:从title提取 star_title = star_tag.get("title") if star_title: rating = float(star_title.split()[0]) print(f"星级评分:{rating}") else: # 方式2:从class解析 class_list = star_tag.get("class") star_class = [c for c in class_list if "i-stars--regular-" in c][0] star_part = star_class.replace("i-stars--regular-", "") if "half" in star_part: rating = float(star_part.split("-")[0]) + 0.5 else: rating = float(star_part) print(f"星级评分:{rating}") else: print("目标类不存在") driver.quit()
内容的提问来源于stack exchange,提问作者Mohammed Rasfa
相关产品推荐
相关产品推荐

