从动态生成HTML页面提取表格数据,除Selenium外还有其他方案吗?
替代Selenium提取动态表格数据的方案
Selenium绝非唯一能提取动态网页表格数据的工具。你遇到的问题是因为目标页面的表格数据是通过JavaScript动态渲染的,bs4只能解析初始HTML,无法获取JS加载后的内容。以下是几个适合无浏览器环境的替代方案:
方案1:使用requests + 无头浏览器(pyppeteer)
pyppeteer是基于Chrome DevTools协议的无头浏览器库,无需安装完整浏览器即可运行,适配无GUI环境。
安装依赖:
pip install pyppeteer requests
示例代码:
import asyncio from pyppeteer import launch from bs4 import BeautifulSoup async def fetch_table_data(): browser = await launch(headless=True, args=['--no-sandbox']) page = await browser.newPage() await page.goto('https://sslmate.com/labs/ocsp_watch/') # 等待表格数据加载完成(可根据页面实际加载节奏调整等待时长) await page.waitForSelector('table#ocsp-watch-table tbody tr', timeout=10000) html = await page.content() await browser.close() soup = BeautifulSoup(html, 'html.parser') table = soup.find('table', id='ocsp-watch-table') rows = table.find('tbody').find_all('tr') # 提取表格数据 data = [] for row in rows: cols = row.find_all('td') data.append([col.get_text(strip=True) for col in cols]) return data if __name__ == '__main__': table_data = asyncio.run(fetch_table_data()) print(table_data)
方案2:直接调用数据接口(最高效)
通过浏览器开发者工具的「网络」面板抓包,能发现页面是通过API请求获取表格数据的。直接请求该API可绕过JS渲染,直接拿到结构化JSON数据,效率远高于模拟浏览器加载。
示例代码(需替换为抓包得到的实际API地址):
import requests url = "目标页面加载表格数据的API接口地址" response = requests.get(url) data = response.json() # 解析JSON为表格格式 table_data = [] for item in data: # 根据API返回字段映射表格列 row = [item['domain'], item['status'], item['response_time']] table_data.append(row) print(table_data)
方案3:Selenium + 无头浏览器模式
如果仍偏好使用Selenium,可配置无头模式,无需显示浏览器界面即可运行,适配无GUI环境。
安装依赖:
pip install selenium
示例代码(以Chrome为例):
from selenium import webdriver from selenium.webdriver.chrome.options import Options from bs4 import BeautifulSoup options = Options() options.add_argument('--headless=new') options.add_argument('--no-sandbox') options.add_argument('--disable-dev-shm-usage') driver = webdriver.Chrome(options=options) driver.get('https://sslmate.com/labs/ocsp_watch/') # 等待表格加载完成 driver.implicitly_wait(10) html = driver.page_source driver.quit() soup = BeautifulSoup(html, 'html.parser') table = soup.find('table', id='ocsp-watch-table') rows = table.find('tbody').find_all('tr') data = [] for row in rows: cols = row.find_all('td') data.append([col.get_text(strip=True) for col in cols]) print(data)
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

