如何提取嵌套<font>标签价格数据并合并矿物名称与价格列表?
问题描述
正在制作矿物名称+价格的列表,已成功获取第一页的矿物名称,但无法提取价格数据。尝试过兄弟/父标签等方法但未成功。另外,若使用两个for循环,能否将矿物名称列表与价格列表合并?需要提取嵌套<font>标签中的价格内容(如€580 / US$598 / ¥84010 / AUD$890),而非“Price:”文本,当前通过find('font')无法获取目标数据。
附代码片段:
import requests from bs4 import BeautifulSoup URL = "https://www.fabreminerals.com/search_results.php?LANG=EN&SearchTerms=&submit=Buscar&MineralSpeciment=&Country=&Locality=&PriceRange=&checkbox=enventa&First=0" headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36'} page = requests.get(URL, headers=headers) print(page.content) soup = BeautifulSoup(page.content, 'html5lib') table = soup.find('a', attrs = {'name':'SearchTop'}) print(table.prettify()) for names in table.find_all('img', alt=True): print(names['alt']) print(soup.find_all('font'))
目标HTML片段:
<font face="Arial, Helvetica, sans-serif" size="-1"> <font color="#FF0000"> Price: </font> €580 / US$598 / ¥84010 / AUD$890 </font>
解决方法
1. 正确提取价格数据
针对目标HTML结构,有两种可靠的提取方式:
- 方式一:通过“Price:”标签的兄弟节点提取
找到包含“Price:”的子<font>标签(color="#FF0000"),然后取它的next_sibling,再清理空白字符即可得到价格:
price_tag = container.find('font', color="#FF0000") price = price_tag.next_sibling.strip()
- 方式二:通过父标签文本过滤提取
直接获取外层<font>标签的所有文本,然后去掉“Price:”部分并清理空白:
parent_font = container.find('font', face="Arial, Helvetica, sans-serif", size="-1") full_text = parent_font.get_text(strip=True, separator=" ") price = full_text.replace("Price:", "").strip()
2. 合并矿物名称与价格列表
不建议用两个独立的for循环分别收集名称和价格(容易因页面结构变动导致顺序错乱),最优方式是遍历每个矿物的容器节点,在同一个循环内同时提取名称和价格,然后直接配对存入列表或字典。
如果已经有两个独立的列表,也可以用zip()函数将它们按顺序合并:
mineral_names = [name['alt'] for name in table.find_all('img', alt=True)] prices = [price for price in price_list] # 假设已提取好价格列表 mineral_data = list(zip(mineral_names, prices))
修改后的完整代码
import requests from bs4 import BeautifulSoup URL = "https://www.fabreminerals.com/search_results.php?LANG=EN&SearchTerms=&submit=Buscar&MineralSpeciment=&Country=&Locality=&PriceRange=&checkbox=enventa&First=0" headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36'} page = requests.get(URL, headers=headers) soup = BeautifulSoup(page.content, 'html5lib') # 找到包含所有矿物的容器(这里基于原代码调整到父节点,需根据实际页面结构微调) table = soup.find('a', attrs={'name':'SearchTop'}).parent mineral_list = [] # 遍历每个矿物项(示例用<tr>,需根据页面实际结构替换为对应容器标签) for item in table.find_all('tr'): # 提取矿物名称 name_tag = item.find('img', alt=True) if not name_tag: continue mineral_name = name_tag['alt'] # 提取价格 price_tag = item.find('font', color="#FF0000") if not price_tag: mineral_price = "无价格" else: mineral_price = price_tag.next_sibling.strip() mineral_list.append({"名称": mineral_name, "价格": mineral_price}) # 输出结果 for idx, mineral in enumerate(mineral_list, 1): print(f"{idx}. {mineral['名称']} - {mineral['价格']}")
注意事项
- 需根据页面实际HTML结构调整矿物容器的选择器(比如示例中的
find_all('tr')),确保每个item对应单个矿物的完整信息。 - 当前目标链接为静态内容,
requests即可处理;若后续页面有动态加载,可改用selenium。
内容的提问来源于stack exchange,提问作者michalb93
相关产品推荐
相关产品推荐

