从入门到进阶:网络爬虫、反爬与反反爬技术全解析

本文从零开始系统讲解网络爬虫的原理、常用方法、网站常见的反爬手段,以及应对反爬的思路。文中所有代码与技术仅用于学习与合法的数据采集,请务必在合法合规的前提下使用(文末有专门的法律与道德说明)。


一、什么是网络爬虫

网络爬虫(Web Crawler / Web Spider),又叫网页蜘蛛、网络机器人,本质上是一段自动化访问网页并提取数据的程序

我们平时用浏览器上网,做的事情其实是:

  1. 在地址栏输入一个网址(URL);
  2. 浏览器向服务器发送一个 HTTP 请求;
  3. 服务器返回 HTML、CSS、JS、图片等资源;
  4. 浏览器把这些资源渲染成我们看到的页面。

爬虫做的事情和浏览器几乎一样,区别在于:浏览器把数据渲染给人看,而爬虫把数据抓回来交给程序处理。所以可以一句话概括:

爬虫 = 模拟浏览器发请求 + 从返回的内容里提取出你需要的数据。

常见的应用场景包括:搜索引擎收录网页、电商比价、舆情监控、学术数据采集、自己做数据分析的练手项目等等。


二、爬虫的基本工作流程

无论用什么语言、什么框架,一个爬虫基本都逃不开这四步:

复制代码
┌──────────┐   ┌──────────┐   ┌──────────┐   ┌──────────┐
│ 1. 发请求 │ → │ 2. 拿响应 │ → │ 3. 解析   │ → │ 4. 存储   │
│  URL     │   │  HTML/JSON│   │  提取数据 │   │  落地保存 │
└──────────┘   └──────────┘   └──────────┘   └──────────┘
  1. 发起请求:构造 URL 和请求头,向目标服务器发送请求。
  2. 获取响应:服务器返回内容,可能是 HTML 页面,也可能是 JSON 数据。
  3. 解析提取:从返回内容里把你关心的字段抠出来(标题、价格、链接......)。
  4. 数据存储:把提取到的数据存进文件、数据库或表格。

理解了这个流程,后面所有的工具其实都是在帮你更好地完成其中某一步。


三、爬虫常用方法与工具

下面以 Python 为例(Python 是爬虫最主流的语言,生态最完善),介绍几类核心工具。

3.1 发请求:requests 库

requests 是最常用、最简单的 HTTP 请求库。

python 复制代码
import requests

url = "https://example.com"
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"
}

resp = requests.get(url, headers=headers, timeout=10)
print(resp.status_code)   # 200 表示成功
print(resp.text[:500])    # 打印前 500 个字符的 HTML

发送带参数的请求(GET 和 POST):

python 复制代码
# GET 带查询参数
params = {"page": 1, "keyword": "python"}
resp = requests.get(url, params=params, headers=headers)

# POST 提交表单
data = {"username": "test", "password": "123456"}
resp = requests.post(url, data=data, headers=headers)

3.2 解析:BeautifulSoup / lxml / 正则

拿到 HTML 后,需要从中提取数据。常用三种方式:

① BeautifulSoup(适合新手,可读性强)

python 复制代码
from bs4 import BeautifulSoup

html = resp.text
soup = BeautifulSoup(html, "lxml")

# 按标签和 class 提取
title = soup.find("h1", class_="article-title").text.strip()

# 提取所有链接
for a in soup.find_all("a"):
    print(a.get("href"), a.text)

② XPath(lxml,定位精准,适合复杂结构)

python 复制代码
from lxml import etree

tree = etree.HTML(resp.text)
titles = tree.xpath('//h2[@class="title"]/text()')
links = tree.xpath('//a/@href')

③ 正则表达式(灵活但脆弱,适合简单提取)

python 复制代码
import re

# 提取所有邮箱
emails = re.findall(r'[\w.-]+@[\w.-]+\.\w+', resp.text)

经验之谈:结构化页面优先用 XPath 或 BeautifulSoup,正则只在万不得已或目标特别简单时用,否则页面一改正则就废了。

3.3 动态页面:Selenium / Playwright

现在很多网站的数据不是直接写在 HTML 里,而是页面加载后由 JavaScript 动态请求生成的。用 requests 抓回来的可能是一个"空壳"。这时有两条路:

路线 A:找到背后的接口(推荐,效率高)

打开浏览器开发者工具(F12)→ Network → XHR/Fetch,往往能看到页面真正请求数据的 API,直接请求这个接口拿 JSON 即可(见 3.4)。

路线 B:用浏览器自动化工具,让真实浏览器跑起来

python 复制代码
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(headless=True)
    page = browser.new_page()
    page.goto("https://example.com")
    page.wait_for_selector(".content")   # 等待数据加载
    html = page.content()                # 拿到渲染后的完整 HTML
    browser.close()

Selenium 和 Playwright 都能驱动真实浏览器,好处是"所见即所得",缺点是慢、占资源。能找接口就别开浏览器。

3.4 直接调用接口(API):最高效的方式

如果能在开发者工具里找到返回 JSON 的接口,直接请求是最干净高效的做法:

python 复制代码
api_url = "https://example.com/api/list"
params = {"page": 1, "size": 20}
resp = requests.get(api_url, params=params, headers=headers)

data = resp.json()           # 直接得到 Python 字典/列表
for item in data["list"]:
    print(item["title"], item["price"])

3.5 爬虫框架:Scrapy

当项目变大(要爬成千上万页、需要去重、并发、断点续爬),手写脚本就力不从心了。Scrapy 是一个成熟的异步爬虫框架,内置了请求调度、并发控制、数据管道、中间件等机制。

一个最小的 Scrapy 爬虫:

python 复制代码
import scrapy

class QuotesSpider(scrapy.Spider):
    name = "quotes"
    start_urls = ["https://quotes.toscrape.com"]

    def parse(self, response):
        for quote in response.css("div.quote"):
            yield {
                "text": quote.css("span.text::text").get(),
                "author": quote.css("small.author::text").get(),
            }
        # 自动翻页
        next_page = response.css("li.next a::attr(href)").get()
        if next_page:
            yield response.follow(next_page, self.parse)

quotes.toscrape.com 是一个官方提供的合法练习站点,新手强烈建议拿它练手。


四、常见的反爬技术

网站为了保护数据、减轻服务器压力、防止内容被恶意抓取,会部署各种反爬手段。了解它们,既是为了让正当爬虫"更像正常用户",也是为了理解网站的安全设计思路。

4.1 请求头(Headers / User-Agent)检测

最基础的反爬。服务器检查请求头里的 User-AgentRefererAccept 等字段。如果发现是 Python 默认的 UA(如 python-requests/2.x),直接拒绝。

4.2 IP 与访问频率限制

同一个 IP 短时间内请求太多次,服务器会判定为机器行为,进行限流、临时封禁或返回验证码。这是最常见、最有效的反爬手段之一。

很多页面要求登录后才能访问,或要求请求里携带特定的 Cookie、Token。没有有效凭证就拿不到数据。

4.4 验证码(CAPTCHA)

当系统怀疑你是机器人时,弹出图形验证码、滑块验证、点选文字、行为验证(如 reCAPTCHA、各类滑动拼图)等,用来区分人和机器。这是网站重要的安全防线。

4.5 JavaScript 动态渲染与数据加密

数据不直接出现在 HTML 里,而是通过 JS 异步加载,甚至请求参数和返回数据都经过加密/混淆。直接抓 HTML 拿不到东西。

4.6 字体反爬(自定义字体映射)

页面用自定义字体文件,把真实数字/文字映射成乱码。例如你看到的是"价格 ¥38",但 HTML 源码里其实是一串编码,只有配合特定字体文件才能正确显示。常见于一些点评、招聘、票务类网站。

4.7 参数签名 / 加密

请求里带有一个由前端 JS 算出来的签名参数(如 signtoken、时间戳 + 密钥),服务器校验签名是否合法,防止别人随意构造请求。

4.8 行为检测与蜜罐

  • 行为检测:分析鼠标轨迹、点击间隔、滚动行为,判断是不是真人。
  • 蜜罐(Honeypot) :在页面里放一些人眼看不见但爬虫会抓到的隐藏链接,一旦程序访问了这些链接,立刻判定为爬虫并封禁。

五、应对反爬的常见思路(反反爬)

理解反爬之后,正当爬虫的核心目标其实只有一个:尽量让自己的请求行为接近一个真实、礼貌的用户。下面是常见思路,请始终在合法合规前提下使用。

5.1 伪装请求头

补全 User-AgentReferer 等字段,模拟真实浏览器。还可以维护一个 UA 池随机切换:

python 复制代码
import random

user_agents = [
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) ... Chrome/120.0.0.0 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) ... Safari/605.1.15",
    "Mozilla/5.0 (X11; Linux x86_64) ... Firefox/121.0",
]

headers = {
    "User-Agent": random.choice(user_agents),
    "Referer": "https://example.com/",
    "Accept-Language": "zh-CN,zh;q=0.9",
}

5.2 控制频率 + 随机延时(最重要也最该做的事)

不要疯狂请求。加入随机延时,既能避开频率限制,更是对目标服务器的基本尊重------别把人家服务器爬挂了。

python 复制代码
import time
import random

for url in url_list:
    resp = requests.get(url, headers=headers)
    # 处理数据 ...
    time.sleep(random.uniform(1, 3))   # 随机停 1~3 秒

5.3 使用代理 IP

当单 IP 被限频时,可以通过代理 IP 池分散请求来源:

python 复制代码
proxies = {
    "http": "http://用户名:密码@代理IP:端口",
    "https": "http://用户名:密码@代理IP:端口",
}
resp = requests.get(url, headers=headers, proxies=proxies, timeout=10)

注意:请使用正规渠道购买的合法代理服务。同时再次强调,代理是用来分散正常采集压力的,不是用来突破网站明确禁止访问的限制。

5.4 维持会话与登录态

requests.Session 自动管理 Cookie,模拟登录后的连续访问:

python 复制代码
session = requests.Session()
session.headers.update(headers)

# 先登录(拿到 Cookie)
session.post("https://example.com/login", data={"user": "...", "pwd": "..."})

# 后续请求自动携带 Cookie
resp = session.get("https://example.com/profile")

仅对你自己拥有合法访问权限的账号这样做,不要尝试爬取需要他人授权才能访问的私密数据。

5.5 应对 JS 渲染

如前所述,两条路:

  • 首选:分析 Network 面板,找到真实数据接口,直接请求 JSON;
  • 兜底:用 Playwright / Selenium 驱动真实浏览器渲染后再取数据。

5.6 应对加密参数(逆向分析,概念层面)

对于带签名/加密参数的接口,技术上的做法是通过浏览器调试,定位到生成该参数的 JS 函数,理解其算法后在程序中复现。这属于前端逆向 范畴,难度较高,且很多网站的服务条款明确禁止此类行为。这里只做概念性说明:

  • 知道有这么个技术方向即可;
  • 是否进行,要先看目标网站的 robots.txt 和用户协议;
  • 涉及破解他人安全/加密机制时,往往已经踩到法律红线,请务必谨慎。

5.7 关于验证码

验证码是网站为区分人机、保护安全而设置的防线。实践中存在 OCR 识别、打码平台等技术,但绕过验证码本质上是在突破网站的安全机制。我的建议很明确:

  • 如果一个网站用验证码明确表示"不希望被自动化访问",最稳妥的做法是尊重它,不要硬爬
  • 很多时候你想要的数据,其实有官方开放 API公开数据集可用,那才是正路;
  • 强行绕过安全验证不仅技术上不稳定,更可能违反法律和服务条款。

一句话原则:反爬越强,越说明对方不欢迎自动化访问。这时候该想的不是"怎么破",而是"我是不是该换条合法的路"。


六、一个完整的实战小例子

下面用官方练习站点 quotes.toscrape.com 演示一个完整流程:抓取名言、作者,并存成 CSV。

python 复制代码
import requests
from bs4 import BeautifulSoup
import csv
import time
import random

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"
}

base_url = "https://quotes.toscrape.com/page/{}/"
results = []

for page in range(1, 6):          # 爬前 5 页
    url = base_url.format(page)
    resp = requests.get(url, headers=headers, timeout=10)
    if resp.status_code != 200:
        break

    soup = BeautifulSoup(resp.text, "lxml")
    quotes = soup.find_all("div", class_="quote")
    if not quotes:
        break

    for q in quotes:
        text = q.find("span", class_="text").text.strip()
        author = q.find("small", class_="author").text.strip()
        results.append({"text": text, "author": author})

    time.sleep(random.uniform(1, 2))   # 礼貌延时

# 存成 CSV
with open("quotes.csv", "w", newline="", encoding="utf-8-sig") as f:
    writer = csv.DictWriter(f, fieldnames=["text", "author"])
    writer.writeheader()
    writer.writerows(results)

print(f"共抓取 {len(results)} 条数据,已保存到 quotes.csv")

跑通这个例子,你就基本掌握了"发请求 → 解析 → 翻页 → 存储"的完整闭环。


七、法律与道德边界(请认真读)

爬虫技术本身是中性的,但怎么用决定了它是工具还是凶器。下面几条务必牢记:

  1. 遵守 robots.txt :网站根目录下的 robots.txt(如 https://example.com/robots.txt)声明了哪些路径允许/禁止爬取。它虽不是法律,但代表网站的明确意愿,应当尊重。

  2. 遵守服务条款(ToS):很多网站的用户协议明确禁止自动化抓取,违反可能构成违约甚至侵权。

  3. 不爬取个人隐私和敏感数据:姓名、电话、身份证、住址、人脸等个人信息受法律严格保护(如中国《个人信息保护法》《数据安全法》,欧盟 GDPR 等)。

  4. 控制频率,不影响网站正常运行:高频爬取导致对方服务器瘫痪,可能涉及破坏计算机信息系统等法律责任。

  5. 尊重版权与数据所有权:抓来的数据用于个人学习是一回事,未经授权商用、转售、二次发布是另一回事。

  6. 不破解、不绕过安全机制:突破登录验证、加密、验证码等安全措施,在很多司法辖区可能触犯法律。

真实世界里,因为违规爬虫被起诉、被判刑、公司被罚的案例并不少见。 技术能做到,不代表法律允许你做。学技术的同时,请同步建立合规意识。

合规采集的优先级建议:

官方 API > 公开数据集 > robots.txt 允许范围内的公开页面 >(其余请三思而后行)


八、学习路线建议

如果你刚入门,建议按这个顺序循序渐进:

  1. 打基础:HTTP 协议(请求/响应、状态码、Headers、Cookie)、HTML/CSS 基础。
  2. 入门工具requests + BeautifulSoup,在 quotes.toscrape.combooks.toscrape.com 等练习站练手。
  3. 进阶解析:学会用 XPath、CSS 选择器精准定位。
  4. 动态页面:学会用 F12 分析接口(这是最重要的实战技能),再学 Playwright。
  5. 工程化:学习 Scrapy 框架,掌握并发、去重、数据管道。
  6. 数据存储:CSV → MySQL / MongoDB。
  7. 合规意识:始终把"这件事合不合法、合不合规"放在技术之前。

总结

本文从爬虫的基本概念讲到工作流程、常用工具,再到网站的各类反爬手段和应对思路,最后落到法律与道德边界。核心要点回顾:

  • 爬虫本质是模拟浏览器发请求 + 提取数据,逃不开"请求→响应→解析→存储"四步;
  • 工具上,requests + BeautifulSoup 入门,Scrapy 工程化,动态页面优先找接口、兜底用浏览器自动化;
  • 反爬手段五花八门(UA 检测、IP 限频、验证码、JS 加密、字体反爬等),应对的核心是让爬虫像个礼貌的真实用户
  • 反爬越强,越说明对方不欢迎自动化访问,这时更该考虑合法替代方案;
  • 技术之上是法律和道德,合规永远是第一位的。

希望这篇文章能帮你建立起爬虫的整体认知。技术的路很长,迈出第一步、并且走在正道上,最重要。


如果这篇文章对你有帮助,欢迎点赞、收藏、关注。有问题可以在评论区交流~

相关推荐
Mr.Daozhi21 小时前
Playwright实战:抓取Meta Ad Library动态页面的三级降级策略
爬虫·python·自动化·playwright·meta广告
Mr.Daozhi1 天前
跨境电商选品完整流水线:Google Trends筛词+Meta广告分析,CLI工具设计实战
开发语言·爬虫·python·跨境电商·工具链·选品
huangdong_1 天前
电商平台图片防盗链机制分析与绕过方案
爬虫
HackTwoHub1 天前
WEB扫描器Invicti-Professional-V26.50.0(自动化爬虫扫描)更新
前端·人工智能·chrome·爬虫·web安全·网络安全·自动化
电商API_180079052472 天前
免 TOP 入驻,第三方淘宝商品详情 API 快速接入与代码示例
java·大数据·开发语言·数据库·爬虫·数据分析
如烟花的信页2 天前
易盾点选逆向分析
javascript·爬虫·python·js逆向
深蓝电商API2 天前
AI自动识别网页结构:零规则提取任意网站数据
人工智能·爬虫
小白学大数据2 天前
爬虫优化:Python 剔除无效超时代理实操
服务器·爬虫·python
在水一缸2 天前
当开源硬件撞上闭源围墙:从 Flux.ai 律师函事件看 AI 时代的爬虫法律风险与技术边界
人工智能·爬虫·开源·开源硬件·数据合规·法律风险·flux.ai