使用BeautifulSoup/Selenium爬取站点时无法通过find/find_all获取指定div元素
问题排查及解决方法
1 requests方案返回空列表原因
- 你的猜测完全正确,该站点的怪物卡片数据为JavaScript动态异步渲染,
requests库仅能获取页面初始静态HTML代码,此时卡片数据还未被JS加载插入到DOM中,因此find_all返回空列表,不存在其他额外问题。
2 Selenium方案报错原因
你代码里存在3个核心错误:
- 第一是对象调用错误:你导入的类名为
BeautifulSoup,但初始化时写的是soup(page,'html.parser'),未给类起别名的情况下直接调用soup()会抛出未定义错误,正确写法应为page_soup = BeautifulSoup(page, 'html.parser') - 第二是变量未定义:你后续代码中使用的
body变量没有提前定义,你应该调用初始化后的page_soup对象来查找元素 - 第三就是错误提示的
ResultSet调用问题:你之前大概率是用find_all给body赋值过,find_all返回的是元素列表而非单个元素对象,列表没有find/find_all方法,才会触发属性错误
修正后可运行代码
需要额外添加页面等待逻辑,避免Selenium获取页面源码时JS还未完成渲染:
from bs4 import BeautifulSoup import pandas as pd from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC url = 'https://roll20.net/compendium/dnd5e/Monsters%20List#content' # 新版Selenium无需手动指定geckodriver路径,会自动匹配 driver = webdriver.Firefox() driver.get(url) # 显式等待最多10秒,直到card元素加载完成 WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CLASS_NAME, "card")) ) # 获取渲染完成的页面源码 page = driver.page_source page_soup = BeautifulSoup(page, 'html.parser') driver.quit() # 查找所有card元素并提取内容 cards = page_soup.find_all("div", class_="card") result = [] for card in cards: card_body = card.find("div", class_="body") if not card_body: continue # 可根据实际DOM结构扩展提取名称、标题等细分字段 item = { "卡片全部文本": card_body.get_text(strip=True) } result.append(item) print(item) # 可按需转为DataFrame存储 df = pd.DataFrame(result)
内容的提问来源于stack exchange,提问作者Jared McCallister
相关产品推荐
相关产品推荐

