You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Beautiful Soup仅按<br>标签拆分段落,stripped_strings无法满足需求的解决方案

使用Beautiful Soup仅按
标签拆分段落,stripped_strings无法满足需求的解决方案

嘿,我完全懂你的困扰——stripped_strings虽然方便,但它会把所有独立的文本节点拆分开,哪怕这些文本属于同一个<br>分段里的不同子标签(比如你例子里的<font>和后面的COAT),所以才会出现RT和COAT被分成两行的情况。咱们要做的是把<br>作为唯一分隔符,把每个<br>之间的所有文本(不管嵌套在什么子标签里)合并成完整的一行。

下面给你两种可行的解决方案,你可以根据自己的HTML结构选更合适的:

方法一:直接遍历节点,按<br>分组合并文本

这种方法适合HTML结构稍复杂的场景,能精准控制每个分段的文本合并:

from bs4 import BeautifulSoup
import requests

pages = ['https://terminology.collectionstrust.org.uk/British-Museum-objects/Obthesa1.htm']
b = 1

for bp in pages:
    response = requests.get(bp)
    html = response.text
    soup = BeautifulSoup(html, "lxml")
    for blockquote in soup.find_all('blockquote'):
        # 获取当前blockquote对应的前置p标签文本
        prev_p = blockquote.find_previous('p')
        prev_text = prev_p.text.strip() if prev_p else ""
        # 定位到blockquote里的内容容器p标签
        p_container = blockquote.find('p')
        if not p_container:
            continue
        
        current_line = []
        # 遍历p标签下的所有子节点
        for node in p_container.contents:
            # 遇到<br>就结束当前行,输出合并后的文本
            if node.name == 'br':
                if current_line:
                    line_text = ''.join(current_line).strip()
                    if line_text:
                        print(b, prev_text, line_text)
                    current_line = []
            else:
                # 非<br>节点,提取所有文本(包括子标签里的)加入当前行
                node_text = node.get_text(strip=True)
                if node_text:
                    current_line.append(node_text)
        # 处理最后一个分段(可能没有<br>结尾)
        if current_line:
            line_text = ''.join(current_line).strip()
            if line_text:
                print(b, prev_text, line_text)
        b += 1

代码说明:

  1. 不再依赖stripped_strings遍历所有文本,而是直接遍历<p>标签的子节点。
  2. 遇到<br>就把之前收集的所有文本拼接成一行,输出后重置收集容器。
  3. 对于非<br>的节点,用get_text(strip=True)提取它包含的所有文本(不管嵌套多少层子标签),加入当前行的收集列表。

方法二:替换<br>为换行符,再拆分文本

如果你的HTML结构比较规范(所有<br>都是直接放在<p>下,没有嵌套在其他标签里),这种方法更简洁:

from bs4 import BeautifulSoup
import requests

pages = ['https://terminology.collectionstrust.org.uk/British-Museum-objects/Obthesa1.htm']
b = 1

for bp in pages:
    response = requests.get(bp)
    html = response.text
    soup = BeautifulSoup(html, "lxml")
    for blockquote in soup.find_all('blockquote'):
        prev_p = blockquote.find_previous('p')
        prev_text = prev_p.text.strip() if prev_p else ""
        p_container = blockquote.find('p')
        if not p_container:
            continue
        
        # 把所有<br>标签替换成换行符
        for br in p_container.find_all('br'):
            br.replace_with('\n')
        # 提取所有文本,按换行拆分,过滤空行
        lines = [line.strip() for line in p_container.get_text().split('\n') if line.strip()]
        # 输出每一行
        for line in lines:
            print(b, prev_text, line)
        b += 1

代码说明:

  1. 先把<p>里的所有<br>替换成换行符\n,这样原来的分段就变成了文本里的换行分隔。
  2. 用get_text()提取<p>的所有文本(自动合并所有子标签的文本),再按换行符拆分,最后过滤掉空行就得到了我们要的每一行。

这两种方法都能得到你想要的结果:

2 ABAYAH RT CLOAK
2 ABAYAH RT COAT
2 ABAYAH BT GARMENT
2 ABAYAH NP ABBA

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 08:23:13