You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python结合JavaScript抓取网页表格及解决NaN无数据问题

嘿,我来帮你搞定这两个问题——先用Python结合JavaScript抓取网页表格,再解决你遇到的NaN/数字不显示的坑。

一、Python结合JavaScript抓取网页表格的常见方法

很多网页的表格数据是通过JavaScript动态渲染的,直接用requests抓静态源码根本拿不到真实数据,这时候就需要让JS先执行完,再抓取渲染后的内容。常见的方案有这三种:

1. 用Selenium模拟浏览器(最直观)

Selenium可以完全模拟真实浏览器的行为,自动执行页面上的JS,等表格加载完成后再抓取。举个简单的例子:

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
from bs4 import BeautifulSoup

# 初始化浏览器(这里用Chrome,需要对应版本的chromedriver)
driver = webdriver.Chrome()
try:
    driver.get("目标网页URL")
    # 等待表格加载完成(最多等10秒)
    WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.TAG_NAME, "table"))
    )
    # 获取渲染后的页面源码
    page_source = driver.page_source
    soup = BeautifulSoup(page_source, "html.parser")
    
    # 解析表格
    table = soup.find("table")
    rows = table.find_all("tr")
    for row in rows:
        cols = row.find_all(["td", "th"])
        print([col.get_text(strip=True) for col in cols])
finally:
    driver.quit()

2. 用Pyppeteer(无头浏览器,更轻量)

Pyppeteer是Chrome DevTools协议的Python实现,不需要额外装浏览器驱动,用无头模式运行更隐蔽:

import asyncio
from pyppeteer import launch
from bs4 import BeautifulSoup

async def scrape_table():
    browser = await launch(headless=True)
    page = await browser.newPage()
    await page.goto("目标网页URL", waitUntil="networkidle2")  # 等待网络空闲,确保JS加载完
    page_source = await page.content()
    await browser.close()
    
    soup = BeautifulSoup(page_source, "html.parser")
    table = soup.find("table")
    # 后续解析逻辑和上面一样
    rows = table.find_all("tr")
    for row in rows:
        cols = row.find_all(["td", "th"])
        print([col.get_text(strip=True) for col in cols])

asyncio.get_event_loop().run_until_complete(scrape_table())

3. 直接提取JS变量(最高效,适合静态页面内嵌JS数据)

如果表格数据是存在页面的JS变量里(比如var tableData = [...];),可以用requests抓源码,再用execjs提取变量:

import requests
import execjs

url = "目标网页URL"
response = requests.get(url)
html = response.text

# 提取JS变量(这里假设变量名为tableData)
js_code = """
function getTableData() {
    // 这里复制页面里定义tableData的代码,或者直接返回变量
    return tableData;
}
"""
ctx = execjs.compile(js_code)
table_data = ctx.call("getTableData")
print(table_data)
二、抓取表格出现NaN/数字未显示的原因及解决办法

你遇到的NaN问题,大概率是数据没被正确抓取到,常见原因和对应解法如下:

1. 数据是动态加载的(最常见)

很多网站的表格不是一开始就渲染在HTML里的,而是页面加载后通过AJAX请求后端接口,再用JS把数据插入DOM。这时候直接用requests抓静态源码,拿到的只是空的表格框架,解析后自然是NaN。
解法:用上面说的Selenium/Pyppeteer等无头浏览器,等待数据加载完成后再抓取;或者打开浏览器F12的Network标签,找到返回表格数据的XHR接口,直接用requests请求这个接口(速度更快)。

2. 数字是JS动态计算生成的

有些网站的表格数字是通过JS计算后插入的(比如从其他数据推导、格式化),静态源码里只有空标签或者占位符,直接抓取就会拿到空值,转成NaN。
解法:要么用无头浏览器让JS执行完再抓渲染后的内容;要么找到计算数字的JS逻辑,自己用Python实现(如果逻辑不复杂的话)。

3. 选择器定位错误

可能你写的CSS/XPath选择器没命中正确的表格元素,或者选中了错误的子节点,导致拿到的是空内容。
解法:打开浏览器F12,用元素选择器定位表格,检查真实的DOM结构,调整你的选择器。比如有时候表格嵌套在div里,或者有多个table标签,要选对目标表格。

4. 网站有反爬机制

有些网站会检测请求是否来自真实浏览器,如果是requests的默认请求头,可能会返回空数据或者假数据,导致你拿到NaN。
解法:模拟浏览器的请求头(比如加User-Agent、Referer),带上必要的Cookie;或者用无头浏览器模拟正常用户行为(比如加随机等待时间、滚动页面)。

举个实际解决NaN的例子

假设你用requests抓表格拿到NaN,换成Selenium等待数据加载:

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.Chrome()
try:
    driver.get("目标网页URL")
    # 等待表格里的第一个数字单元格加载完成
    WebDriverWait(driver, 15).until(
        EC.text_to_be_present_in_element((By.CSS_SELECTOR, "table td:nth-child(2)"), "")
    )
    # 直接用pandas读取表格,更方便
    df = pd.read_html(driver.page_source)[0]
    print(df)  # 这时候数字应该能正常显示了
finally:
    driver.quit()

内容的提问来源于stack exchange,提问作者saga

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:55:31