Python网页数据提取求助:NSE股票行情关键字段提取失败
解决尼日利亚证券交易所(NSE)股票交易统计数据提取问题
看起来你遇到的核心问题是静态爬取不到动态加载的表格数据,而且你的代码里find('tbody')的ID参数还没写完。我来帮你理清问题并给出可行的解决方案:
为什么你的代码失效?
尼日利亚证券交易所的这个页面,股票交易统计表格是通过JavaScript动态加载的——你用urllib2拿到的只是初始的静态HTML,里面根本没有表格的实际数据,只有用来加载数据的脚本。所以哪怕你补全了dataconta...的完整ID,也找不到目标字段。
解决方案1:用Selenium模拟浏览器加载动态内容
这是最直观的方法,模拟真实浏览器打开页面、等待数据加载完成后再提取内容:
首先你需要安装依赖:
pip install selenium
还要下载对应浏览器的驱动(比如ChromeDriver,要和你的Chrome版本匹配)。
然后用下面的代码替换你的原有代码:
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在系统PATH里,或者指定路径) driver = webdriver.Chrome() url = "http://www.nse.com.ng/market-data/trading-statistics/equities" driver.get(url) # 等待表格加载完成(最多等10秒),避免还没加载就提取数据 wait = WebDriverWait(driver, 10) wait.until(EC.presence_of_element_located((By.ID, "datatable"))) # 获取渲染后的完整页面HTML raw_html = driver.page_source parsed_html = bs(raw_html, 'html.parser') # 定位表格主体并提取数据 tbody = parsed_html.find('tbody', id='datatable') if tbody: for row in tbody.find_all('tr'): cols = row.find_all('td') # 确认列数足够,避免索引越界 if len(cols) >= 7: prev_close = cols[2].text.strip() open_price = cols[3].text.strip() high_price = cols[4].text.strip() low_price = cols[5].text.strip() close_price = cols[6].text.strip() print(f"前收盘价: {prev_close}, 开盘价: {open_price}, 最高价: {high_price}, 最低价: {low_price}, 收盘价: {close_price}") else: print("未找到表格数据,请检查页面结构是否更新") # 关闭浏览器 driver.quit()
解决方案2:直接调用API接口(更高效)
动态页面的数据通常来自后台API,你可以通过浏览器开发者工具(F12 → Network → XHR)找到数据接口,直接请求JSON数据,不需要模拟浏览器:
import requests # 替换为你抓到的真实API接口(实际需要自己抓包确认,这里是示例) api_url = "http://www.nse.com.ng/api/v1/equities/trading-statistics" response = requests.get(api_url) if response.status_code == 200: stock_data = response.json() # 根据API返回的JSON结构提取数据,以下是示例结构 for stock in stock_data.get('data', []): prev_close = stock.get('previousClose', '暂无数据') open_price = stock.get('open', '暂无数据') high_price = stock.get('high', '暂无数据') low_price = stock.get('low', '暂无数据') close_price = stock.get('close', '暂无数据') print(f"前收盘价: {prev_close}, 开盘价: {open_price}, 最高价: {high_price}, 最低价: {low_price}, 收盘价: {close_price}") else: print(f"请求API失败,状态码: {response.status_code}")
这种方法比Selenium更快,也更稳定,唯一需要注意的是API接口可能会更新,需要定期检查。
内容的提问来源于stack exchange,提问作者Darlington Emeagi




