如何用Python获取Angular网站动态内容?解决Selenium爬取失效问题
解决Angular网站动态内容爬取问题
一、修正你的Selenium代码
你的现有代码核心问题是等待条件错误,加上headless模式配置缺失,调整后即可获取渲染后的完整内容:
1. 修正等待逻辑
ng-version是<app-root>的属性而非子元素,正确的等待应该聚焦于<app-root>内部是否生成了实际内容,或者等待页面中某个具体的渲染后元素出现:
2. 完善headless模式配置
Chrome旧版headless模式可能禁用部分渲染特性,改用新版配置并设置窗口大小,避免布局异常。
修正后的代码:
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 webdriver_manager.chrome import ChromeDriverManager service = Service(ChromeDriverManager().install()) options = webdriver.ChromeOptions() options.add_argument("--headless=new") # 新版headless模式,兼容性更强 options.add_argument("--disable-gpu") options.add_argument("--window-size=1920,1080") # 固定窗口尺寸,避免渲染错位 driver = webdriver.Chrome(service=service, options=options) try: driver.get("https://www.fedlex.admin.ch/de/cc/international-law/0.1") # 等待app-root内部生成有效内容(跳过初始空注释) WebDriverWait(driver, 15).until( lambda d: len(d.find_element(By.TAG_NAME, "app-root").get_attribute("innerHTML").strip()) > 20 ) # 也可以等待页面中具体元素,比如主标题 # WebDriverWait(driver, 15).until(EC.presence_of_element_located((By.CSS_SELECTOR, "h1"))) page_source = driver.page_source finally: driver.quit() print(page_source)
二、针对Angular应用的Selenium高级技巧
Angular有专属的渲染生命周期,可通过执行JavaScript精准判断加载状态:
1. 等待Angular应用稳定
执行Angular内置的调试方法,确认应用完成渲染:
# 替换原有等待逻辑,用JS判断Angular稳定性 WebDriverWait(driver, 15).until( lambda d: d.execute_script(""" return window.getAllAngularTestabilities().every(function(testability) { return testability.isStable(); }); """) )
注意:该方法依赖Angular调试模块,部分生产环境可能禁用此功能。
2. 直接提取Angular数据模型
若能定位到目标组件,可跳过HTML解析直接获取原始数据:
# 执行JS获取组件内的数据 data = driver.execute_script(""" const rootElement = document.querySelector('app-root'); const componentScope = angular.element(rootElement).scope(); return componentScope.targetDataProperty; // 替换为实际数据属性名 """) print(data)
此方法需要了解目标网站的Angular组件结构,适合有Angular基础的场景。
三、其他高效替代方案
1. Playwright(推荐)
Playwright对SPA渲染的支持更智能,内置等待机制无需手动配置:
from playwright.sync_api import sync_playwright with sync_playwright() as p: browser = p.chromium.launch(headless=True) page = browser.new_page() page.goto("https://www.fedlex.admin.ch/de/cc/international-law/0.1", wait_until="networkidle") page_source = page.content() browser.close() print(page_source)
2. 直接调用后台API
多数Angular网站通过API获取数据,可通过浏览器开发者工具(Network标签)定位数据接口,直接请求原始数据,效率远高于页面渲染:
import requests headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36" } # 替换为实际API地址 response = requests.get("https://www.fedlex.admin.ch/api/xxx", headers=headers) data = response.json() print(data)
3. Puppeteer(Node.js工具)
Chrome官方无头浏览器工具,对SPA渲染支持完善:
const puppeteer = require('puppeteer'); (async () => { const browser = await puppeteer.launch({ headless: 'new' }); const page = await browser.newPage(); await page.goto('https://www.fedlex.admin.ch/de/cc/international-law/0.1', { waitUntil: 'networkidle2' }); const pageSource = await page.content(); console.log(pageSource); await browser.close(); })();
内容的提问来源于stack exchange,提问作者Joshua Eseigbe
相关产品推荐
相关产品推荐

