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

如何使用Python爬取整站h1-h6标题并导出为Excel/CSV文件

整站H1-H6层级标题采集脚本

前置依赖安装

先安装脚本运行需要的第三方库,执行命令如下:

pip install requests beautifulsoup4 lxml pandas openpyxl

完整可运行代码

import time
import requests
from bs4 import BeautifulSoup
from urllib.parse import urlparse, urljoin
import pandas as pd

# -------------------------- 配置项 --------------------------
start_url = "https://www.nypost.com"  # 替换为目标站点入口URL
heading_tags = ["h1", "h2", "h3", "h4", "h5", "h6"]  # 要采集的标题层级
request_delay = 1  # 单次请求间隔(秒),建议不小于1避免触发反爬
request_headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
}
# -----------------------------------------------------------

# 初始化爬取队列、已爬集合、结果存储
crawled_urls = set()
pending_urls = {start_url}
target_domain = urlparse(start_url).netloc
result_list = []

print(f"开始采集站点:{start_url},目标域名:{target_domain}")

while pending_urls:
    current_url = pending_urls.pop()
    # 跳过已爬取链接
    if current_url in crawled_urls:
        continue
    crawled_urls.add(current_url)
    print(f"正在爬取:{current_url},已爬页面数:{len(crawled_urls)},待爬队列长度:{len(pending_urls)}")

    try:
        response = requests.get(current_url, headers=request_headers, timeout=10)
        response.encoding = response.apparent_encoding
        # 跳过非HTML内容
        if "text/html" not in response.headers.get("Content-Type", ""):
            continue
    except Exception as e:
        print(f"请求{current_url}失败:{str(e)}")
        continue

    # 解析页面提取标题
    soup = BeautifulSoup(response.text, "lxml")
    for tag in soup.find_all(heading_tags):
        tag_content = tag.text.strip()
        if tag_content:  # 跳过空内容标题
            result_list.append({
                "页面URL": current_url,
                "标题层级": tag.name.upper(),
                "标题内容": tag_content
            })

    # 提取页面内所有同域链接加入待爬队列
    for a_tag in soup.find_all("a", href=True):
        href = a_tag["href"].strip()
        # 过滤无效链接
        if not href or href.startswith(("javascript:", "mailto:", "tel:", "#")):
            continue
        # 拼接为绝对路径,去除锚点
        full_url = urljoin(current_url, href).split("#")[0]
        # 仅保留同域链接,跳过已爬链接
        if urlparse(full_url).netloc == target_domain and full_url not in crawled_urls:
            pending_urls.add(full_url)

    time.sleep(request_delay)

# 导出结果
print(f"采集完成,共爬取{len(crawled_urls)}个页面,采集到{len(result_list)}条标题,开始导出文件")
df = pd.DataFrame(result_list)
# 导出CSV,用utf-8-sig编码避免中文乱码
df.to_csv("site_headings.csv", index=False, encoding="utf-8-sig")
# 导出Excel
df.to_excel("site_headings.xlsx", index=False, engine="openpyxl")
print("文件导出完成,已保存至脚本同目录下的site_headings.csv和site_headings.xlsx")

使用说明

  • 替换代码配置区的start_url为需要采集的目标站点入口地址即可运行
  • 若仅需要采集部分层级标题,可修改heading_tags列表,比如保留["h1", "h2", "h3"]即可和原有代码采集范围一致
  • 不要将request_delay设置过小,高频请求可能触发站点反爬导致IP被临时封禁,也会对目标站点服务器造成压力
  • 脚本会自动过滤跨域外链、重复页面、非HTML资源链接,不会爬取目标域名外的内容
  • 导出的CSV文件可用文本编辑器、Excel打开,xlsx文件可直接用Excel编辑

原有单页采集代码的不足

  • 无整站链接遍历逻辑,仅能采集单个输入页面的标题
  • 仅覆盖h1-h3标签,未包含h4-h6层级内容
  • 未配置模拟浏览器请求头,多数站点会直接返回403拦截请求
  • 无结果持久化能力,采集内容仅在控制台打印,无法导出为文件
  • 无异常处理逻辑,遇到请求错误、非HTML内容时会直接中断运行

内容的提问来源于stack exchange,提问作者MD. Sujon Sarder

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.31 20:48:47