You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Python爬虫:如何用BeautifulSoup同时提取标题与段落并按原序输出?

嘿,刚好能帮到你!我懂你现在的需求——之前只能爬取零散的段落,现在想让爬取结果跟着原网页的结构走,每个段落前面都带上对应的标题,这样内容逻辑清晰多了对吧?

作为用BeautifulSoup的新手,其实只要稍微调整一下逻辑,就能实现这种结构化输出。我给你举两个常用场景的代码例子,你可以根据自己爬的网页结构来适配:

场景1:标题和段落是兄弟元素(标题后直接跟段落,直到下一个标题)

这种是最常见的网页结构,比如h2后面跟着几个p,然后是下一个h3。代码可以这么写:

from bs4 import BeautifulSoup

# 这里替换成你实际获取到的网页HTML内容
html_content = """
<html>
  <body>
    <h2>BeautifulSoup基础用法</h2>
    <p>BeautifulSoup可以将复杂HTML文档转换成一个树形结构,每个节点都是Python对象。</p>
    <p>常用的解析器有html.parser(Python内置)、lxml(速度快)和html5lib(兼容性好)。</p>
    <h3>提取元素的常用方法</h3>
    <p>find()方法返回第一个匹配的元素,find_all()返回所有匹配的元素列表。</p>
    <p>get_text()方法可以提取元素中的纯文本内容,strip=True能去掉多余的空格和换行。</p>
  </body>
</html>
"""

# 初始化BeautifulSoup对象
soup = BeautifulSoup(html_content, 'html.parser')

# 先找到所有的标题标签,这里选h2和h3,你可以根据网页实际情况加h1/h4等
all_headings = soup.find_all(['h2', 'h3'])

for heading in all_headings:
    # 先输出标题,用###标识让结构更清晰
    print(f"### {heading.get_text(strip=True)}")
    # 遍历标题的下一个兄弟元素,直到遇到下一个标题为止
    next_node = heading.next_sibling
    while next_node:
        # 如果是段落标签,就输出内容
        if next_node.name == 'p':
            print(f"- {next_node.get_text(strip=True)}")
        # 如果碰到下一个标题,就停止当前循环,处理下一个标题
        elif next_node.name in ['h2', 'h3']:
            break
        # 继续找下一个兄弟节点
        next_node = next_node.next_sibling
    # 每个标题块之间加空行分隔
    print("\n")

场景2:标题和段落都在同一个容器里(比如section/div)

有些网页会把每个标题+段落组放在一个容器标签里,比如<section>,这种情况更简单,直接遍历容器就行:

from bs4 import BeautifulSoup

html_content = """
<html>
  <body>
    <section>
      <h2>安装BeautifulSoup</h2>
      <p>打开终端,执行pip install beautifulsoup4即可安装核心库。</p>
      <p>如果需要用lxml解析器,还要额外安装:pip install lxml</p>
    </section>
    <section>
      <h3>实战小技巧</h3>
      <p>爬取动态网页时,BeautifulSoup无法处理JS加载的内容,这时候可能需要配合Selenium或Requests-HTML。</p>
    </section>
  </body>
</html>
"""

soup = BeautifulSoup(html_content, 'html.parser')

# 找到所有容器标签
containers = soup.find_all('section')

for container in containers:
    # 在容器内找标题
    heading = container.find(['h2', 'h3'])
    if heading:
        print(f"### {heading.get_text(strip=True)}")
        # 在容器内找所有段落
        paragraphs = container.find_all('p')
        for p in paragraphs:
            print(f"- {p.get_text(strip=True)}")
        print("\n")

小提示

  • 你需要根据目标网页的实际HTML结构调整标题标签(比如有的网页用h1作为主标题,h4作为子标题)和容器标签(比如有的用div而不是section)。
  • 如果不确定网页结构,可以右键网页→查看页面源代码,看看标题和段落的嵌套关系。

要是你爬的网页有特殊的结构,比如标题和段落不是直接相邻或者在多层嵌套里,把对应的HTML片段贴出来,我再帮你调整代码~

内容的提问来源于stack exchange,提问作者akisonlyforu

火山引擎 最新活动