网络爬虫技术详解
目录
一、爬虫基础概念
什么是爬虫
关键概念
二、Requests 库详解
1. 基本请求方法
2. 响应内容处理
3. 反爬基础:请求头设置
4. 带参数的请求
三、登录状态处理
1. Cookie 直接复用
2. 账号密码登录(含验证码)
四、代理 IP 的使用
代理分类(按匿名程度)
Requests 中使用代理
代理使用技巧
五、爬虫进阶要点
六、法律与伦理规范
一、爬虫基础概念
什么是爬虫
爬虫是通过编写程序模拟浏览器行为,自动从互联网抓取数据的过程。其核心特点:
- 只能获取浏览器可见的数据(客户端渲染内容)
- 理论上可实现所有浏览器能完成的操作
- 核心流程:
URL→发送请求→获取响应→提取数据→保存数据
或URL→发送请求→获取响应→提取新URL
(循环爬取)
关键概念
- 编码与解码:跨平台 / 语言数据传输时的格式转换(如 UTF-8 与 GBK 互转)
- HTTP 状态码:服务器对请求的响应状态标识
- 200:请求成功
- 3xx:重定向(如 301 永久重定向、302 临时重定向)
- 4xx:客户端错误(如 404 资源不存在、403 权限不足)
- 5xx:服务器错误(如 500 服务器内部错误)
二、Requests 库详解
Requests 是 Python 中最常用的 HTTP 请求库,简化了网络请求操作(官方文档)
1. 基本请求方法
import requests# GET请求
response = requests.get(url="https://www.baidu.com")
# POST请求(带表单数据)
response = requests.post(url="https://api.example.com", data={"key": "value"})
2. 响应内容处理
方法 | 返回类型 | 说明 |
---|---|---|
response.text | 字符串 | 自动解码(需提前设置response.encoding="utf-8" 确保中文正常显示) |
response.content | 字节流 | 需手动解码(如response.content.decode("utf-8") ),适合处理二进制数据(图片、文件) |
response.json() | 字典 / 列表 | 自动解析 JSON 格式响应(需确保响应为 JSON) |
response.headers | 字典 | 响应头信息 |
response.status_code | 整数 | HTTP 状态码 |
3. 反爬基础:请求头设置
通过设置headers
模拟浏览器行为,避免被服务器识别为爬虫:
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.64 Safari/537.36","Referer": "https://www.example.com", # 表示请求来源页"Cookie": "xxx" # 携带登录状态
}
response = requests.get(url, headers=headers)
4. 带参数的请求
- URL 参数:通过
params
参数传递params = {"page": 1, "limit": 10} response = requests.get("https://api.example.com/data", params=params)
- 表单数据:通过
data
参数传递(POST 请求)data = {"username": "test", "password": "123456"} response = requests.post("https://api.example.com/login", data=data)
三、登录状态处理
许多网站需要登录后才能访问数据,常见处理方式:
1. Cookie 直接复用
适用于登录状态有效期较长的场景:
headers = {"User-Agent": "...","Cookie": "xxx=xxx; yyy=yyy" # 从浏览器开发者工具复制登录后的Cookie
}
# 直接使用带Cookie的请求头访问需要登录的页面
response = requests.get("https://www.example.com/user", headers=headers)
缺点:Cookie 有有效期,过期后需重新获取;存在账号安全风险
2. 账号密码登录(含验证码)
完整流程:
- 获取登录页面:提取必要参数(如
__VIEWSTATE
、验证码 URL) - 处理验证码:
- 手动识别(适合临时测试)
- 第三方接口(如超级鹰、云打码)自动识别
- 提交登录请求:携带账号、密码、验证码等参数
- 保持会话:使用
requests.session()
维持登录状态
示例(以古诗词网登录为例):
import requests
import re
from chaojiying import verify_fun # 第三方验证码识别工具# 初始化会话(自动处理Cookie)
session = requests.session()
headers = {"User-Agent": "..."}# 1. 获取登录页面,提取验证码URL和VIEWSTATE
login_page_url = "https://www.gushiwen.cn/user/login.aspx"
response = session.get(login_page_url, headers=headers)
html = response.text# 提取验证码图片URL
code_src = re.findall(r'<img id="imgCode" src="(.*?)"', html, re.S)[0]
code_url = f"https://www.gushiwen.cn{code_src}"# 2. 下载验证码并识别
code_img = session.get(code_url, headers=headers).content
with open("code.jpg", "wb") as f:f.write(code_img)
code = verify_fun("code.jpg") # 调用验证码识别接口# 3. 提取VIEWSTATE(ASP.NET页面常用的隐藏参数)
viewstate = re.findall(r'__VIEWSTATE" value="(.*?)"', html, re.S)[0]# 4. 提交登录请求
data = {"__VIEWSTATE": viewstate,"email": "your_email","pwd": "your_password","code": code,"denglu": "登录"
}
session.post(login_page_url, headers=headers, data=data)# 5. 访问登录后页面(会话已保持登录状态)
collect_url = "https://www.gushiwen.cn/user/collect.aspx"
collect_page = session.get(collect_url, headers=headers).text
print("登录成功" if "我的收藏" in collect_page else "登录失败")
四、代理 IP 的使用
代理 IP 是爬虫反反爬的重要手段,作用:
- 隐藏真实 IP,避免被服务器封禁
- 绕过地域限制
- 分散请求压力,模拟多用户行为
代理分类(按匿名程度)
类型 | 特点 | 适用场景 |
---|---|---|
透明代理 | 服务器可知真实 IP(HTTP_X_FORWARDED_FOR 暴露真实 IP) | 仅需隐藏 IP 形式,无隐私需求 |
匿名代理 | 服务器知使用代理,但不知真实 IP(HTTP_X_FORWARDED_FOR 显示代理 IP) | 一般反爬场景 |
高匿代理 | 服务器无法识别代理行为(无HTTP_VIA 和HTTP_X_FORWARDED_FOR ) | 严格反爬网站(推荐使用) |
Requests 中使用代理
# 代理池(键为协议,值为代理地址)
proxies = {"http": "http://ip:port","https": "https://ip:port"# 带认证的代理:"http": "http://username:password@ip:port"
}# 发送请求时指定代理
response = requests.get(url="https://www.example.com",headers=headers,proxies=proxies,timeout=10 # 设置超时,避免代理无响应
)
代理使用技巧
- 维护代理池:定期检测代理有效性,剔除失效代理
- 随机切换代理:避免单一代理被频繁使用导致封禁
- 结合超时设置:防止因代理速度慢影响爬取效率
五、爬虫进阶要点
-
爬取策略:
- 深度优先:优先爬取当前页面链接的深层页面
- 广度优先:优先爬取同层级所有页面(适合全站爬取)
-
反爬与反反爬:
- 基础反爬:User-Agent 校验、Cookie 验证、IP 限制
- 进阶反爬:JavaScript 加密(如参数签名)、验证码、动态渲染(需结合 Selenium)
- 反反爬手段:代理池、请求间隔随机化、模拟浏览器环境
-
面向对象封装:
提高代码复用性和可维护性,示例:class TiebaSpider:def __init__(self, tieba_name, page_count):self.tieba_name = tieba_nameself.page_count = page_countself.session = requests.session()self.headers = {"User-Agent": "..."}def get_urls(self):"""生成所有待爬页面URL"""return [f"https://tieba.baidu.com/f?kw={self.tieba_name}&pn={i*50}" for i in range(self.page_count)]def crawl(self):"""执行爬取逻辑"""for url in self.get_urls():response = self.session.get(url, headers=self.headers)self.save_data(response.text, url)time.sleep(random.randint(1, 3)) # 随机延迟,模拟人类行为def save_data(self, html, url):"""保存爬取结果"""page = url.split("pn=")[-1] // 50 + 1with open(f"{self.tieba_name}_page{page}.html", "w", encoding="utf-8") as f:f.write(html)
六、法律与伦理规范
- 遵守网站
robots.txt
协议(虽非法律强制,但体现爬虫伦理) - 避免高频请求对服务器造成压力(合理设置爬取间隔)
- 不爬取敏感信息(个人隐私、商业机密等)
- 注意目标网站的服务条款,避免侵犯知识产权
通过系统掌握上述知识,可应对大部分常规网站的爬取需求。进阶学习需关注动态渲染页面爬取(Selenium/Puppeteer)、分布式爬虫、验证码识别等技术。