使用Python爬取JavaScript动态网站时BeautifulSoup无法获取元素如何解决
问题原因
你当前的判断是准确的,该站点的文章内容属于JavaScript动态渲染内容:直接用requests发起GET请求只能拿到服务端返回的未执行JS的初始HTML源码,你需要的article-document容器、标题、段落等内容都是浏览器加载页面后执行JS动态生成的,不存在于初始源码中,所以BeautifulSoup无法定位到对应元素。
另外你提供的初始代码存在遗漏导入requests库的问题,直接运行会抛出导入错误。
可行解决方案
方案1:模拟浏览器动态渲染(通用适配,无需分析接口)
这是最稳妥的方案,直接通过工具模拟浏览器加载页面、执行JS的完整流程,渲染完成后再提取内容,不需要额外分析站点的接口逻辑。
我们以Selenium为例,实现步骤如下:
- 安装依赖包:
pip install selenium webdriver-manager beautifulsoup4 lxml - 编写代码启动无头浏览器(后台运行无界面)访问目标页面,等待内容渲染完成后提取页面源码,再用BeautifulSoup解析即可。
完整可运行示例代码
from bs4 import BeautifulSoup from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from webdriver_manager.chrome import ChromeDriverManager def get_rendered_page(url): # 配置Chrome无头模式 chrome_options = webdriver.ChromeOptions() chrome_options.add_argument("--headless=new") chrome_options.add_argument("--disable-blink-features=AutomationControlled") chrome_options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36") driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=chrome_options) driver.get(url) # 等待目标容器加载完成,最多等待10秒 WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CLASS_NAME, "article-document")) ) page_source = driver.page_source driver.quit() return BeautifulSoup(page_source, "lxml") url = "https://portaljuridic.gencat.cat/eli/es-ct/l/2014/12/29/19" soup = get_rendered_page(url) # 提取文章内容 article = soup.find("div", class_="article-document") # 提取所有三级标题 titles = [h.get_text(strip=True) for h in article.find_all("h3")] # 提取所有段落 paragraphs = [p.get_text(strip=True) for p in article.find_all("p")] print("文章标题列表:", titles) print("段落内容列表:", paragraphs)
方案2:直接请求数据接口(高性能,适合批量爬取)
如果需要批量爬取大量页面,启动浏览器的方案性能较低,你可以通过浏览器抓包获取内容接口:
- 打开浏览器F12开发者工具,切换到「网络」标签,刷新页面后过滤「XHR/提取」类请求
- 逐个查看请求的响应内容,找到返回文章结构化数据的接口,直接用
requests请求该接口即可拿到JSON格式的内容,无需解析HTML,速度比渲染方案高10倍以上。
内容的提问来源于stack exchange,提问作者Merinoide
相关产品推荐
相关产品推荐

