Python实现全站链接爬取工具:助力打造AI 知识库

1 阅读5分钟

Python实现全站链接爬取工具:助力打造AI 知识库

标签:#Python #Playwright #爬虫 #AI知识库
日期:2026-05-01
摘要:本文介绍一个自己开发的基于 Playwright 的全站站内链接爬取工具,通过递归爬取 + BeautifulSoup 解析实现自动收集网站所有内部链接,支持导出为 Markdown 格式,方便批量导入 AI 知识库进行"提问式学习"。


前言

最近在学习 NiceGUI 时,发现官方文档内容非常丰富,组件数量有一百多个。按照传统方式逐页阅读,效率很低。

有了 AI 之后,更高效的学习方式是:把官方文档变成你的私人 AI 知识库,用提问代替搜索

具体分三步走:

  1. 收集:抓取技术网站的所有站内链接
  2. 导入:将链接批量导入 AI 知识库工具(我用的是腾讯 IMA)
  3. 对话:像和老师一对一交流一样,用自然语言提问学习

本文重点介绍:如何高效抓取全站链接


一、实现原理

🎯 核心思路

用户输入URL
    ↓
递归爬取每个页面的内部链接
    ↓
BeautifulSoup 解析 HTML,提取 <a> 标签
    ↓
过滤:同域名、非锚点、HTTP/HTTPS
    ↓
去重后保存为 Markdown 文件

🔑 关键技术点

技术作用
Playwright渲染 JavaScript,获取动态加载后的完整 HTML
BeautifulSoup解析 HTML,快速定位所有链接
urljoin将相对路径转换为绝对路径
递归爬取从首页开始,自动发现并访问所有子页面

二、完整源码

'''
全站站内链接爬取脚本
功能:递归爬取指定网站的所有内部链接,自动过滤锚点链接
'''
from bs4 import BeautifulSoup
from urllib.parse import urljoin, urlparse
from my_playwright import MyPlaywright


def get_internal_links(base_url: str) -> set[str]:
    """
    递归爬取全站内部链接
    Args:
        base_url: 目标网站根 URL
    Returns:
        visited: 所有发现的内部链接集合
    """
    visited: set[str] = set()  # 已访问的 URL 集合
    page = MyPlaywright(headless=True).page  # 获取 Playwright Page 对象
    target_netloc = urlparse(base_url).netloc  # 提取目标网站的域名

    def _crawl_links(url: str) -> None:
        '''爬取指定 URL 的所有内部链接'''
        print(f"总数:{len(visited)} [+] 正在抓取: {url}...")
        visited.add(url)
        try:
            page.goto(url, wait_until='networkidle', timeout=30000)
            page.wait_for_timeout(500)  # 等待确保页面加载完成
            html = page.content()
            soup = BeautifulSoup(html, 'html.parser')

            for a in soup.find_all('a', href=True):
                href = a['href']
                full_url = urljoin(url, href)
                parsed = urlparse(full_url)

                # 过滤非内部链接
                if not parsed.netloc == target_netloc:
                    continue  # 跳过其他域名的链接
                if '#' in full_url:
                    continue  # 跳过锚点链接
                if parsed.scheme not in ('http', 'https'):
                    continue  # 跳过非 HTTP/HTTPS 链接
                if full_url in visited:
                    continue  # 跳过已访问的链接

                _crawl_links(full_url)  # 递归爬取子链接
        except Exception as e:
            print(f"[!] 请求失败: {url} - {e}")

    _crawl_links(base_url)
    print(f"[✓] 已完成 {len(visited)} 条链接的爬取")
    return visited


def save_to_markdown(links, output_path='internal_links.md'):
    """将链接列表保存为 Markdown 文件,每 10 条为一组"""
    sorted_links = sorted(links)
    chunk_size = 10
    chunks = [sorted_links[i:i + chunk_size] for i in range(0, len(sorted_links), chunk_size)]

    markdown_content = []
    markdown_content.append("# 全站内部链接列表\n")
    markdown_content.append(f"共发现 **{len(links)}** 条链接\n\n")
    markdown_content.append("---\n\n")

    for idx, chunk in enumerate(chunks, 1):
        start_num = (idx - 1) * chunk_size + 1
        markdown_content.append(f"### 第 {start_num}-{start_num + len(chunk) - 1} 条链接\n\n")
        for link in chunk:
            markdown_content.append(f"{link}\n")
        markdown_content.append("\n")

    with open(output_path, 'w', encoding='utf-8') as f:
        f.writelines(markdown_content)
    print(f"[✓] 已保存到: {output_path}")


if __name__ == '__main__':
    base_url = 'https://nicegui.io/'
    links = get_internal_links(base_url)
    save_to_markdown(links)

三、源码解析

🔍 MyPlaywright 封装

这里的 MyPlaywright 是我对 Playwright 的封装,核心特点:

特性说明
永久上下文浏览器状态持久化,只需创建一次
自动资源释放程序退出时自动关闭浏览器
跨平台Windows 显示浏览器,Linux 自动无头
自动下载监听下载事件,自动保存文件

使用方式极其简单:

page = MyPlaywright(headless=True).page
page.goto("https://example.com")

🔍 链接过滤逻辑

# 1. 只爬取同域名的链接
if not parsed.netloc == target_netloc:
    continue

# 2. 跳过锚点链接(如 #section)
if '#' in full_url:
    continue

# 3. 只处理 HTTP/HTTPS 链接
if parsed.scheme not in ('http', 'https'):
    continue

# 4. 已访问过的跳过
if full_url in visited:
    continue

🔍 递归爬取流程

nicegui.io (起始页)
├── /documentation
│   ├── /documentation/button
│   │   └── (发现更多子链接...)
│   ├── /documentation/input
│   └── ...
├── /examples
│   └── ...
└── ...

四、使用效果

以 NiceGUI 官网为例,运行脚本后:

总数:0 [+] 正在抓取: https://nicegui.io/...
总数:1 [+] 正在抓取: https://nicegui.io/documentation...
总数:2 [+] 正在抓取: https://nicegui.io/documentation/button...
...
[✓] 已完成 139 条链接的爬取
[✓] 已保存到: internal_links.md

生成的 Markdown 文件示例:

# 全站内部链接列表
共发现 **139** 条链接

---

### 第 1-10 条链接

https://nicegui.io
https://nicegui.io/documentation
https://nicegui.io/documentation/button
https://nicegui.io/documentation/switch
...

每 10 条链接为一组,方便批量导入到 IMA 等 AI 知识库工具。


五、后续计划

这个工具将被整合到类似于龙虾的Agent中,作为一个自动化子任务:

AI Agent
├── 任务:学习 NiceGUI
│   ├── 子任务:爬取全站链接 → 调用 crawl_internal_links.py
│   ├── 子任务:整理分组格式
│   └── 子任务:导入 AI 知识库
└── ...

目标是实现:一句话,让 AI 自动完成整个学习准备工作


六、总结

📌 要点回顾

  1. Playwright 解决了 JavaScript 动态渲染页面的抓取问题
  2. 递归爬取 确保覆盖全站所有页面
  3. BeautifulSoup 高效解析 HTML 中的链接
  4. Markdown 分组导出 方便批量导入 AI 知识库
  5. 配合 AI 知识库 实现"提问式学习",效率倍增

💡 适用场景

  • 学习新技术框架的官方文档
  • 构建个人技术知识库
  • 批量收集某网站的所有页面

⚠️ 注意事项

  • 如果使用腾讯IMA知识库的话,很多网上资源可能已经有人已经整理过了,只要点击IMA的“发现”按钮,就可以搜索并寻找自己感兴趣的知识库,订阅即可。

七、相关资源


本文为本人原创,首发于掘金。
如果你有任何问题或想法,欢迎在评论区交流!