
本文详解为何 CSS 选择器返回 None,并提供健壮的 BeautifulSoup 解析方案,解决因缺失 标签导致的元素定位失败问题,确保燃油价格自动抓取稳定可靠。 本文详解为何 CSS 选择器返回 `None`,并提供健壮的 BeautifulSoup 解析方案,解决因缺失 `` 标签导致的元素定位失败问题,确保燃油价格自动抓取稳定可靠。在使用 BeautifulSoup(特别是 select_one())从网页中提取结构化数据时,一个常见却极易被忽视的问题是:HTML 文档实际结构与开发者工具中显示的“美化后结构”不一致。你遇到的 "Initial number: None" 错误,根本原因正是 CSS 选择器过度依赖了浏览器开发者工具自动补全的 标签——而目标网站 https://nbeub.ca/index.php?page=current-petroleum-prices-2 的原始 HTML 中, 元素是直接嵌套在 内的,并未显式声明 。因此,原选择器:body > table > tbody > tr:nth-child(5) > td > ...会在解析时逐级匹配失败,最终返回 None。✅ 正确做法是改用更鲁棒的后代选择器(descendant selector),省略对 的强制要求。只需将所有 > tbody > 替换为空格(即 ` `),让选择器匹配任意层级的后代元素:import requests from bs4 import BeautifulSoup import time url = 'https://nbeub.ca/index.php?page=current-petroleum-prices-2' def fetch_number(): try: response = requests.get(url, timeout=10) response.raise_for_status() # 检查 HTTP 错误状态码 soup = BeautifulSoup(response.text, 'html.parser') # ✅ 修正后的选择器:移除所有 > tbody >,使用空格表示后代关系 element = soup.select_one( 'body > table tr:nth-child(5) > td > table tr > td > table tr > td:nth-child(3) > table tr:nth-child(3) > td:nth-child(2)' ) # 安全提取文本:去除空白、处理 None if element and element.get_text(strip=True): return element.get_text(strip=True) else: return "N/A" except Exception as e: print(f"⚠️ 抓取异常: {e}") return "ERROR" def monitor(): last_number = fetch_number() print(f"Initial number: {last_number}") # ⚠️ 注意:原代码中 time.sleep(2592000) 是 30 天,开发调试建议先设为 10–60 秒 while True: time.sleep(60) # 调试阶段建议缩短间隔 current_number = fetch_number() if current_number != last_number and current_number not in ["N/A", "ERROR"]: print(f"✅ Number updated: {current_number}") last_number = current_number else: print("ℹ️ No change or invalid value.") if __name__ == "__main__": monitor()? 关键优化说明: 选择器健壮性提升:使用 table tr(后代)替代 table > tbody > tr(子元素),兼容无 的真实 HTML; 异常防护:添加 try/except 和 response.raise_for_status(),避免网络错误导致程序崩溃; 文本安全提取:调用 .get_text(strip=True) 避免空格、换行干扰,并显式检查 element 是否存在; 调试友好:初始轮询间隔改为 60 秒,便于快速验证逻辑;生产环境再按需调整至数小时或数天; 可维护性增强:若未来页面结构调整,建议结合 soup.find_all('table') 层级遍历 + 关键文本定位(如查找含 "Regular Unleaded" 的行),比硬编码 nth-child 更可持续。? 额外建议:该网站未设置反爬头,但长期运行仍建议添加 headers={'User-Agent': 'Mozilla/5.0...'};同时注意遵守 robots.txt(访问 https://nbeub.ca/robots.txt 查看限制),并尊重网站更新频率,避免高频请求。通过以上调整,你的燃油价格解析器将稳定输出真实数值,真正为计算器提供动态、准确的油价数据支撑。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










