Python股票爬取遇3位数字值失败:KeyError问题求助
嘿,我来帮你搞定这个爬虫问题!
首先得澄清一个误解:你遇到的KeyError: 0和3位数字的股票数值完全没关系,本质是你的代码在尝试访问一个空DataFrame的索引0——简单说就是,你要找的日期在网页表格里根本没有对应数据,导致筛选后的结果为空,这时候硬取row.loc[0,...]自然会报错。
错误原因拆解
从错误栈和你的代码来看,问题出在这一行:
value = (row.loc[0,'Erster Schluss'].split()[0]).replace(',','.')
当df[df['Datum']== previous.strftime('%d.%m.%y')]没有匹配到任何行时,得到的是一个空DataFrame,哪怕reset_index()之后,它依然没有索引为0的行,直接调用loc[0]就会抛出KeyError: 0。你误以为是3位数字导致的,只是刚好那些日期的历史数据在网页里缺失而已。
另外你的代码还有一个隐藏bug:你把网页解析的代码(src = response.content、soup = BeautifulSoup(...))放在了while循环里,但response只请求了一次!这意味着你每次循环都在重复处理同一个页面的内容,根本没有获取新日期的数据。
解决方案
1. 先检查DataFrame是否为空,再访问数据
在尝试取row.loc[0,...]之前,先判断筛选后的结果是否有数据,避免空指针错误:
row = df[df['Datum']== previous.strftime('%d.%m.%y')].reset_index() # 先确认row不是空的 if not row.empty: value = row.loc[0,'Erster Schluss'].split()[0].replace(',','.') print(value) date = previous.strftime('%d.%m.%y') shareValues.append([value, date]) else: print(f"⚠️ 没有找到{previous.strftime('%d.%m.%y')}的历史数据")
2. 优化网页解析逻辑,避免重复解析
把网页请求和解析的代码移到循环外面,只执行一次(如果该页面包含你需要的所有历史数据):
def loadFromWebsite(company,ISIN): count = 28 URL = "https://www.boerse.de/historische-kurse/{0}-Aktie/{1}".format (company, ISIN) shareValues = [] # 只请求一次网页,避免重复请求浪费资源 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(URL, headers=headers) src = response.content soup = BeautifulSoup(src, 'html.parser') tables = soup.find_all("table") date_object = datetime.datetime.now() start = date_object + datetime.timedelta(days = -1) previous = start while count > 0: if previous.weekday() < 5: target_date = previous.strftime('%d.%m.%y') data_found = False for table in tables: if target_date in table.text: df = pd.read_html(str(table))[0] row = df[df['Datum'] == target_date].reset_index() if not row.empty: # 不管是几位数字,这里都能正常处理 value = row.loc[0,'Erster Schluss'].split()[0].replace(',','.') print(f"{target_date}: {value}") shareValues.append([value, target_date]) data_found = True break # 找到对应日期的表格就退出循环 if not data_found: print(f"⚠️ 无数据:{target_date}") count -= 1 previous = previous + datetime.timedelta(days = -1) return shareValues # 调用函数 loadFromWebsite("TecDax","DE0007203275")
3. 额外优化建议
- 加入
User-Agent请求头:避免被网站的反爬机制拦截,模拟浏览器请求 - 打印
df.columns确认列名:有时候网页表格的列名可能有空格或特殊字符,确保你用的Erster Schluss是准确的列名
内容的提问来源于stack exchange,提问作者Hendrik Niemax




