欢迎光临
我们一直在努力

爬虫原理与反爬实战:从requests到Scrapy,破解前端防护与后端限流

爬虫这个事儿,圈内人聊起来总是两极分化:有人靠它搞数据采集养活整个业务线,有人因为不懂反爬天天被网站封IP,还有人写了一堆代码最后被对方的JavaScript验证码折磨到怀疑人生。其实爬虫没那么玄乎,本质就是“模拟浏览器行为、批量获取网页公开数据、再按需提取信息”的一套流程。这篇东西我不打算写成教科书,就按我自己这些年踩坑、排查、重构的经验,把爬虫从原理到实战、从前端防护到后端限流,尽量讲透。适合刚准备入门的Python新手,也适合写了两三个月爬虫但总被反爬搞得焦头烂活的人,甚至后端同学也可以看看别人是怎么“破解”你接口的,反向做防护。

1. 爬虫到底是怎么工作的:从一次网络请求说起

很多人一上来就装Scrapy、配代理池,其实连最基本的“一次HTTP请求到底发生了什么”都没搞清楚。我个人觉得,爬虫入门最该花时间的地方,就是先把requests库和浏览器开发者工具吃透。这俩搞明白,后面所有框架、分布式、去重方案都是锦上添花。

1.1 一次普通请求的完整流程

你在浏览器地址栏输入一个网址并回车,背后发生的事情大致是:DNS解析把域名换成IP,然后和服务器建立TCP连接(HTTPS还要多做一次TLS握手),接着发送HTTP请求头,服务器处理完返回响应体,浏览器再把HTML、CSS、JS渲染成页面。爬虫做的事情就是跳过“渲染”这一步,直接把服务器返回的原始HTML拿过来,或者直接请求后端接口拿JSON数据,然后自己用代码提取需要的内容。

1.2 解析响应的几种方式

拿到HTML之后怎么把数据抠出来,这是爬虫的核心分水岭。常见的解析方式有三种:

  • 正则表达式:最原始但最灵活,适合结构简单、模式固定的字符串提取,比如拿 <title>(.*?)</title> 这种。缺点是写起来容易出错,还特别难维护。
  • XPath:基于DOM树路径定位节点,比正则易读得多。Python里配合 lxml 使用,性能很好。热词里提到的“text函数”就是XPath里的 text() ,用来获取节点文本内容,坑是它只能拿当前节点的直接文本,拿不到子节点拼出来的全文。
  • BeautifulSoup:适合快速原型,API友好,但大流量下性能一般。
  • Jmespath、CSS Selector、JsonPath:分别对应复杂JSON、HTML CSS选择器、嵌套JSON提取,按需用就行。

1.3 爬虫的最小实现:requests + XPath

我建议新手第一节课就先跑通这个最小闭环,不要着急上框架。代码大概长这样:

import requests
from lxml import html

url = \”https://example.com/news\”
headers = {\”User-Agent\”: \”Mozilla/5.0 (Windows NT 10.0; Win64; x64)\”}
resp = requests.get(url, headers=headers, timeout=10)
resp.encoding = resp.apparent_encoding

doc = html.fromstring(resp.text)
titles = doc.xpath(\”//h2/a/text()\”)
for t in titles:
print(t.strip())

这段代码虽然短,但已经包含了爬虫四个必备步骤:构造请求、处理响应、解析内容、输出结果。注意 resp.encoding 那行,很多新手中文乱码就是没设置编码,直接用 resp.text 会按响应头的charset解码,如果服务器没给对就会乱。用 apparent_encoding 能根据字节推断出实际编码,算是第一道保险。

2. 常见爬虫技术栈与框架选型

工具选型没有绝对好坏,只有合不合适。我自己经历过从纯requests脚本到Scrapy项目,再到自己封装调度器的过程。这里把几个常用方案拿来做对比,你们也好判断什么场景上什么。

2.1 requests还是urllib,为什么是requests

urllib是Python自带的HTTP库,能用但不好用:不支持自动重试、不自动管理Cookie、处理代理也麻烦。requests封装了这些细节,一行 requests.get 搞定,还支持会话对象 Session() ,可以跨请求保持Cookie、复用连接池。爬虫里最重要的是Session,因为很多网站登录态就是靠Cookie维持的,用同一个Session连续请求,就像你在同一台浏览器里没关过页面,反爬系统不容易把你识别成机器人。

2.2 XPath还是正则:text函数的坑

有一个经典场景:页面上有个商品描述区域,HTML长这样:

<div class=\”desc\”>
这个是<span class=\”hot\”>爆款</span>商品
</div>

如果你用XPath写 //div[@class=\”desc\”]//text() ,得到的是三个独立文本节点:[“这个是”, “爆款”, “商品”],需要用 \”\”.join(…) 拼起来。换成 //div[@class=\”desc\”]/text() 只拿到第一层文本,会漏掉span里的内容。这是text函数最常见的坑,搜索引擎里搜“爬虫 xpath text函数”十有八九都是这类问题。

我的习惯是:能用XPath就用XPath,因为它定位节点比正则稳定,但正则也有不可替代的场景,比如提取JSON字段里的某个字符串、清理空行、匹配时间格式。真正项目里我经常XPath和正则混用,比如先用XPath拿到列表节点,再用正则提取里面的日期或编号。 </

赞(0)
未经允许不得转载:171主机测评 » 爬虫原理与反爬实战:从requests到Scrapy,破解前端防护与后端限流
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址