使用Selenium爬取Coincodex历史数据并转换为Pandas DataFrame求助
解决后完整可运行代码
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 import pandas as pd import time # 数值&单位统一处理函数 def convert_val(val_str, keep_dollar_sign=False): # 先替换$加空格的格式,对应第二个问题 processed = val_str.replace('$ ', '$' if keep_dollar_sign else '').replace(',', '').strip() if keep_dollar_sign: # 仅需要替换格式不转数值时直接返回 return processed # 去掉$符号处理单位转换,对应第三个问题 num_str = processed.replace('$', '') if num_str.endswith('B'): return float(num_str[:-1]) * 10**9 elif num_str.endswith('M'): return float(num_str[:-1]) * 10**6 elif num_str.endswith('K'): return float(num_str[:-1]) * 10**3 else: return float(num_str) URL = "https://coincodex.com/crypto/bitcoin/historical-data/" # 若使用Selenium v4.6以下版本,替换为下方写法即可: # driver = webdriver.Chrome(executable_path = "/usr/local/bin/chromedriver") driver = webdriver.Chrome() driver.get(URL) time.sleep(3) extracted_data = [] # 按需求修改目标起始日期,格式和页面显示的日期格式保持一致 target_start_date = 'Jan 01 2024' while True: # 等待当前页表格加载完成 WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CSS_SELECTOR, 'table.styled-table.full-size-table tr.ng-star-inserted')) ) HTMLPage = BeautifulSoup(driver.page_source, 'html.parser') Table = HTMLPage.find('table', class_='styled-table full-size-table') Rows = Table.find_all('tr', class_='ng-star-inserted') for row in Rows: try: Values = row.find_all('td') if len(Values) != 7: continue date_str = Values[0].text.replace(',', '').strip() # 爬到年初目标日期直接结束整个爬取流程 if date_str == target_start_date: driver.quit() df = pd.DataFrame(extracted_data) print(df) exit() RowDict = { "Date": date_str, "Open": convert_val(Values[1].text), "High": convert_val(Values[2].text), "Low": convert_val(Values[3].text), "Close": convert_val(Values[4].text), "Volume": convert_val(Values[5].text), "Market Cap": convert_val(Values[6].text) } # 如果需要保留$符号,把上面的转换逻辑改成convert_val(Values[1].text, keep_dollar_sign=True)即可 extracted_data.append(RowDict) except Exception as e: print(f"行处理错误: {e}") # 模拟点击下一页,对应第一个分页问题 try: next_btn = WebDriverWait(driver, 5).until( EC.element_to_be_clickable((By.CSS_SELECTOR, 'a.pagination-next')) ) next_btn.click() time.sleep(2) except: # 没有下一页时自动停止 break driver.quit() df = pd.DataFrame(extracted_data) print(df)
对应问题的解决逻辑
- 分页爬取问题:网站表格默认按倒序排列,最新的9月数据在第一页,通过循环模拟点击下一页按钮,每次点击后等待表格刷新再解析内容,直到爬取到当年1月1日的目标日期就自动停止,刚好覆盖年初到9月末的所有数据。
$格式替换问题:在convert_val函数中统一处理字符串,默认直接去掉$符号转成数值方便后续分析,如果需要保留$格式只删除空格,传参keep_dollar_sign=True即可。- 单位转换问题:函数自动识别字符串末尾的B/M/K单位,分别对应乘以109、106、10^3转成完整数值,同时兼容无单位的普通数值。
内容的提问来源于stack exchange,提问作者FCH1922
相关产品推荐
相关产品推荐

