网络爬虫的工作原理

网络爬虫(也叫网页蜘蛛、网络机器人)是一种自动化程序 ,核心目标是按照既定规则,从互联网上抓取并解析网页数据。小到搜索引擎的海量数据索引,大到电商平台的商品信息采集,都依赖爬虫技术实现。

其工作流程可以拆解为 5 个核心步骤,从 "发起请求" 到 "数据存储" 形成完整闭环,下面逐一详细讲解。

一、核心工作流程

1. 种子 URL 准备(爬虫的起点)

爬虫的一切工作都从 种子 URL 开始,这是人工或程序预先设定的初始网页地址。

  • 来源 :可以是单个 URL(如 https://www.example.com),也可以是一批 URL 列表(如搜索引擎的待爬取站点清单);
  • 作用:爬虫从种子 URL 出发,先抓取这个页面,再从页面中发现新的 URL,不断扩展爬取范围(类似 "滚雪球")。

示例 :要爬取某电商的手机商品数据,种子 URL 可以设为 https://www.shop.com/mobile(手机分类页)。

2. 发送 HTTP 请求(获取网页原始数据)

这一步是爬虫与目标网站的核心交互环节,本质是模拟浏览器的行为,向目标服务器发送请求,获取网页内容。

(1)核心原理
  • 爬虫通过编程语言的网络库(如 Python 的requestsurllib)构建 HTTP 请求,携带必要的请求头(User-AgentReferer等);
  • 服务器接收请求后,验证请求合法性(如是否为正常浏览器请求),返回对应的HTML 网页源码(这是最常见的目标数据,也可能是 JSON、XML 等格式)。
(2)关键细节:模拟浏览器,避免被识别

服务器会通过请求头判断访问者身份,若直接发送请求,很容易被判定为爬虫而被拦截。因此爬虫需要伪装成普通浏览器

python 复制代码
# Python 模拟浏览器请求示例
import requests

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
    "Referer": "https://www.shop.com/"  # 模拟从首页跳转
}
response = requests.get(url="https://www.shop.com/mobile", headers=headers)
html = response.text  # 获取网页HTML源码
  • User-Agent:核心标识,告诉服务器 "我是 Chrome 浏览器";
  • Referer:告诉服务器 "我是从哪个页面跳过来的",增加请求的真实性。
(3)请求类型
  • GET 请求:最常用,用于获取网页内容(如商品列表、文章详情);
  • POST 请求:用于需要提交数据的场景(如爬取需要登录的页面,需携带账号密码参数)。

3. 解析网页内容(提取目标数据)

服务器返回的 HTML 源码是杂乱的字符串 ,包含大量无关标签(如<div><style>),爬虫需要通过解析,提取出有价值的数据(如商品名称、价格、链接)。

解析方式分为 3 类,从易到难、从简单到复杂依次为:

解析方式 核心原理 适用场景 优缺点
正则表达式 通过匹配字符串的特定模式(如\d+\.\d+匹配价格)提取数据 简单场景(如提取单个字段) 优点:灵活;缺点:复杂网页易出错,维护成本高
XPath 基于 XML/HTML 的树形结构,通过路径表达式定位元素(如//div[@class="price"]/text() 结构化网页 优点:语法简洁,定位精准;缺点:依赖网页结构
CSS 选择器 模拟 CSS 选择元素的方式(如div.price),通过库(如 Python 的BeautifulSoup)提取数据 大多数网页 优点:语法通俗易懂,兼容性好;缺点:复杂嵌套需多层匹配
实际示例(Python + BeautifulSoup 解析商品数据)

假设网页中商品价格的 HTML 结构如下:

html 复制代码
<div class="product-item">
    <h3 class="name">小米14 Pro</h3>
    <span class="price">4999元</span>
    <a href="/mobile/1001" class="link">查看详情</a>
</div>

爬虫解析代码:

python 复制代码
from bs4 import BeautifulSoup

soup = BeautifulSoup(html, "html.parser")  # 初始化解析器
# 提取所有商品项
products = soup.find_all("div", class_="product-item")
for p in products:
    name = p.find("h3", class_="name").text  # 商品名称
    price = p.find("span", class_="price").text  # 商品价格
    link = p.find("a", class_="link")["href"]  # 商品链接
    print(f"名称:{name},价格:{price},链接:{link}")

解析结果:

复制代码
名称:小米14 Pro,价格:4999元,链接:/mobile/1001
补充:解析动态渲染的网页

很多现代网页(如 Vue、React 开发的页面)使用 JavaScript 动态渲染数据 ------ 直接爬取的 HTML 源码中没有目标数据(只有 JS 代码)。此时需要使用 无头浏览器(如 Selenium、Playwright)模拟浏览器加载页面,等待 JS 执行完成后再解析:

python 复制代码
from selenium import webdriver
from selenium.webdriver.common.by import By

# 初始化无头Chrome浏览器
options = webdriver.ChromeOptions()
options.add_argument("--headless=new")  # 无界面模式
driver = webdriver.Chrome(options=options)

driver.get("https://www.shop.com/mobile")
# 等待页面加载完成,提取价格
price = driver.find_element(By.CLASS_NAME, "price").text
print(price)
driver.quit()

4. URL 去重与调度(避免重复爬取,提高效率)

爬虫从已爬页面中解析出大量新 URL,若直接全部爬取,会出现 重复爬取 (同一 URL 多次请求)和 无效爬取(如爬取无关页面)的问题,因此需要两个核心机制:

(1)URL 去重

通过去重容器存储已爬取或待爬取的 URL,确保每个 URL 只被处理一次。常见的去重方案:

  • 内存集合(Set) :适合小型爬虫,将 URL 存入set,利用集合 "元素唯一" 的特性去重;
  • 布隆过滤器(Bloom Filter):适合海量 URL 场景(如搜索引擎爬虫),占用内存小,查询效率高,允许极小的误判率;
  • 数据库存储:将 URL 存入 MySQL、Redis 等数据库,通过主键或索引去重。
(2)URL 调度

爬虫的任务队列 会管理待爬取的 URL,调度器按照一定规则(如广度优先、深度优先)决定下一个要爬取的 URL:

  • 广度优先(BFS):先爬取当前页面的所有子 URL,再爬取子 URL 的子 URL------ 适合爬取全站数据(如电商分类页→商品列表页→商品详情页);
  • 深度优先(DFS):先爬取一个 URL 的所有层级页面,再返回爬取下一个 URL------ 适合爬取特定深度的页面(如只爬取商品详情页)。

5. 数据存储(持久化爬取结果)

解析出的目标数据需要持久化存储,方便后续分析、使用。常见的存储方式分为 3 类:

存储方式 适用场景 优缺点
文本文件(TXT/CSV/JSON) 小型数据、临时存储 优点:操作简单,无需数据库;缺点:不支持复杂查询
关系型数据库(MySQL/PostgreSQL) 结构化数据、需要复杂查询 优点:支持 SQL 查询,数据完整性高;缺点:配置稍复杂
非关系型数据库(MongoDB/Redis) 非结构化 / 半结构化数据、高并发写入 优点:写入速度快,适合海量数据;缺点:查询功能不如关系型数据库
示例:将商品数据存入 CSV 文件
python 复制代码
import csv

# 写入CSV文件
with open("products.csv", "w", encoding="utf-8", newline="") as f:
    writer = csv.writer(f)
    writer.writerow(["商品名称", "价格", "链接"])  # 表头
    for p in products:
        name = p.find("h3", class_="name").text
        price = p.find("span", class_="price").text
        link = p.find("a", class_="link")["href"]
        writer.writerow([name, price, link])

二、爬虫的关键策略(反反爬 + 效率优化)

目标网站会通过各种手段反爬(如限制访问频率、验证人机身份),因此爬虫需要针对性优化,实现 "友好爬取"。

1. 控制爬取频率

  • 设置请求间隔 :在两次请求之间加入延迟(如time.sleep(1)),避免短时间内大量请求压垮服务器;
  • 模拟随机间隔 :使用随机延迟(如time.sleep(random.uniform(1, 3))),更接近人类浏览行为。

2. 使用代理 IP 池

网站会通过IP 地址识别爬虫(单个 IP 频繁请求会被封禁)。爬虫可以搭建代理 IP 池,每次请求切换不同的 IP:

python 复制代码
proxies = {
    "http": "http://123.123.123.123:8080",
    "https": "https://123.123.123.123:8080"
}
response = requests.get(url, headers=headers, proxies=proxies)

部分页面需要登录后才能访问,爬虫可以通过以下方式处理:

  • 手动登录后,复制浏览器的 Cookie 到请求头;
  • 使用 Selenium 模拟登录流程,保存登录状态的 Cookie。

4. 遵守 robots 协议

robots.txt是网站根目录下的一个文本文件,用于告知爬虫哪些页面可以爬取,哪些禁止爬取 (如搜索引擎爬虫会遵守,恶意爬虫可能忽略)。例如,https://www.example.com/robots.txt 的内容可能为:

复制代码
User-agent: *  # 所有爬虫
Disallow: /admin/  # 禁止爬取/admin目录
Allow: /public/  # 允许爬取/public目录

三、爬虫的分类(按应用场景)

根据爬取范围和目标的不同,爬虫可分为 3 类:

  1. 通用爬虫:如百度、谷歌的搜索引擎爬虫,目标是爬取整个互联网的网页,建立索引库,为搜索功能提供数据;
  2. 聚焦爬虫:针对特定领域或主题的爬虫(如爬取电商平台的手机数据、新闻网站的科技新闻),只爬取与主题相关的页面;
  3. 增量爬虫 :只爬取新增或更新的网页,而非重复爬取所有页面,常用于数据实时更新的场景(如股票价格、新闻资讯)。

0voice · GitHub

相关推荐
菩提祖师_1 天前
基于VR的虚拟会议系统设计
开发语言·javascript·c++·爬虫
是有头发的程序猿1 天前
Python爬虫防AI检测实战指南:从基础到高级的规避策略
人工智能·爬虫·python
菩提祖师_1 天前
量子机器学习在时间序列预测中的应用
开发语言·javascript·爬虫·flutter
菩提祖师_1 天前
量子计算在网络安全中的应用
开发语言·javascript·爬虫·flutter
梦帮科技2 天前
第三十四篇:开源社区运营:GitHub Stars增长策略
开发语言·前端·爬虫·python·docker·架构·html
B站计算机毕业设计之家2 天前
大数据毕业设计:基于python图书数据分析可视化系统 书籍大屏 爬虫 清洗 可视化 当当网书籍数据分析 Django框架 图书推荐 大数据
大数据·爬虫·python·机器学习·自然语言处理·数据分析·课程设计
想看一次满天星2 天前
某里231——AST解混淆流程
爬虫·python·ast·js·解混淆
devnullcoffee4 天前
2026年亚马逊数据采集与反爬虫对抗技术深度解析
爬虫·scrape api·亚马逊数据追踪·亚马逊数据 api·亚马逊反爬虫·爬虫对抗
电商API&Tina5 天前
【电商API接口】多电商平台数据API接入方案(附带实例)
运维·开发语言·数据库·chrome·爬虫·python·jenkins