如何用Python和BeautifulSoup批量提取嵌套HTML的时长与加价信息?
问题描述
现有如下单个HTML标签:
<label class="cOpt" for="prod_1234_rMon_3"> <span>12 M <span>+300 €</span></span> </label>
需要提取其中的「12 M」和「+300 €」信息。实际场景中存在多个同类标签(结构如下),尝试用find方法只能返回第一个值,无法获取所有条目:
vObj_detail = bsObj.find('label', attrs={'class': 'cOpt'}).get_text(strip=True).split("+")
实际HTML源数据:
<label class="cOpt" for="prod_1234_rMon_0"> <span>6 M</span> </label> <label class="cOpt" for="prod_1234_rMon_1"> <span>24 M <span>+150 € </span> </span> </label> <label class="cOpt" for="prod_1234_rMon_2"> <span>18 M <span> +200 € </span> </span> </label> <label class="cOpt" for="prod_1234_rMon_3"> <span>12 M <span>+300 € </span> </span> </label> <label class="cOpt" for="prod_1234_rRen_0"> <span>1.250 km </span> </label> <label class="cOpt" for="prod_1234_rRen_1"> <span>1.750 km <span>+100 € </span> </span> </label> <label class="cOpt" for="prod_1234_rRen_2"> <span>2.000 km <span>+150 € </span> </span> </label> <label class="cOpt" for="prod_1234_rRen_3"> <span>2.500 km <span>+250 € </span> </span> </label>
解决方案
核心问题修正
你之前的代码用了find()方法,它仅返回匹配的第一个元素,改用find_all()即可获取所有符合条件的标签。
方法一:基于DOM结构精准提取(推荐)
利用HTML标签层级结构直接提取内容,不受文本格式(换行、空格)影响,稳定性更高:
from bs4 import BeautifulSoup # 替换为你的原始HTML内容 html_content = """[这里放入实际的HTML代码]""" soup = BeautifulSoup(html_content, "html.parser") # 获取所有class为cOpt的label标签 all_options = soup.find_all("label", class_="cOpt") extracted_data = [] for label in all_options: outer_span = label.find("span") # 提取外层span的直接文本(排除子span内容) base_option = outer_span.contents[0].strip() if outer_span.contents else "" # 提取内层span的加价文本(如果存在) price_span = outer_span.find("span") extra_price = price_span.get_text(strip=True) if price_span else "" extracted_data.append({ "基础选项": base_option, "加价": extra_price }) # 打印结果 for item in extracted_data: print(item)
方法二:基于文本拆分提取(适用于结构简单场景)
如果标签文本格式固定,可通过文本拆分快速提取:
from bs4 import BeautifulSoup html_content = """[这里放入实际的HTML代码]""" soup = BeautifulSoup(html_content, "html.parser") all_options = soup.find_all("label", class_="cOpt") extracted_data = [] for label in all_options: full_text = label.get_text(strip=True) if "+" in full_text: base_part, price_part = full_text.split("+", 1) base_option = base_part.strip() extra_price = "+" + price_part.strip() else: base_option = full_text.strip() extra_price = "" extracted_data.append({ "基础选项": base_option, "加价": extra_price }) # 打印结果 for item in extracted_data: print(item)
输出示例
两种方法都会输出类似以下结构的结果:
{'基础选项': '6 M', '加价': ''} {'基础选项': '24 M', '加价': '+150 €'} {'基础选项': '18 M', '加价': '+200 €'} {'基础选项': '12 M', '加价': '+300 €'} {'基础选项': '1.250 km', '加价': ''} {'基础选项': '1.750 km', '加价': '+100 €'} {'基础选项': '2.000 km', '加价': '+150 €'} {'基础选项': '2.500 km', '加价': '+250 €'}
内容的提问来源于stack exchange,提问作者ioSven
相关产品推荐
相关产品推荐

