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

如何用BeautifulSoup爬取CoinMarketCap历史快照表格全部数据?

解决CoinMarketCap历史快照20行后数据爬取异常问题

问题根源:CoinMarketCap历史页面的表格数据采用懒加载机制,前20行是页面初始渲染时嵌入HTML的静态内容,20行之后的数据需要通过JavaScript动态加载。直接用requests获取的静态HTML仅包含前20行,因此BeautifulSoup无法匹配到后续的<tr>元素。

以下是两种可行的解决方法:

方法1:调用官方API(推荐,稳定性更高)

CoinMarketCap提供了历史数据API,比网页爬取更可靠。需先在官网申请免费API密钥(有调用次数限制),代码示例:

import requests
import pandas as pd

API_KEY = "你的API密钥"
target_date = "2021-12-19"  # 格式为YYYY-MM-DD

api_url = "https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/historical"
params = {
    "date": target_date,
    "start": "1",
    "limit": "5000",  # 可调整获取数据的数量上限
    "convert": "USD"
}
headers = {
    "Accepts": "application/json",
    "X-CMC_PRO_API_KEY": API_KEY
}

response = requests.get(api_url, headers=headers, params=params)
data = response.json()

# 转换为DataFrame方便处理
df = pd.json_normalize(data["data"])
print(df.head())

方法2:用Selenium模拟浏览器加载动态内容

通过模拟浏览器行为,等待页面完全加载所有内容后再提取HTML,从而获取完整表格数据。需提前安装对应浏览器的驱动(如Chrome的chromedriver),代码示例:

import pandas as pd
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

target_date = '20211219/'
url = f'https://coinmarketcap.com/historical/{target_date}'

# 初始化Chrome浏览器(需确保chromedriver路径正确)
driver = webdriver.Chrome()
driver.get(url)

# 滚动到页面底部触发懒加载,等待剩余内容加载完成
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
WebDriverWait(driver, 15).until(
    EC.presence_of_element_located((By.CSS_SELECTOR, 'tr.cmc-table-row:last-child'))
)

# 获取完整页面的HTML
page_html = driver.page_source
soup = BeautifulSoup(page_html, 'lxml')
all_rows = soup.find_all('tr', attrs={'class': 'cmc-table-row'})

driver.quit()

# 解析提取所需字段
result_data = []
for row in all_rows:
    cells = row.find_all('td')
    result_data.append({
        '排名': cells[0].text.strip(),
        '币种名称': cells[2].text.strip(),
        '符号': cells[3].text.strip(),
        '价格': cells[4].text.strip(),
        '市值': cells[6].text.strip()
    })

df = pd.DataFrame(result_data)
print(df.tail())  # 验证是否获取到20行之后的数据

注意事项

  • API免费版有调用限制(每分钟10次、每日1000次),适合少量数据需求;
  • Selenium需匹配浏览器版本的驱动,且避免频繁请求导致IP被封禁;
  • 可根据实际需求调整字段提取逻辑和等待时间。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 01:06:26