新手求助:用BeautifulSoup提取无标识财务数据并存入Pandas DataFrame
问题
本人是网页爬虫绝对新手,需要从指定网站提取财务数据,目标数据隐藏在无序列表(ul)及无名称的span标签中。当前用BeautifulSoup写的代码跑不起来,想获取正确方法提取Κεφαλαιοποίηση对应的数值2.320.552.455(要去掉欧元符号),还要把数据存入Pandas DataFrame。
网页HTML片段
<div class="finance__details__right"> <ul> <li> <i>Άνοιγμα</i> <span data-bind="text: o.extend({priceNumeric: { dependOn: l, precision: 4 }})">15,8100</span> </li> <li> <i>Υψηλό</i> <span data-bind="text: hp.extend({priceNumeric: { dependOn: l, precision: 4 }})">16,2400</span> </li> <li> <i>Χαμηλό</i> <span data-bind="text: lp.extend({priceNumeric: { dependOn: l, precision: 4 }})">15,8100</span> </li> </ul> <ul> <li> <i>Όγκος</i> <span data-bind="text: tv() > 0? tv.extend({numeric: { precision: 0}})(): '', flashBackground: tv">301.286</span> </li> <li> <i>Τζίρος</i> <span data-bind="text: to() > 0? to.extend({numeric: { precision: 0 }})() + ' €': '', flashBackground: to"> 4.843.588 € </span> </li> <li> <i>Πράξεις</i> <span data-bind="text: t() > 0? t.extend({numeric: { precision: 0}})(): '', flashBackground: t">1.890</span> </li> </ul> <ul> <li> <i>Αγοραστές</i> <span data-bind="text: bs() > 0? b.extend({priceNumeric: l})() + ' x ' + bs.extend({numeric: { precision: 0}})(): '', flashBackground: b"> </span> </li> <li> <i>Πωλητές</i> <span data-bind="text: as() > 0? a.extend({priceNumeric: l})() + ' x ' + as.extend({numeric: { precision: 0}})(): '', flashBackground: a"> 16,2400 x 6.884 </span> </li> <li> <i>Κεφαλαιοποίηση</i> <span data-bind="text: cp.extend({numeric: { precision: 0}})() + ' €', flashBackground: cp">2.320.552.455 €</span> </li>
失效代码
SCRIP = 'ΜΥΤΙΛ' link = f'https://www.capital.gr/finance/quote/{SCRIP}' hdr = {'User-Agent':'Mozilla/5.0'} req = Request(link,headers=hdr) try: page=urlopen(req) soup = BeautifulSoup(page) div_html = soup.find('div',{'class': 'finance_details_right'}) ul_html = div_html.find('ul') Κεφαλαιοποίηση = 0.0 for li in ul_html.find_all("li"): name_span = li.find('') if 'Κεφαλαιοποίηση' in name_span.text: num_span = li.find('span',{'class':''}) Κεφαλαιοποίηση = float(num_span) if (num_span != '') else 0.0 break print(f'Κεφαλαιοποίηση - {SCRIP}: {Κεφαλαιοποίηση} Cr') except: print(f'EXCEPTION THROWN: UNABLE TO FETCH DATA FOR {SCRIP}')
解决方法
原代码的核心问题
- 类名匹配错误:HTML里的div类是
finance__details__right,代码里写成了finance_details_right(少了两个下划线),导致定位不到容器。 - 范围遍历错误:目标数据在第三个ul里,原代码只取了第一个ul,根本遍历不到目标li。
- 元素查找无效:
li.find('')是错误写法,应该找<i>标签来获取标题文本。 - 数值处理错误:直接把span对象转float会报错,必须先提取文本,清理掉欧元符号和千分位分隔符再转换。
修正后的完整代码
import pandas as pd from urllib.request import Request, urlopen from bs4 import BeautifulSoup SCRIP = 'ΜΥΤΙΛ' link = f'https://www.capital.gr/finance/quote/{SCRIP}' hdr = {'User-Agent':'Mozilla/5.0'} req = Request(link, headers=hdr) try: page = urlopen(req) # 指定解析器避免警告 soup = BeautifulSoup(page, 'html.parser') # 定位正确的div容器 div_html = soup.find('div', {'class': 'finance__details__right'}) # 获取所有ul标签,遍历所有可能的列表 all_uls = div_html.find_all('ul') κεφαλαιοποίηση = 0.0 # 逐层遍历所有ul下的li for ul in all_uls: for li in ul.find_all('li'): # 通过i标签获取标题文本 title_tag = li.find('i') if title_tag and 'Κεφαλαιοποίηση' in title_tag.text.strip(): # 提取对应的span文本 num_span = li.find('span') if num_span: # 清理文本:移除欧元符号(含实体编码)、空格、千分位点 clean_text = num_span.text.strip().replace('€', '').replace('€', '').replace('.', '').strip() # 转换为数值 κεφαλαιοποίηση = float(clean_text) if clean_text else 0.0 break # 将数据存入Pandas DataFrame df = pd.DataFrame({ '股票代码': [SCRIP], 'Κεφαλαιοποίηση': [κεφαλαιοποίηση] }) print(df) # 可选:保存到CSV文件 # df.to_csv('财务数据.csv', index=False, encoding='utf-8') except Exception as e: # 捕获具体错误信息,方便调试 print(f'报错: 无法获取{SCRIP}的数据,错误详情: {str(e)}')
关键说明
- 修复了div类名,确保能定位到正确的父容器。
- 遍历所有ul标签,不会错过目标数据所在的列表。
- 通过
<i>标签匹配标题,准确找到目标项。 - 文本清理时处理了两种欧元符号形式(普通字符和HTML实体),移除千分位的点后再转float,避免转换错误。
- 最后将数据封装到DataFrame,方便后续分析或导出。
内容的提问来源于stack exchange,提问作者grayred8
相关产品推荐
相关产品推荐

