2、爬虫与反爬虫基础:爬虫的工作原理、常见爬虫框架(Scrapy、Requests)、反爬虫的基本手段(User-Agent检测、IP限制)

好,咱们正式开始聊爬虫与反爬虫。这一章是地基,地基不牢,后面那些高级对抗手段你学起来会特别吃力。我个人习惯把爬虫和反爬虫比作「矛与盾」——矛要刺穿盾,盾要挡住矛。但有意思的是,攻防双方用的都是同一套底层技术:HTTP协议。

2.1 爬虫到底是怎么工作的?

说白了,爬虫就是个自动化浏览器。你手动打开网页、看内容、点链接,爬虫把这些步骤用代码自动化了。核心流程就三步:

  1. 发送请求:向目标服务器要数据(HTTP GET/POST)
  2. 解析响应:把拿回来的HTML、JSON或二进制数据拆开
  3. 提取存储:把你要的信息(标题、价格、链接)存到数据库或文件里

我在项目中遇到过最典型的场景:一个电商网站的商品信息采集。爬虫先请求商品列表页,拿到每个商品的详情页URL,再逐个请求详情页,最后把价格、库存、评论数存到CSV里。听起来简单吧?但实际跑起来,各种坑就来了。

核心要点:爬虫的本质是模拟HTTP请求。你发的每一个请求,服务器都能看到你的IP、浏览器标识、请求头。这就是反爬虫的切入点。

2.2 常见爬虫框架:Requests vs Scrapy

做爬虫,你绕不开这两个工具。我刚开始学爬虫时,先用Requests手撸,后来才接触Scrapy。嗯,这里要注意:选哪个取决于你的场景

2.2.1 Requests:轻量级利器

Requests是Python里最优雅的HTTP库。没有之一。它的设计哲学就是「让HTTP服务人类」。你想想看,一个简单的GET请求只需要两行代码:

import requests

response = requests.get('https://example.com')
print(response.text)

就这么简单。但别被它的简洁骗了——Requests能处理Session、Cookie、代理、SSL证书验证。我个人习惯用它做小规模采集,或者写API接口的测试脚本。

避坑指南:我曾经用Requests爬一个反爬严格的网站,忘了设置请求头,结果返回的全是403。后来加了User-Agent和Referer,问题就解决了。记住:默认的Requests请求头太干净了,服务器一眼就能认出你是爬虫

2.2.2 Scrapy:工业级框架

Scrapy是爬虫界的「重型坦克」。它内置了请求调度、并发控制、数据管道、中间件机制。你写一个爬虫,只需要定义好Item(数据结构)和Spider(爬取逻辑),剩下的并发、去重、错误重试,Scrapy全帮你搞定。

看一个最简单的Scrapy爬虫示例:

import scrapy

class QuotesSpider(scrapy.Spider):
    name = 'quotes'
    start_urls = ['http://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 is not None:
            yield response.follow(next_page, self.parse)

你发现没有?Scrapy天然支持异步并发。一个爬虫默认并发16个请求,而Requests是同步的,一个请求没返回,下一个就得等着。所以做大规摸采集时,Scrapy的效率能甩Requests几条街。

特性 Requests Scrapy
学习曲线 低(几小时上手) 中(需要理解框架设计)
并发能力 需自行实现(如ThreadPool) 内置异步引擎
数据管道 内置Item Pipeline
中间件支持 Downloader/Spider中间件
适用场景 小规模、API调用 大规模、多层级爬取

2.3 反爬虫的基本手段

好,现在换到防守方视角。作为搜索引擎安全工程师,我每天的工作就是识别并拦截那些「不守规矩」的请求。反爬虫的手段很多,但最基础、最常用的就两个:User-Agent检测IP限制

2.3.1 User-Agent检测

每个HTTP请求都会带一个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

而很多新手写的爬虫,User-Agent长这样:

python-requests/2.28.1

你想想看,服务器看到这个,基本可以断定:这不是人,是爬虫。所以反爬虫的第一步,就是检查User-Agent。如果发现是爬虫库的默认标识,直接返回403或验证码。

注意:只靠User-Agent检测是不够的。稍微有点经验的爬虫工程师都会伪造User-Agent。我见过最狠的爬虫,每次请求都从几千个真实浏览器标识里随机选一个。这时候就需要结合其他手段了。

2.3.2 IP限制

IP限制是反爬虫的「核武器」。原理很简单:同一个IP在单位时间内请求次数太多,就封掉。常见的策略有:

  • 频率限制:比如每分钟最多60次请求,超过就返回429 Too Many Requests
  • 并发限制:同一IP同时建立的连接数不能超过N个
  • 黑名单:发现是代理IP或数据中心IP,直接拉黑

我在项目中遇到过最经典的案例:一个爬虫用单IP每秒发100个请求,直接把我们的API服务器打挂了。后来我们加了IP级别的限流,每秒超过20个请求就返回503,同时记录日志。那个爬虫不到10分钟就被自动封禁了。

但IP限制也有弱点。爬虫可以用代理IP池,每次请求换一个IP。这时候就需要更高级的手段了——比如浏览器指纹检测、行为分析、验证码。这些我们后面章节会详细讲。

避坑指南:我曾经帮一个客户排查反爬虫误伤问题。他们的正常用户(来自同一个公司内网)因为共享同一个出口IP,被误判为爬虫。解决方案是把内网IP段加入白名单。所以做反爬虫时,一定要考虑误伤问题,别把真用户挡在门外。

2.4 攻防对抗的起点

爬虫和反爬虫的对抗,本质上是一场「成本博弈」。反爬虫要让爬虫的获取成本高于收益,爬虫则要想办法降低成本。User-Agent检测和IP限制只是最基础的防线,后面还有更复杂的挑战——JavaScript渲染、验证码、行为分析、动态令牌……

但不管多高级的反爬虫手段,底层逻辑都是一样的:识别出非人类行为,然后拒绝服务。理解了这一点,你就能举一反三,自己设计反爬虫策略了。

下一章,我们会深入聊「请求头分析与伪造」——为什么Referer、Cookie、Accept-Language这些字段也能暴露爬虫身份?到时候见。