网页提取企业财务数据存CSV仅保留最后一行的解决求助
解决CSV仅保存最后一组财务数据的问题
我帮你分析下代码里的两个关键问题,以及对应的修复方案:
问题诊断
- 文件写入模式错误:你每次循环调用
df2.to_csv('output.csv', ...)时,默认使用的是mode='w'(覆盖写入),这意味着每次循环都会清空之前写入的内容,最终只有最后一次循环的数据被保留在CSV里。 - 循环中固定了目标公司:代码里的
url2 = f'https://www.bankier.pl/gielda/notowania/akcje/{names_of_company[0]}/wyniki-finansowe'用了names_of_company[0],也就是始终爬取第一家公司的数据——哪怕你循环了464次,爬的都是同一家的内容,这也是个隐藏的bug!
修复方案
这里提供两种可行的解决方法,你可以根据需求选择:
方法1:先收集所有数据再统一写入(推荐)
这种方法先把所有公司的财务数据存入列表,最后合并成一个DataFrame再写入CSV,效率更高,也方便后续数据处理:
import requests from bs4 import BeautifulSoup import pandas as pd import time # 可选,用于添加爬取延迟 url = 'https://www.bankier.pl/gielda/notowania/akcje' page = requests.get(url) soup = BeautifulSoup(page.content,'lxml') # 获取公司列表 t = soup.find_all('table')[0] df = pd.read_html(str(t))[0] names_of_company = df["Walor AD"].values # 初始化列表存储所有公司的财务数据 all_financial_dfs = [] for company_name in names_of_company: # 修正URL,使用当前循环的公司名称 url2 = f'https://www.bankier.pl/gielda/notowania/akcje/{company_name}/wyniki-finansowe' page2 = requests.get(url2) soup2 = BeautifulSoup(page2.content,'lxml') # 解析财务数据表格 t2 = soup2.find_all('table')[0] df2 = pd.read_html(str(t2))[0] # 添加公司名称列,方便区分数据来源 df2['公司名称'] = company_name all_financial_dfs.append(df2) # 可选:添加1秒延迟,避免给服务器造成过大压力 time.sleep(1) # 合并所有DataFrame combined_df = pd.concat(all_financial_dfs, ignore_index=True) # 写入CSV combined_df.to_csv('output.csv', index=False)
方法2:循环中以追加模式写入
如果数据量极大,不想占用太多内存,可以选择每次循环以追加模式写入CSV,注意第一次写入要保留表头,之后跳过表头:
import requests from bs4 import BeautifulSoup import pandas as pd import time url = 'https://www.bankier.pl/gielda/notowania/akcje' page = requests.get(url) soup = BeautifulSoup(page.content,'lxml') t = soup.find_all('table')[0] df = pd.read_html(str(t))[0] names_of_company = df["Walor AD"].values # 标记是否为第一次写入(控制表头) is_first_write = True for company_name in names_of_company: url2 = f'https://www.bankier.pl/gielda/notowania/akcje/{company_name}/wyniki-finansowe' page2 = requests.get(url2) soup2 = BeautifulSoup(page2.content,'lxml') t2 = soup2.find_all('table')[0] df2 = pd.read_html(str(t2))[0] df2['公司名称'] = company_name # 第一次写入用覆盖模式并写入表头,后续用追加模式跳过表头 if is_first_write: df2.to_csv('output.csv', index=False) is_first_write = False else: df2.to_csv('output.csv', mode='a', index=False, header=False) time.sleep(1)
额外建议
- 异常处理:可以给请求和解析部分加上
try-except块,避免因为某一家公司数据异常导致整个程序中断。 - 爬取延迟:添加
time.sleep()是个好习惯,能降低被网站反爬机制拦截的风险。
内容的提问来源于stack exchange,提问作者Tmiskiewicz
相关产品推荐
相关产品推荐

