为何BS4无法找到HTML中已存在的指定class元素?
解决BS4无法抓取动态渲染卡片的问题
问题原因
- 动态生成的类名:你使用的
divcomponent__Div-sc-hnfdyq-0...这类带sc-前缀的类名,是前端框架(如React)通过CSS-in-JS生成的动态哈希类名,不仅容易随网站部署变更,作为选择器也过于冗余,完全不可靠。 - JS动态加载内容:页面的 testimonial 卡片是通过JavaScript动态渲染的,
requests.get()只能获取服务器返回的初始静态HTML,无法捕获JS执行后生成的DOM元素。
解决方案
方案1:直接抓取数据接口(推荐)
多数现代网站会通过API接口异步加载数据,你可以通过浏览器开发者工具找到接口:
- 打开浏览器开发者工具(F12),切换到Network标签,勾选XHR/Fetch选项。
- 刷新页面,筛选出包含
testimonial或api关键字的请求,这类请求通常就是返回 testimonial 数据的接口。 - 直接请求该接口,解析返回的JSON数据即可,无需解析HTML。
示例代码:
import requests import pandas as pd # 需自行通过浏览器确认实际API地址 api_url = "https://zerotomastery.io/api/testimonials" res = requests.get(api_url) if res.status_code == 200: data = res.json() df = pd.DataFrame(data) print(df.head())
方案2:使用Selenium渲染JS
如果找不到API接口,可通过Selenium模拟浏览器渲染页面,获取完整DOM:
from selenium import webdriver from selenium.webdriver.common.by import By from bs4 import BeautifulSoup import pandas as pd # 初始化浏览器(需提前下载对应浏览器驱动,如ChromeDriver) driver = webdriver.Chrome() driver.get("https://zerotomastery.io/testimonials/") # 等待页面加载完成(可根据实际情况调整等待时长) driver.implicitly_wait(10) # 获取渲染后的页面源码 page_source = driver.page_source driver.quit() # 用BS4解析页面 soup = BeautifulSoup(page_source, "html.parser") # 改用更稳定的选择逻辑,比如通过类名中固定的关键字定位卡片 testimonial_cards = soup.find_all("div", class_=lambda x: x and "testimonial-cardstyles__TestimonialCard" in x) blog_data = [] for card in testimonial_cards: # 提取卡片内的核心信息(可根据实际DOM结构调整) user_name = card.find("h3").text.strip() if card.find("h3") else "" testimonial_content = card.find("p").text.strip() if card.find("p") else "" blog_data.append({ "user_name": user_name, "testimonial": testimonial_content }) df = pd.DataFrame(blog_data) print(df)
注意事项
- 避免使用动态生成的类名定位元素,优先选择语义化类名、标签层级结构或属性选择器,提升抓取稳定性。
- 使用Selenium时,需确保浏览器驱动版本与本地浏览器版本匹配,并配置好环境路径。
内容的提问来源于stack exchange,提问作者Abhay Bisht
相关产品推荐
相关产品推荐

