Python爬取CoinMarketCap数据异常:pd.read_html结果不符预期
嘿,我来帮你搞定这个问题!
问题出在哪?
你对pd.read_html()的返回值理解有点偏差——这个函数从来都是返回一个DataFrame的列表,不是单个DataFrame。之前你觉得它直接返回DataFrame,是因为当时页面里只有一个能被识别的表格,所以取df[0]就拿到了目标数据。现在要么是页面结构变了,要么是read_html识别到了多个表格,导致你后续转成DataFrame的操作完全错了方向。
当你执行pd.DataFrame(df)时,相当于把整个DataFrame列表当成了构造新DataFrame的数据源,这会把每个子DataFrame当成一行数据,结果自然就只有列名,完全不是你想要的加密货币数据。
怎么解决?
第一步:先看看抓到了多少个表格
先跑这段代码确认一下read_html识别到的表格数量:
import pandas as pd url = 'https://coinmarketcap.com/all/views/all/' df_list = pd.read_html(url, header=None) print(f"一共识别到 {len(df_list)} 个表格")
第二步:找到真正的目标表格
逐个查看列表里的每个DataFrame,找到包含币价、市值这些数据的那个:
for idx, table in enumerate(df_list): print(f"\n--- 第 {idx} 个表格的前5行 ---") print(table.head())
一般来说,加密货币的全量数据会在第一个表格里,所以直接拿它就行:
df_crypto = df_list[0] # 验证一下结果 print(f"数据形状:{df_crypto.shape}") print(df_crypto.head())
如果还是拿不到数据?试试动态抓取
要是上面的方法拿到的是空表格或者数据不全,那说明CoinMarketCap现在用JavaScript动态渲染数据了,pd.read_html只能抓静态HTML里的内容,这时候得用selenium模拟浏览器加载页面:
- 先装selenium:
pip install selenium
下载对应浏览器的驱动(比如ChromeDriver),要和你的浏览器版本匹配哦。
用这段代码抓动态数据:
from selenium import webdriver from selenium.webdriver.chrome.options import Options import pandas as pd # 配置无头浏览器(不用弹出窗口) chrome_options = Options() chrome_options.add_argument("--headless=new") driver = webdriver.Chrome(options=chrome_options) # 加载页面,等它渲染完 driver.get('https://coinmarketcap.com/all/views/all/') driver.implicitly_wait(10) # 给页面10秒加载时间,不够可以调长 # 拿页面HTML再解析 html = driver.page_source df_list = pd.read_html(html, header=None) driver.quit() # 取目标表格 df_crypto = df_list[0] print(df_crypto.shape) print(df_crypto.head())
划重点
- 记住
pd.read_html()返回的是DataFrame列表,要通过索引取你要的表格,别把整个列表直接转成DataFrame! - 静态抓取不行就换动态抓取,对付JS渲染的页面selenium很好用。
内容的提问来源于stack exchange,提问作者Alessandro Carvalho
相关产品推荐
相关产品推荐

