如何从HTML提取page=、new">、/a>-后的三类数字?用BS还是正则?
提取方案选型对比
最终选型结论
优先使用BeautifulSoup基于已定位的a标签做关联提取,不建议直接用正则全局匹配整个HTML。
全局正则匹配的弊端
- 匹配精度无保障:全局扫描
/a>-\d+模式时,只要页面任意位置出现同类字符串(比如无关a标签闭合后、HTML注释、其他功能模块的文本里的相似片段),就会误抓结果。 - 结果对齐成本极高:你已经筛选出了符合条件的a标签列表,全局匹配到的数字序列很可能和a标签的顺序、数量不匹配,最后会出现跨条目错位,把不同pdf条目下的页码数混在一起。
基于a标签关联提取的优势
- 绑定关系天然可靠:第三类数字本身就是紧跟在对应a标签后面的同级文本节点,和当前循环处理的a标签属于同一个页码条目,不会出现跨条目错位。
- 完全兼容你现有的循环流程,不需要重新全量扫描HTML,执行效率更高。
现有代码的问题与修正
你现在写的循环逻辑有两处明显问题:
number1 = filter(regex.match, tables)逻辑完全错误:regex.match是从字符串起始位置做匹配,tables是整个a标签对象列表,既没有把每个a标签的href属性单独传入匹配,也没有用search做子串匹配,根本取不到page后面的数字。- 你在尝试用
table.next_sibling.strip()取a标签后的文本时,拿到的就是类似-4450的字符串,拆分后刚好可以对应第二类、第三类数字的位置,不需要额外扫描全页。
修正后的可运行代码
import re from bs4 import BeautifulSoup # 初始化解析器(替换为你自己的HTML源码、解析器配置) soup = BeautifulSoup(your_html_content, "html.parser") target_a_tags = soup.find_all('a', attrs={'target': 'new'}) list_of_number1 = [] # page=后跟的数字 list_of_number2 = [] # target="new">后面的a标签文本数字 list_of_number3 = [] # /a>-后面的数字 # 预编译匹配规则 page_re = re.compile(r"page=(\d+)") dash_re = re.compile(r"-(\d+)") for a_tag in target_a_tags: # 提取number1:从a标签的href属性中匹配page后的数字 href_content = a_tag.get("href", "") page_result = page_re.search(href_content) list_of_number1.append(int(page_result.group(1)) if page_result else None) # 提取number2:a标签内部的纯文本内容 a_inner_text = a_tag.get_text(strip=True) list_of_number2.append(int(a_inner_text)) # 提取number3:a标签紧邻的后续兄弟文本节点中,横杠后的数字 next_text_node = a_tag.next_sibling.strip() if a_tag.next_sibling else "" dash_result = dash_re.search(next_text_node) list_of_number3.append(int(dash_result.group(1)) if dash_result else None)
边界场景说明:如果a标签和后续横杠数字之间插入了其他嵌套HTML标签(比如
<b>、<span>),直接取next_sibling可能拿不到目标文本,这时候可以定位a标签的父级td元素,在父元素的全量文本里做匹配,这种方式的匹配精度依然远高于全局正则扫描。
内容的提问来源于stack exchange,提问作者id345678
相关产品推荐
相关产品推荐

