在开放的互联网上,不断有海量数据被生成。产品价格会发生变化,招聘信息会被发布或删除,新闻文章会被发表,公司信息也会得到更新。

对于那些依赖这类数据的开发人员和团队来说,他们面临的问题从来不是是否要从网络上抓取数据,而是如何能够持续、可靠地完成这一工作。

长期以来,人们采用的方法一直很直接:先检查目标网页,编写相应的选择器,然后使用像BeautifulSoup这样的工具或PlaywrightSelenium这样的浏览器自动化库来提取数据。这种方法效果不错,但也存在一个常见的问题:一旦网页的结构发生变化,抓取脚本就会失效,需要重新进行修改。

最近,另一种方法开始受到人们的关注。这种方法不再需要编写选择器,而是直接描述所需获取的数据内容,让系统自己去判断如何提取这些数据。人们把这种方法称为“人工智能抓取”。

如今,这两种方法都被广泛使用,但它们解决问题的方式截然不同。本指南将详细解释每种方法的运作原理、适用场景,以及如何根据具体需求来选择合适的方法。

目录

什么是传统网页抓取?

传统网页抓取这种技术基于一个简单的理念:如果浏览器能够加载某个网页并向用户显示其中的数据,那么程序也应该能够做到这一点,并自动提取这些数据。

这一过程是通过CSS选择器和XPath来实现的。对于CSS选择器来说,像.product-card .price这样的选择器意味着“在产品卡片元素中查找价格信息”。这种表示方法很容易理解,在大多数情况下也能很好地发挥作用。

而XPath则功能更加强大,但使用起来也更为复杂。它允许人们更加详细地导航网页的结构,包括在DOM树中上下移动、根据文本内容进行筛选,以及处理深度嵌套的元素。

在实际开发中,大多数开发者会先从使用CSS选择器开始,只有当网页结构过于复杂时,才会考虑使用XPath。

这种思路其实可以追溯到互联网发展的早期。那时,开发者们不再需要手动从网页上复制信息,而是开始编写脚本,通过这些脚本来发送请求、接收HTML响应,并提取所需的数据。

从根本上说,这种方法的本质并没有发生任何变化。

你仍然需要获取页面内容、分析其结构,并从中提取数据。如今的不同之处不在于方法本身,而在于所使用的工具已经变得多么先进,以及抓取操作的规模已经扩大到何种程度。

传统抓取技术所依赖的工具

随着时间的推移,围绕这种抓取方式逐渐形成了一套完善的工具生态系统。

  • Requests是Python中用于发起HTTP请求的常用库。大多数传统抓取工具都会使用requests来获取页面内容,然后再将响应结果传递给BeautifulSoup进行解析。对于静态网站来说,这种方法是简单且可靠的。

  • BeautifulSoup是一个用于解析HTML和XML的Python库。它能够将原始HTML代码转换成结构清晰的对象树,易于理解和使用,特别适合处理静态页面。不过它的最大局限性在于没有内置浏览器引擎,因此无法执行JavaScript脚本;如果某个网站在页面加载后动态生成内容,BeautifulSoup就会无法获取这些信息。

  • SeleniumPlaywright是用于控制真实浏览器的自动化工具。它们可以点击按钮、滚动页面,并等待JavaScript脚本完成执行后再提取数据。不过,与简单的HTTP请求相比,这些工具的执行速度较慢,且对系统资源的需求也更高,但对于处理动态网站来说却是必不可少的。

实际应用中的传统抓取技术

让我们使用专门为练习网络爬虫而设计的Books to Scrape这个沙盒网站,来构建一个能够正常运行的抓取工具。我们的目标是从首页上列出的每一本书中提取书名、价格和星级评价等信息。

步骤1:安装所需依赖库

pip install requests beautifulsoup4

步骤2:分析页面结构

在编写任何代码之前,先在浏览器中打开目标网站,然后分析其HTML结构。右键点击任意一本书的标题,选择“检查”选项就能看到该页面的具体结构。

分析页面结构

你会发现,每本书的信息都被包含在

这个元素中,而在这个元素内部,具体信息又分布在以下这些位置:

这就是传统爬虫技术中的核心工作:你需要分析HTML代码,找出其中的规律,并编写相应的选择器来匹配这些规律。

步骤3:编写爬虫程序

import requests
from bs4 import BeautifulSoup

# 1. 获取页面内容
url = "https://books.toscrape.com/"
response = requests.get(url)

# 在继续下一步之前,务必检查请求是否成功
if response.status_code != 200:
    print(f"无法获取页面内容:{response.status_code}")
    exit()

# 2. 解析HTML代码
soup = BeautifulSoup(response.content, "html.parser")

# 3. 找出页面上所有的书籍信息
books = soup.select("article.product_pod")

# 4. 从每本书中提取数据
results = []

for book in books:
    # 书名存储在属性中,而不是可见文本
    title = book.select_one("h3 a")["title"]

    # 价格是price元素中的文本内容
    price = book.select_one("p.price_color").get_text.strip()

    # 评分是通过CSS类来表示的,例如“star-rating Three”
    # 我们提取第二个类名并将其转换为数字
    rating_word = book.select_one("p.star-rating")["class"][1]
    rating_map = {"One": 1, "Two": 2, "Three": 3, "Four": 4, "Five": 5}
    rating = rating_map.get(rating_word, 0)

    results.append({
        "title": title,
        "price": price,
        "rating": rating
    })

# 5. 显示结果
for book in results:
    print(f"{book['title']} | {book['price']} | {book['rating']}星"

步骤4:运行程序

python scraper.py

你的输出结果会如下所示:

《阁楼里的光》 | £51.77 | 3星
《轻抚天鹅绒》 | £53.74 | 1星
《屈服》 | £50.10 | 1星
《锋利的物体》 | £47.82 | 4星
《人类简史》 | £54.23 | 5星
...

二十本书的信息都被整齐地提取出来了。

步骤5:扩展程序以爬取多页内容

这个网站共有50页。要想让爬虫程序能够访问所有这些页面,就需要跟踪页面上的“next”按钮:

import requests
from bs4 import BeautifulSoup

BASE_URL = "https://books.toscrape.com/catalogue/"
start_url = "https://books.toscrape.com/catalogue/page-1.html"

all_books = []
url = start_url

while url:
    response = requests.get(url)
    soup = BeautifulSoup(response.content, "html.parser")

    for book in soup.select("article.product_pod"):
        title = book.select_one("h3 a")["title"]
        price = book.select_one("p.price_color").get_text.strip()
        rating_word = book.select_one("p.star-rating")["class"][1]
        rating_map = {"One": 1, "Two": 2, "Three": 3, "Four": 4, "Five": 5}
        rating = rating_map.get(rating_word, 0)
        all_books.append({"title": title, "price": price, "rating": rating})

    # 查找“next”按钮并点击它
    next_btn = soup.select_one("li.next a")
    url = BASE_URL + next_btn["href"] if next_btn else None

print(f"共爬取了{len(all_books)}本书的信息。")

运行这个脚本会遍历所有50页中的1,000本书籍。

这种方法的脆弱性在于……

目前,这个抓取工具能够正常工作,是因为books.toscrape.com是一个静态且稳定的测试环境。但在实际生产环境中,这种方法存在一个明显的缺陷:它完全依赖于HTML结构的稳定性。

如果网站开发者将product_pod改名为book-card,或者将价格信息放在

标签中而不是

标签中,那么所有的选择器都会失效。这样一来,你将无法获取任何数据,甚至可能会得到错误的数据,而这种问题只有在有人发现输出结果异常时才会被察觉。

而这正是人工智能抓取技术旨在解决的问题之一。

什么是人工智能网页抓取?

传统的抓取方法是通过分析页面的结构来工作的。它会寻找HTML中的特定元素、类名或模式,并根据这些规则提取数据。

而基于人工智能的抓取技术则采用了不同的方式。它并不只依赖页面结构,而是致力于理解页面的内容本身。它会判断某个元素代表什么意义,而不仅仅是它的位置。

在传统的抓取工具中,你可能会编写这样的代码:

response.css(".product-card .price::text").get()

你是在告诉系统具体该在哪里查找数据。但使用人工智能抓取技术时,你只需要描述想要得到的结果:

提取此页面上每件商品的商品名称、价格和库存情况。

系统会读取页面内容,识别出哪些部分属于产品信息,然后提取相关数据并返回结构化结果。

底层究竟发生了什么?

乍一看,人工智能抓取技术似乎像是一种魔法,但实际上它是建立在一些常见的技术组件之上的。

其核心是大型语言模型,这些模型经过大量文本数据的训练,包括网页内容和HTML代码。通过学习,它们能够识别出产品列表的格式、价格信息的呈现方式以及招聘信息的结构等等。

当给定一个页面时,这些模型就能识别出其中的模式,并将它们转换成你所需要的数据结构。

不过,模型只是整个系统的一部分。你还需要其他组件来加载并操作网页内容。这时浏览器自动化技术就派上了用场。大多数人工智能抓取工具都会使用Chromium这样的无头浏览器,或者Playwright这样的框架来渲染页面、执行JavaScript代码,并模拟用户的点击或滚动等操作。

除此之外,还有一层机制负责解析你的输入指令。当你编写一个描述所需数据的提示语时,系统会将其转化为具体的抓取任务,从而决定哪些页面内容是相关的,以及应该如何组织输出结果。

最后,系统会将提取到的结果整理成结构清晰的数据格式,通常是JSON或CSV格式,这样你就可以直接使用这些数据,而几乎不需要进行后续处理。

注意:像ChatGPT这样的工具虽然能够理解文本内容,但它们并不是用于抓取数据的工具。它们不会爬取网页、处理工作流程,也不会执行重复性的数据提取操作。人工智能抓取工具将这种智能功能与收集数据所需的基础设施结合在一起,从而实现了高效的数据采集。

随着人工智能抓取技术越来越受欢迎,出现了许多能够帮助人们轻松使用这一技术的工具,人们无需从头开始构建所有相关系统即可开展抓取工作。

例如:

实际上,这些工具所解决的具体问题并不完全相同。有些工具专注于提取结构化数据,有些则侧重于清理文本内容,还有些工具用于构建完整的抓取工作流程。选择合适的工具取决于你想要实现的目标,而不仅仅是工具本身具备的功能。

人工智能抓取在实践中的应用

让我们使用一个人工智能爬取工具,执行同样的数据收集任务,从books.toscrape.com中提取书籍信息。我们将使用Spidra的API,这样你们就能清楚地看到其中发生了哪些变化。

步骤1:获取API密钥

请在spidra.io注册账号,然后从控制面板中生成一个API密钥。后续的所有请求都需要使用这个密钥来进行身份验证。

获取Spidra API密钥

步骤2:了解API结构

Spidra的爬取接口接受JSON格式的数据。其中两个最重要的字段是url(需要爬取的网址)和prompt(需要提取的信息,需用简单的英语表述)。你还可以选择指定output格式——对于结构化数据来说,JSON格式最为适用。

POST https://api.spidra.io/scrape
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json

如你所见,我们根本不需要使用任何选择器或进行HTML结构分析,只需要提供一个URL和相应的提取要求即可。

步骤3:编写单页数据提取代码

以下是我们传统爬虫程序的等效版本,它是通过API调用来实现的:

import requests
import json

API_KEY = "your_api_key_here"

payload = {
    "urls": [{"url": "https://books.toscrape.com/"}],
    "prompt": "提取该页面上的所有书籍信息。对于每本书,需要返回书名、价格以及星级评分(评分范围为1到5)。",
    "output": "json"
}

response = requests.post(
    "https://api.spidra.io/scrape",
    headers={
        "Authorization": f"Bearer {API_KEY}",
        "Content-Type": "application/json"
    },
    json=payload
)

data = response.json()
print(json.dumps(data, indent=2))

这就是整个爬取程序的代码。其中没有使用BeautifulSoup,也没有任何选择器逻辑或HTML解析过程。

步骤4:理解输出结果

API会返回一个结构化的JSON响应。每本书的信息都会以对象的形式呈现出来,其中包含你之前指定的各个字段:

{
  "results": [
    {
      "title": "阁楼里的光",
      "price": "£51.77",
      "rating": 3
    },
    {
      "title": "轻触天鹅绒",
      "price": "£53.74",
      "rating": 1
    },
    {
      "title": "屈服",
      "price": "£50.10",
      "rating": 1
    }
    ...
  ]
}

该系统能够自动识别星级评分的编码规则(例如star-rating Three表示3分),而无需我们事先指定评分的具体表示方式。它完全理解了“星级评分应为1到5之间的数字”这一要求,并自行完成了相应的转换工作。

步骤5:在多步骤工作流程中使用Actions功能

当涉及到那些在传统爬虫中需要耗费大量开发工作的工作流程时,人工智能爬取技术才能真正发挥其优势。

假设你想访问每本书的详细页面,并提取其中的所有描述信息以及图书的可用状态(而不仅仅是列表页面上显示的内容)。
在传统的爬虫系统中,这意味着你需要构建一个循环来遍历这些页面,管理状态信息,在每个详细页面上处理可能出现的错误,同时为页面不同的结构设计专门的选取器。而在像Spidra这样的人工智能爬虫工具中,你可以通过浏览器操作来模拟人类的交互行为:

{
  "urls": [
    {
      "url": "https://books.toscrape.com/catalogue/category/books/mystery_3/index.html",
      "actions": [
        {
          "type": "forEach",
          "observe": "查找产品列表中的所有图书卡片",
          "mode": "inline",
          "captureSelector": "article.product_pod",
          "maxItems": 10,
          "itemPrompt": "提取图书的标题、价格和星级评价(一/二/三/四/五),并以JSON格式返回:{title, price, star_rating}"
        }
      ]
    }
  ]
}

该系统会自动导航到每本书的页面,读取新内容,提取所需的字段,并将所有结果整合到同一个结果集中。
你还可以根据自己的需求配置数据提取的方式:

{
  "urls": ["https://jobs.example.com/senior-engineer"],
  "prompt": "提取职位详情",
  "schema": {
    "type": "object",
    "required": ["title", "company", "remote", "employment_type"],
    "properties": {
      "title": { "type": "string" },
      "company": { "type": "string" },
      "location": { "type": ["string", "null"] },
      "remote": { "type": ["boolean", "null"] },
      "salary_min": { "type": ["number", "null"] },
      "salary_max": { "type": ["number", "null"] },
      "employment_type": {
        "type": ["string", "null"],
        "enum": ["full_time", "part_time", "contract", null]
      },
      "skills": {
        "type": "array",
        "items": { "type": "string" }
      }
    }
  }
}

这些人工智能爬虫工具还有许多其他功能,比如批量爬取、人工智能检索等等。

人工智能爬取技术为何能发挥作用

现在假设某个网站的界面进行了更新:product_pod这个类被改名为book-card,价格信息也被放置到了另一个元素中。
在传统的爬虫系统中,你可能一开始会得到零条结果,也不会有任何错误提示,直到你发现数据缺失了才会发现问题。这时你需要重新检查页面内容,更新选取器,进行测试,然后再重新部署爬虫程序。
而在人工智能爬虫工具中,你只需要再次运行相同的指令即可。因为该模型并不会去寻找product_podprice_color这些具体的元素,而是会自动识别那些包含产品信息及价格的数据。因此,页面布局的变更对数据提取过程完全没有影响。

这就是人工智能方法所具备的核心优势:页面结构的任何变化都不会自动影响数据提取过程。

传统爬取与人工智能爬取:何时使用哪种方法

目前,这两种方法之间的区别已经非常明显了。更重要的是,在实际应用中,究竟在什么情况下使用哪种方法才最为合适。

一个简单的理解方式是如下所示:

应用场景 传统爬取 人工智能爬取
稳定性较高的网站 ✅ 最佳选择 ✅ 可以使用,但有时可能会显得过于繁琐
布局经常变化的网站 ❌ 容易出现提取错误 ✅ 适应能力更强
大规模爬取任务 ✅ 更具成本效益 ✅ 效率较高,但成本也可能随之增加
快速原型开发 ❌ 设置过程较慢 ✅ 非常快捷
非技术用户 ❌ 需要编程技能 ✅ 更容易上手使用
需要完全控制且追求透明度 ✅ 控制能力较强 ❌ 透明度较低
数据结构混乱或不一致 ❌ 难以维护 ✅ 更容易处理
涉及复杂操作流程(如登录、多步骤操作) ⚠️ 可以实现,但需要手动操作 ✅ 通常这些功能都是内置的

在实际应用中,这两种方法并不是非此即彼的选择。当所有内容都具备可预测性且稳定性较高时,传统爬取方法是最佳选择;而当数据结构混乱、动态变化或具有时间敏感性时,人工智能爬取方法就会显得更加有用。大多数现实世界中的系统都会结合使用这两种方法,而不是仅依赖其中一种。

总结

网络爬取技术并不会消失,真正发生变化的是我们使用这些技术的方式。

传统爬取方法能够提供较高的控制能力和精确性,但维护起来可能较为繁琐且耗时;而人工智能爬取方法则能让操作过程变得更快速、更灵活,尤其是在处理数据结构混乱或经常变化的网站时。不过,人工智能爬取方法的透明度相对较低。

在实际应用中,大多数系统已经开始结合使用这两种方法。

我们还可以看到,越来越多的人工智能爬取工具被集成到更大的系统中,尤其是与人工智能助手或MCP架构相结合时,爬取任务就可以根据需求随时触发,而无需每次都从头开始进行设置。

关键在于明白:传统爬取方法是告诉系统数据位于何处,而人工智能爬取方法则是告诉系统数据的含义是什么。真正重要的是要知道在什么情况下使用哪种方法才最为合适。

Comments are closed.