
本文介绍如何使用 requests + BeautifulSoup 配合正则清洗,从嵌入 JavaScript 的混淆 HTML 表格中稳定提取 内的商品名称(如 FEIJAO CARIOCA URBAN),解决换行符、制表符及转义序列干扰导致的解析失败问题。
本文介绍如何使用 requests + beautifulsoup 配合正则清洗,从嵌入 javascript 的混淆 html 表格中稳定提取 `` 内的商品名称(如 `feijao carioca urban`),解决换行符、制表符及转义序列干扰导致的解析失败问题。
在抓取巴西电子发票(NFC-e)Danfe 页面时,目标商品标题常被包裹在动态生成的 HTML 片段中——这些片段并非直接存在于初始 HTML DOM,而是通过 JavaScript(如 new DanfeNFCe(...))注入到 <script> 标签内。原始响应中混杂大量 、 、\r 及 HTML 实体(如 ),若直接对 script 内容调用 BeautifulSoup,会因未解码转义或结构不完整而解析失败。</script>
核心思路分三步:
- 定位脚本块:用 soup.select_one("script[type='text/javascript']:-soup-contains('new DanfeNFCe')") 精准捕获含表格数据的 JS 脚本;
-
提取并清洗 HTML 字符串:用正则 re.findall(r"(
)", ...) 提取完整 片段,再通过 re.sub(r'\r|\n|\\', '', raw_html) 清除所有转义符与换行,确保 HTML 结构合法;
- 二次解析与提取:将清洗后的字符串重新载入 BeautifulSoup,使用 CSS 选择器 table#tabResult > tr > td > span.txtTit 精确匹配每行商品标题节点,并调用 .get_text(strip=True) 去除首尾空白及内部冗余空格。
以下是可直接运行的优化代码:
@@######@@⚠️ 注意事项:
- 该页面依赖会话状态(如 Cookie),必须使用 requests.Session() 并先访问 start_url;
- 正则 r"(
)" 易受嵌套干扰,推荐改用非贪婪匹配 r"( ]*id="tabResult"[^>]*>[sS]*?
)" 提高鲁棒性; - 若目标站点启用 CSP 或反爬策略,需补充 Referer 头或处理验证码;
- lxml 解析器对损坏 HTML 容错性优于 html.parser,但需确保已安装 lxml 包(pip install lxml)。
此方法绕过了前端渲染依赖,不需 Selenium,兼顾效率与稳定性,适用于批量解析同类 NFC-e Danfe 表格场景。
from bs4 import BeautifulSoup import requests import re start_url = 'http://nfe.sefaz.go.gov.br/nfeweb/sites/nfce/d/danfeNFCe?p=52240345543915002478650110004179799060499506|2|1|19|118.42|2b4937755a5a76797a522b6435534159784f5859427646356c7a4d3d|1|A763ED574AF1AECE3380D1E3A1EE188E3E95B414' url = "http://nfe.sefaz.go.gov.br/nfeweb/sites/nfce/render/danfeNFCe?chNFe=52240345543915002478650110004179799060499506" headers = { "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:101.0) Gecko/20100101 Firefox/101.0", } with requests.Session() as s: s.headers.update(headers) s.get(start_url) # 触发会话初始化与 Cookie 设置 resp = s.get(url) soup = BeautifulSoup(resp.text, "lxml") # 步骤1:定位含表格的 JS 脚本 script_tag = soup.select_one("script[type='text/javascript']:-soup-contains('new DanfeNFCe')") if not script_tag or not script_tag.contents: raise ValueError("未找到包含 DanfeNFCe 初始化的 script 标签") js_content = script_tag.contents[0] # 步骤2:提取 table HTML 并清洗转义符 table_match = re.search(r"(]*id="tabResult"[^>]*>[sS]*?
)", js_content) if not table_match: raise ValueError("未能从脚本中提取 tabResult 表格 HTML") raw_table_html = table_match.group(1) cleaned_html = re.sub(r'\r|\n|\\', '', raw_table_html) # 移除常见转义符 # 步骤3:二次解析并提取标题 table_soup = BeautifulSoup(cleaned_html, "lxml") titles = [ span.get_text(strip=True) for span in table_soup.select("table#tabResult > tr > td > span.txtTit") ] # 输出结果 for i, title in enumerate(titles, 1): print(f"{i:2d}. {title}")











