KDnuggets

How to Build a Simple AI Web Scraper with Python

8.5内容质量

TL;DR · AI 摘要

本文介绍了使用Python构建AI网络爬虫的方法,结合HTML清理、Markdown转换和OpenAI API实现高效问答。

核心要点

  • 使用BeautifulSoup清理HTML噪声元素可减少70%冗余内容
  • markdownify库能将HTML转换为结构化Markdown格式
  • OpenAI API配合特定prompt可实现精准问答而非全量返回

结构提纲

按章节快速跳转。

  1. 说明传统网页抓取的局限性及AI增强方案的优势

  2. 详细列出Jupyter Notebook环境所需依赖库及安装步骤

  3. 演示使用BeautifulSoup移除脚本、注释等非文本元素的方法

  4. 解释markdownify库如何将清理后的HTML转为可读Markdown

  5. 展示ftfy库处理乱码和特殊字符的具体应用场景

  6. 说明如何构造prompt让OpenAI模型返回精准答案而非完整内容

思维导图

用一张图看清主题之间的关系。

查看大纲文本(无障碍 / 无 JS 友好)
  • AI Web Scraper架构
    • 数据获取层
      • requests库
      • BeautifulSoup
    • 数据处理层
      • HTML清洗
      • Markdown转换
      • ftfy文本修复
    • AI交互层
      • OpenAI API
      • 问答prompt工程

金句 / Highlights

值得收藏与分享的关键句。

#Python#Web Scraping#AI#OpenAI#Markdown
打开原文

如何使用 Python 构建一个简单的 AI 网络爬虫 - KDnuggets

publ: 2026年8月14日

  • 博客热门文章
  • 主题 AI 职业建议 计算机视觉 数据工程 数据科学 语言模型 机器学习 MLOps NLP 编程 Python SQL
  • 数据集
  • 活动
  • 资源 快速参考指南 推荐 技术简报
  • 广告

订阅通讯

#header end

/ad_wrapper

如何使用 Python 构建一个简单的 AI 网络爬虫

通过清理 HTML、将内容转换为 Markdown 并返回聚焦答案,将任何网页转换为轻量级的 LLM 驱动问答引擎,同时减少 token 使用量。

作者:

Abid Ali Awan,KDnuggets 助理编辑,2026年8月14日,Python

<div class="addthis_native_toolbox"></div>

网络爬虫是自动从网站收集信息的过程。普通爬虫通常提取原始文本、HTML 元素或完整页面内容。但当你构建 AI 代理或大型语言模型(LLM)应用时,将整个网页发送给模型并不总是最佳选择。

更好的方法是先清理页面,将其转换为 Markdown,然后使用 LLM 理解内容并仅返回用户需要的答案。这使输出更整洁、更易读,并且更容易在其他工作流程中使用。

这也有助于减少 token 使用量。我们不再发送包含导航链接、按钮、脚本、页脚和重复内容的杂乱网页,而是仅将有用的内容发送给模型。LLM 然后以 Markdown 格式返回聚焦答案,而不是将整个页面内容返回给用户。

在本指南中,我们将使用 Jupyter Notebook 在 Python 中构建一个简单的 AI 网络爬虫。它将获取网页、清理 HTML、将其转换为 Markdown、接受用户查询,并根据页面内容返回清晰的 Markdown 答案。

# 环境准备

我们将使用 Jupyter Notebook 进行本项目。它使我们能够先测试每个步骤,然后再将爬虫转换为适当的应用编程接口(API)或应用程序。

首先安装所需的 Python 包:

code
!pip install requests beautifulsoup4 markdownify openai ftfy python-dotenv

我们将使用:

  • requests 用于获取网页。BeautifulSoup 用于去除杂乱的 HTML 元素。markdownify 用于将 HTML 转换为 Markdown。OpenAI 用于回答用户查询。ftfy 用于修复损坏或杂乱的文本。python-dotenv 用于安全加载 API 密钥。

在下一个单元格中,导入所需的库:

code
import os
import re
import requests

from bs4 import BeautifulSoup, Comment
from ftfy import fix_text
from markdownify import markdownify as markdownify_html
from openai import OpenAI
from dotenv import load_dotenv
from IPython.display import Markdown, display

接下来,确保你的 OpenAI API 密钥作为环境变量可用。更安全的方式是在与笔记本相同的文件夹中创建一个 .env 文件,并将密钥添加到其中:

code
OPENAI_API_KEY=your_api_key_here

然后在笔记本中加载它:

code
load_dotenv()

client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))

你也可以检查密钥是否已正确加载:

code
if not os.getenv("OPENAI_API_KEY"):
    raise ValueError("OPENAI_API_KEY is missing. Add it to your .env file first.")

同时确保你的 OpenAI 平台账户已设置计费。对于新的 API 账户,你可能需要先添加预付信用额度才能运行 API 调用。如果账户中没有可用模型,请使用 OpenAI 仪表板中的其他模型。

现在定义模型名称:

code
MODEL_NAME = "gpt-5.4-nano"

我们在这里使用较小的模型,因为此任务不需要大型推理模型。目标很简单:读取清理后的网页内容,理解用户查询,并返回一个聚焦的Markdown答案。

# 获取网页内容

现在我们将创建第一个函数。该函数将使用requests包获取网页并返回原始HTML。

code
def fetch_page(url: str) -> str:
    """
    从网页下载HTML内容。
    """
    headers = {
        "User-Agent": "SimpleAIScraper/1.0"
    }

    response = requests.get(url, headers=headers, timeout=15)
    response.raise_for_status()

    return response.text

User-Agent请求头会告诉网站请求来自我们的爬虫程序。一些网站会阻止没有用户代理的请求,因此添加这个请求头可以让请求更可靠。

我们还使用了超时设置,以避免在网站未响应时无限等待。raise_for_status()调用会在请求失败时停止代码——例如,当页面返回404或500错误时。

现在让我们用真实网站测试这个函数:

code
raw = fetch_page("https://www.olostep.com/")
print(raw[:500])

这将从网页下载原始HTML并打印前500个字符。

原始HTML输出 | 图片由作者提供

在此阶段,输出仍然看起来杂乱,因为它包含完整的页面HTML,包括标签、脚本、布局元素和其他我们不需要的内容。

# 清理HTML

网页的原始HTML通常包含大量我们不需要的内容。它可能包括脚本、样式、导航菜单、按钮、表单、页眉、页脚、弹窗和其他布局元素。

在将页面内容发送给LLM之前,我们需要清理HTML。这有助于减少噪声,使最终的Markdown更容易被模型理解。

我们将使用BeautifulSoup解析HTML并移除不必要的元素。

code
def clean_html(html):
    html = fix_text(html)

    soup = BeautifulSoup(html, "html.parser")

    # 移除明显的噪声标签
    for tag in soup([
        "script", "style", "noscript", "svg", "img", "iframe",
        "nav", "header", "footer", "aside", "form", "button"
    ]):
        tag.decompose()

    noise_words = [
        "cursor",
        "modal",
        "popup",
        "floating",
        "signup",
        "login",
        "cookie",
        "banner",
        "navbar",
        "menu",
        "footer",
        "header",
        "subscribe",
        "newsletter",
        "loading",
        "wait",
        "success",
        "auth",
        "w-nav",
        "w-form"
    ]

    # 首先收集噪声标签
    tags_to_remove = []

    for tag in soup.find_all(True):
        if tag.attrs is None:
            continue

        class_value = tag.get("class", [])
        id_value = tag.get("id", "")

        if isinstance(class_value, list):
            class_text = " ".join(class_value).lower()
        else:
            class_text = str(class_value).lower()

        id_text = str(id_value).lower()

        if any(word in class_text or word in id_text for word in noise_words):
            tags_to_remove.append(tag)

    # 然后安全地移除它们
    for tag in tags_to_remove:
        tag.decompose()

    body = soup.body if soup.body else soup

    return str(body)

首先,我们使用 fix_text() 来清理任何损坏或奇怪的文本编码问题。然后使用 BeautifulSoup 解析 HTML,这样我们可以删除不需要的部分。

我们移除明显冗余的标签,如 script、style、nav、header、footer、form 和 button。这些部分通常无法帮助回答用户查询,反而会浪费 token。

接下来,我们查找冗余的类名和 ID。许多网站会在 HTML 中使用 popup、cookie、navbar、newsletter 或 modal 等词语。如果某个标签包含这些词语,我们会安全地收集并删除它。

现在让我们在原始 HTML 上运行该函数:

code
clean = clean_html(raw)
print(clean[:500])

如你所见,网页现在变得干净得多。它仍然包含有用的 HTML 标签和文本,但大部分冗余的布局、脚本、导航和弹窗已被删除。

清理后的 HTML 输出 | 图片由作者提供

# 将 HTML 转换为 Markdown

现在我们将清理后的 HTML 转换为 Markdown。与原始 HTML 相比,Markdown 更易于阅读、保存,并且更容易被 LLM 理解。

这一步也有助于减少输入 token,因为我们移除了不必要的格式、图片、空行和重复文本。为了转换,我们将使用 markdownify。

code
def html_to_markdown(html):
    markdown_text = markdownify_html(
        html,
        heading_style="ATX",
        bullets="-"
    )

    markdown_text = fix_text(markdown_text)

    # 移除图片 Markdown
    markdown_text = re.sub(r"!\[.*?\]\(.*?\)", "", markdown_text)

    # 移除多余空格和空行
    markdown_text = re.sub(r"[ \t]+", " ", markdown_text)
    markdown_text = re.sub(r"\n{3,}", "\n\n", markdown_text)

    lines = []

    skip_lines = [
        "click to try",
        "wait. ..",
        "you've successfully reserved your spot.",
        "thank you! your submission has been received!",
        "oops! something went wrong while submitting the form.",
        "product",
        "resources",
        "company"
    ]

    for line in markdown_text.splitlines():
        line = line.strip()

        if not line:
            continue

        if line.lower() in skip_lines:
            continue

        lines.append(line)

    return "\n".join(lines)

首先,我们使用 markdownify 将清理后的 HTML 转换为 Markdown。我们将标题样式设置为 ATX,这意味着标题将使用标准 Markdown 语法(#、##、###)。

然后我们再次运行 fix_text() 来清理任何剩余的编码问题。之后,我们移除图片 Markdown,因为图片链接通常对回答基于文本的问题没有帮助。

我们还移除多余空格和空行,使最终内容更加紧凑。这使页面更易于检查,并有助于减少发送给模型的 token 数量。

skip_lines 列表会移除重复的网站文本,如表单消息、导航标签和小的行动号召文本。你可以根据抓取的网站更新这个列表。

现在让我们运行该函数:

code
md = html_to_markdown(clean)
print(md[:500])

如你所见,文本现在更加干净,更接近我们想要的格式。我们不再有原始 HTML,而是有了可读的 Markdown,包含有用的标题、段落和项目符号。

Markdown 输出 | 图片由作者提供

# 对页面提出用户查询

现在我们将创建一个函数,将清理后的 Markdown 内容发送给 LLM。这个函数接受两个输入:Markdown 格式的网页内容和用户查询。

我们不再要求模型总结整页内容,而是让它仅使用页面内容来回答特定问题。这使响应更加聚焦且实用。

code
def answer_query_from_page(markdown_text, user_query):
    prompt = f"""
你是一个AI网络爬虫助手。

你将收到从网页中提取的Markdown内容。

你的任务是仅使用页面中的有用内容来回答用户的问题。

用户问题:
{user_query}

网页Markdown内容:
{markdown_text}

指令:
- 仅返回干净的Markdown格式
- 仅使用网页Markdown中的信息
- 不要编造缺失的细节
- 忽略导航链接、按钮、CTA、弹窗、装饰性标签、图片说明和重复的营销片段
- 忽略"Start for free"、"Contact Sales"、"Your AI Agent"等装饰性工作流程示例,除非它们直接回答问题
- 聚焦于标题、段落、产品描述、功能模块、定价详情、文档文本和事实声明
- 如果页面中没有答案,请说明:"The page does not contain this information."
- 保持回答简短、清晰且聚焦
"""

    response = client.responses.create(
        model=MODEL_NAME,
        input=prompt
    )

    return response.output_text

提示词是这个步骤中最重要的部分。它告诉模型应该扮演什么角色、可以使用什么内容以及应该返回什么类型的答案。

我们还要求模型仅使用提供的Markdown内容。这一点很重要,因为我们不希望模型猜测或添加网页上不存在的信息。

要求仅返回干净的Markdown格式,使输出更易于在笔记本中显示、保存到文件或传递到其他AI工作流中。

这个函数使AI网络爬虫真正具备实用性。我们现在不再只是提取页面文本——我们是在要求大语言模型理解清理后的页面内容,并返回用户正在寻找的确切答案。

# 创建完整的AI网络爬虫

现在我们将创建最终的函数来连接所有组件。

这个函数将接收URL和用户查询作为输入。然后它将获取网页内容、清理HTML、将内容转换为Markdown,并使用gpt-5.4-nano模型返回答案。

code
def ai_web_scraper(url, user_query):
    raw_html = fetch_page(url)
    cleaned_html = clean_html(raw_html)
    markdown_text = html_to_markdown(cleaned_html)
    answer = answer_query_from_page(markdown_text, user_query)

    return answer

这就是我们的完整AI网络爬虫流水线。现在我们不再需要手动逐个运行每个步骤,而是可以通过调用单个函数从任何网页获取干净的Markdown格式答案。

流程非常简单:

  • 获取网页内容。清理HTML。转换为Markdown。向大语言模型提问。返回最终答案。

这使代码保持简洁且易于后续在API、聊天机器人或代理工作流中复用。

# 测试AI网络爬虫

现在让我们测试我们的AI网络爬虫。我们将提供一个网站URL并询问公司是做什么的。

code
url = "https://www.olostep.com/"
user_query = "What does this company do?"
result = ai_web_scraper(url, user_query)

display(Markdown(result))

作为回报,我们得到了一份关于公司及其产品的规范 Markdown 响应。这比返回完整网页内容要好得多,因为答案更加聚焦、可读性强,并且与用户查询直接相关。

抓取器输出:公司概况查询 | 作者图片

现在让我们尝试访问不同页面并询问定价信息。

code
url = "https://www.olostep.com/pricing"
user_query = "Help me understand the pricing"
result = ai_web_scraper(url, user_query)

display(Markdown(result))

几秒钟后,我们得到了一个清晰易懂的响应。无需手动访问定价页面并尝试查找相关信息,抓取器会提取页面内容、进行清理,并要求 LLM 仅解释关键信息。

抓取器输出:定价查询 | 作者图片

我们还可以将最终响应保存为 Markdown 文件。

code
with open("ai_scraper_result.md", "w", encoding="utf-8") as file:
    file.write(result)

print("Markdown saved to ai_scraper_result.md")

输出:

code
Markdown saved to ai_scraper_result.md

现在结果已保存为 Markdown 文件,您可以打开、编辑、分享或在其他工作流程中使用。

最后思考

如今构建自己的 AI 工具变得简单得多。只需几行 Python 代码和一个 LLM,我们就能将普通网页转换为简单的问答引擎,该引擎可以读取页面内容、理解用户查询并返回清晰的 Markdown 答案。

这非常强大,因为您并不总是需要复杂系统来解决特定问题。有时,一个小型专用解决方案就足够了。

但也要记住,一切都有成本。在服务器上运行应用程序会产生费用。调用 LLM 会产生费用。维护抓取器、修复损坏的页面、处理错误以及随时间改进系统也需要时间和金钱。

因此,在构建自己的定制解决方案之前,值得查看现有工具,如 Olostep、Firecrawl 或 Exa。在某些情况下,付费使用现成的抓取或网络情报 API 可能更有意义。在其他情况下——特别是当任务很小、本地化或非常具体时——构建自己的轻量级解决方案可能是更好的选择。

Abid Ali Awan(@1abidaliawan)是一名认证的数据科学家,热爱构建机器学习模型。目前,他专注于内容创作和撰写关于机器学习和数据科学技术的博客文章。Abid 拥有技术管理硕士学位和电信工程学士学位。他的愿景是使用图神经网络为有心理困扰的学生构建 AI 产品。

更多相关内容

  • 使用 Python 和 Docker 构建自己的简单数据管道
  • 从零开始构建简单 RAG 系统的 7 个步骤
  • 10 个用于 Python 网络开发的 GitHub 仓库
  • 使用 Reflex 构建纯 Python Web 应用
  • 数据科学家的 7 个 Python Web 开发框架
  • 2026 年 7 个最佳网络爬虫工具和 API

<hr class="grey-line"><br> <div><h3>我们推荐的 5 门免费课程</h3><br> </div>

Mailchimp for WordPress v4.14.0 - https://wordpress.org/plugins/mailchimp-for-wp/

/ Mailchimp for WordPress 插件

您可以从这里开始编辑。

如果评论已关闭。

<= 上一篇

#content end

<script type="text/javascript">kda_sid_write(kda_sid_n);</script>

最新文章

/

  • 如何使用 Python 构建一个简单的 AI 网络爬虫 5 个有趣的智能体 AI 论文推荐 构建流式本地 AI 代理 为 SLM 狭窄自动化优化输出空间 构建端到端的数据科学作品集项目 5 种在 Windows 上安装 Python 的简便方法

热门文章

  • 规范工程:提示工程之后的新技能
  • 如何使用 Python 构建一个简单的 AI 网络爬虫
  • 5 个有趣的智能体 AI 论文推荐
  • 构建端到端的数据科学作品集项目
  • 5 门免费课程学习现代 AI 和大语言模型
  • 构建流式本地 AI 代理
  • 参与开源项目的终极指南
  • 3 个直观理解中心极限定理的可视化证明
  • 5 种在 Windows 上安装 Python 的简便方法
  • 2026 年最小 AI 工程师工具包

#content_wrapper end

© 2026

Guiding Tech Media

|

关于

联系我们

广告合作

隐私政策

服务条款

2026年8月14日由 blank 发布

No, thanks!

/.main_wrapper

<script defer type="text/javascript" src="https://s7.addthis.com/js/300/addthis_widget.js#pubid=gpsaddthis"></script>

noptimize

/noptimize