如何用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
相关产品推荐
相关产品推荐

