Python爬取网页生成CSV问题:仅获取列名无数据
解决Moneycontrol套利表格爬取无数据问题
问题原因
目标页面的表格数据是通过JavaScript异步加载的,pandas.read_html()只能解析初始HTML中的静态内容,无法获取动态渲染的数据,因此仅返回列名空表。
解决方案一:使用Selenium模拟浏览器加载动态内容
该方法通过模拟浏览器完整渲染页面,获取动态加载的表格数据。
步骤
- 安装依赖:
pip install selenium pandas
- 下载对应浏览器的驱动(如ChromeDriver),并将其路径配置到环境变量,或在代码中指定路径。
完整代码
from selenium import webdriver from selenium.webdriver.chrome.options import Options import pandas as pd import time # 配置Chrome无头模式(可选,不弹出浏览器窗口) chrome_options = Options() chrome_options.add_argument("--headless=new") chrome_options.add_argument("--disable-gpu") # 初始化浏览器驱动 driver = webdriver.Chrome(options=chrome_options) target_url = "https://www.moneycontrol.com/stocks/fno/marketstats/arbitrage/futures-spot-near-2.html" driver.get(target_url) # 等待页面加载完成(根据网络情况调整等待时长) time.sleep(5) # 定位目标表格并提取HTML table = driver.find_element("xpath", '//table[@class="tblList"]') table_html = table.get_attribute("outerHTML") # 解析表格数据 df = pd.read_html(table_html)[0] # 调整列名匹配需求 df.columns = ["Company", "Future", "Spot", "Basis", "Basis%", "Previous", "Change", "Lot Size"] # 保存为CSV文件 df.to_csv("arbitrage_data.csv", index=False, encoding="utf-8") # 关闭浏览器 driver.quit() print("CSV文件生成成功!")
解决方案二:直接调用API接口(高效推荐)
通过浏览器开发者工具抓包,找到加载表格数据的后台API接口,直接请求获取数据,无需模拟浏览器。
步骤
- 打开目标页面,按F12进入开发者工具,切换到「Network」标签,刷新页面后筛选「XHR」类型请求,找到返回表格数据的API接口。
- 模拟浏览器请求头调用API,解析返回的JSON数据。
完整代码
import requests import pandas as pd # 抓包获取的API接口URL(若网站更新需重新验证) api_url = "https://api.moneycontrol.com/mcapi/v1/arbitrage/futures-spot-near?offset=0&limit=100" # 模拟浏览器请求头,避免被拦截 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(api_url, headers=headers) data = response.json() # 转换为DataFrame并映射列名 df = pd.DataFrame(data["data"]) column_mapping = { "companyName": "Company", "futurePrice": "Future", "spotPrice": "Spot", "basis": "Basis", "basisPerc": "Basis%", "previousClose": "Previous", "change": "Change", "lotSize": "Lot Size" } df = df.rename(columns=column_mapping)[list(column_mapping.values())] # 保存为CSV文件 df.to_csv("arbitrage_data.csv", index=False, encoding="utf-8") print("CSV文件生成成功!")
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

