使用BeautifulSoup爬取CoinGecko数据时相同类名无法区分字段问题
问题解决方案
首先你遇到的核心问题是未限定仅提取表格tbody内的行,且没有利用表格列顺序固定的特性取值,具体修正逻辑如下:
- 该网站历史数据表格的每一行
<tr>内字段顺序是固定的,不需要通过类名区分,直接按索引取值即可,对应关系如下:- 第0个元素
<th>→ 日期date - 第2个
<td>→ 交易量volume - 第3个
<td>→ 开盘价open - 第4个
<td>→ 收盘价close
- 第0个元素
- 你之前的代码错误点:
- 调用
soup.find_all('tr')会把表头行也纳入遍历范围,表头行不存在<td>元素,访问all_td[4]会触发索引越界 - 提取的文本未做去空白处理,会残留换行、多余空格
- 调用
修正后的可运行代码如下:
from bs4 import BeautifulSoup import requests import pandas as pd website = 'https://www.coingecko.com/en/coins/bitcoin/historical_data/usd?start_date=2021-01-01&end_date=2021-09-30#panel' # 加请求头避免被网站拦截 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36' } response = requests.get(website, headers=headers) soup = BeautifulSoup(response.content, 'html.parser') # 仅获取tbody内的行,排除表头 all_tr = soup.find('table', {'class':'table-striped'}).find('tbody').find_all('tr') close = [] volume = [] open_price = [] # 避免和内置函数open重名 date = [] for row in all_tr: # 提取日期 date_val = row.find('th').text.strip() date.append(date_val) # 提取所有td all_td = row.find_all('td') # 按索引取值+去空白+去除$符号方便后续处理(不需要可以去掉replace部分) volume_val = all_td[1].text.strip().replace('$', '').replace(',', '') volume.append(volume_val) open_val = all_td[2].text.strip().replace('$', '').replace(',', '') open_price.append(open_val) close_val = all_td[3].text.strip().replace('$', '').replace(',', '') close.append(close_val) # 可以转成DataFrame查看效果 df = pd.DataFrame({ 'date': date, 'volume': volume, 'open': open_price, 'close': close }) print(df.head())
注:代码中加了User-Agent请求头是为了避免网站直接拦截爬虫请求,导致返回空内容的问题;变量名避免用open是因为Python内置有同名函数,避免冲突。
内容的提问来源于stack exchange,提问作者Jeffrey Sachs
相关产品推荐
相关产品推荐

