抓取Yelp餐厅数据时类名动态变化,该如何解决?
Yelp餐厅数据抓取:动态类名定位问题解决方案
问题背景
抓取Yelp旧金山餐厅数据时,网站动态生成的CSS类名频繁变化,导致基于固定类名的定位方式失效;原代码使用的绝对Xpath维护性极差,易受页面结构变动影响,无法稳定循环提取餐厅记录。
原代码
driver = webdriver.Chrome(options=options) url = "https://www.yelp.com/search?find_desc=Restaurants&find_loc=San+Francisco%2C+CA" driver.get(url) driver.maximize_window() time.sleep(15) main = driver.find_element(By.XPATH, "/html/body/yelp-react-root/div[1]/div[5]/div/div/div[1]/div/main/div/ul") main_box = main.find_elements(By.CSS_SELECTOR, "div.container__09f24__mpR8_.hoverable__09f24__wQ_on.css-1qn0b6x") for x in main_box: try: link = x.find_element(By.CSS_SELECTOR,"div.businessName__09f24__EYSZE.css-1jq1ouh").get_attribute("href") rest_link.append(link) except: rest_link.append("NA") try: title = x.find_element(By.CSS_SELECTOR, "a.css-19v1rkv").text rest_name.append(title) except: rest_name.append("NA") print(rest_link) print(rest_name)
解决方案
核心思路是避开动态生成的CSS类名,转而使用网站为测试/无障碍设计的稳定属性(如data-testid),结合相对定位实现可靠抓取:
改进后代码
from selenium import webdriver from selenium.webdriver.common.by import By import time # 初始化浏览器(假设options已提前配置) driver = webdriver.Chrome(options=options) url = "https://www.yelp.com/search?find_desc=Restaurants&find_loc=San+Francisco%2C+CA" driver.get(url) driver.maximize_window() # 建议替换为显式等待(更高效稳定),此处先保留原sleep逻辑 time.sleep(15) # 用稳定的data-testid定位结果列表,替代绝对Xpath main = driver.find_element(By.XPATH, "//ul[@data-testid='search-results-list']") # 定位每个餐厅卡片,依赖测试ID而非动态类名 main_box = main.find_elements(By.XPATH, ".//li[@data-testid='business-card']") rest_link = [] rest_name = [] for card in main_box: try: # 定位餐厅名称的a标签,同时获取链接和名称 name_elem = card.find_element(By.XPATH, ".//a[@data-testid='business-name']") rest_link.append(name_elem.get_attribute("href")) rest_name.append(name_elem.text) except: rest_link.append("NA") rest_name.append("NA") print(rest_link) print(rest_name) driver.quit()
关键优化点
- 使用
data-testid定位:Yelp的搜索结果列表和餐厅卡片都带有固定的data-testid属性,这类属性用于自动化测试,不会随样式更新而变动,稳定性远高于动态类名。 - 相对Xpath替代绝对路径:所有元素定位均基于父元素的相对路径,避免了绝对Xpath因页面结构微调而失效的问题。
- 合并重复定位:餐厅名称和链接可通过同一个元素获取,减少冗余代码。
- 显式等待建议:可替换固定
sleep为显式等待(注释中可补充实现),根据元素加载状态动态等待,进一步提升代码健壮性。
内容的提问来源于stack exchange,提问作者Sadam Shah
相关产品推荐
相关产品推荐

