如何用Python+Selenium提取动态表格数据并适配Pandas处理
如何提取Angular动态表格数据并导入Pandas
我太懂你遇到的这个坑了——Angular生成的动态表格自带_ngcontent-xxx这类样式隔离前缀,静态爬取工具根本抓不到有效元素,之前你写的代码里也有几个关键问题:比如硬编码的绝对XPath容易失效、循环里的变量没正确插入选择器、全局查找元素时容易定位混乱。
下面给你两种最简便规范的解决方案,优先推荐第一种,省心又高效:
方法一:Selenium+Pandas直接读取动态表格
这是最偷懒也最靠谱的方式,Pandas的read_html能自动解析页面里的表格结构,只要确保动态内容加载完成就行:
from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By import pandas as pd # 初始化浏览器(换成Chrome也可以,对应webdriver.Chrome()) driver = webdriver.Firefox() wait = WebDriverWait(driver, 15) # 显式等待,最长15秒确保内容加载 try: # 加载目标网站 driver.get("https://coinmunity.co/") # 等待表格核心区域加载——直到tbody出现,确保动态数据渲染完毕 wait.until(EC.presence_of_element_located((By.TAG_NAME, "tbody"))) # 获取页面源码,交给Pandas自动解析表格 page_source = driver.page_source # read_html返回所有表格的DataFrame列表,这里取第一个就是目标表格 df = pd.read_html(page_source)[0] # 预览结果,按需处理或保存 print(df.head()) df.to_csv("coinmunity_data.csv", index=False) finally: # 无论成功失败,记得关闭浏览器 driver.quit()
为什么这个方法好用?
- Pandas自动帮你处理表头、行列映射,不用手动写循环提取每个字段
- 显式等待比
implicitly_wait更可靠,确保表格真的加载完成再操作
方法二:手动循环提取(需要精细控制时用)
如果需要对元素做额外操作(比如点击链接、提取属性),可以用这种方式,核心是用相对定位避免全局查找出错:
from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By import pandas as pd driver = webdriver.Firefox() wait = WebDriverWait(driver, 15) results = [] try: driver.get("https://coinmunity.co/") # 等待所有数据行加载完成 wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, "tbody tr"))) # 获取所有数据行(tbody里的tr都是内容行,排除表头) rows = driver.find_elements(By.CSS_SELECTOR, "tbody tr") for row in rows: # 重点:在当前行内做相对定位,避免拿到其他行的元素 symbol = row.find_element(By.CLASS_NAME, "coin-link").text # 提取当前行内所有stats类元素,按顺序取对应字段 stats = row.find_elements(By.CLASS_NAME, "stats") followers = stats[0].text change_followers = stats[1].text subscribers = stats[2].text change_subscribers = stats[3].text price = stats[4].text change_price = stats[5].text results.append({ "Symbol": symbol, "Total Followers": followers, "Followers Change": change_followers, "Subscribers": subscribers, "Subscribers Change": change_subscribers, "Price": price, "Price Change": change_price }) # 转成DataFrame进行后续处理 df = pd.DataFrame(results) print(df.head()) finally: driver.quit()
修复了你之前代码的几个核心问题:
- 用
row.find_element做相对定位,避免全局查找时元素混乱 - 用显式等待确保所有数据行加载完成,替代不可靠的固定sleep
- 直接遍历已找到的行元素,不用手动计数拼接选择器
关键注意事项
- 绝对不要用
/html/body/app-root/...这类绝对XPath,页面结构稍有变动就会失效,优先用相对选择器 - 针对Angular这类SPA,必须等待动态内容渲染完成,显式等待是最佳实践
- 如果遇到反爬,可以添加
time.sleep(2)(但优先用显式等待),或者启用无头浏览器模式(比如Firefox添加options.add_argument("--headless"))
内容的提问来源于stack exchange,提问作者skeitel
相关产品推荐
相关产品推荐

