1. 开篇为什么需要伪装与会话作为一名爬虫开发者我经常遇到这样的场景明明代码逻辑没问题但就是拿不到想要的数据。后来才发现大多数网站都会检测请求是否来自真实浏览器。这就是为什么我们需要学习伪装和会话管理——让我们的爬虫看起来更像人类用户。记得刚开始做爬虫时我直接用裸奔的Requests发请求结果要么被拒绝要么被限流。直到学会了设置请求头和会话管理爬虫才真正活了起来。今天我就把这些实战经验分享给你。2. HTTP请求头详解2.1 请求头的作用原理请求头(Headers)是HTTP请求的重要组成部分它告诉服务器关于客户端的信息。没有合理设置请求头的爬虫就像没穿衣服走在街上一样显眼。服务器通常会检查这些关键字段User-Agent客户端类型和版本Accept客户端能接收的内容类型Referer请求来源页面Cookie会话标识提示现代网站通常会有多层防护仅设置User-Agent可能不够需要完整的请求头组合。2.2 实战获取真实浏览器请求头最可靠的方法是直接从浏览器复制请求头Chrome中按F12打开开发者工具访问目标网站在Network标签找到任意请求右键选择Copy → Copy request headers得到的格式类似这样User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) Accept: text/html,application/xhtmlxml Accept-Language: zh-CN,zh;q0.9 Referer: https://example.com/2.3 在Python中设置请求头headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64), Accept: text/html,application/xhtmlxml, Accept-Language: zh-CN,zh;q0.9, Referer: https://example.com/ } response requests.get(https://target.com, headersheaders)3. User-Agent的高级使用技巧3.1 常见User-Agent类型不同设备的User-Agent差异很大PC端ChromeMozilla/5.0 (Windows NT 10.0; Win64; x64)移动端SafariMozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X)旧版IEMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)3.2 随机User-Agent实现固定User-Agent容易被识别建议使用随机轮换from fake_useragent import UserAgent ua UserAgent() random_ua ua.random headers {User-Agent: random_ua}注意fake-useragent需要单独安装pip install fake-useragent4. Session会话管理实战4.1 为什么需要Session普通请求是无状态的而Session可以自动处理Cookie保持TCP连接复用共享请求配置维持登录状态4.2 基础Session用法s requests.Session() # 首次请求会设置Cookie s.get(https://example.com/login) # 后续请求自动携带Cookie response s.get(https://example.com/dashboard)4.3 封装高级Session类我推荐封装一个SmartSession类class SmartSession: def __init__(self): self.session requests.Session() self.headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64), Accept-Language: zh-CN,zh;q0.9 } def get(self, url, **kwargs): return self.session.get(url, headersself.headers, **kwargs) def post(self, url, dataNone, jsonNone, **kwargs): return self.session.post(url, datadata, jsonjson, headersself.headers, **kwargs)5. 合规处理登录与Cookie5.1 手动获取Cookie方法使用浏览器正常登录目标网站按F12打开开发者工具在Application → Cookies中找到有效Cookie复制到爬虫代码中cookies { sessionid: abc123..., csrftoken: xyz456... } response requests.get(url, cookiescookies)5.2 表单登录实现对于简单登录表单login_data { username: your_username, password: your_password } s requests.Session() s.post(https://example.com/login, datalogin_data) # 现在s已保持登录状态 response s.get(https://example.com/protected)6. 反爬机制与应对策略6.1 常见反爬手段反爬类型检测方式应对方法UA检测检查User-Agent使用真实浏览器UAReferer检查验证来源页面设置合理Referer频率限制统计请求频率添加随机延迟Cookie验证检查会话Cookie使用Session保持状态6.2 请求频率控制避免被封的关键是模拟人类行为import time import random def random_delay(): time.sleep(random.uniform(1, 3)) # 1-3秒随机延迟 for page in range(1, 10): response requests.get(fhttps://example.com/page/{page}) random_delay()7. 实战案例完整爬取流程7.1 准备工作安装必要库pip install requests fake-useragent准备目标网站分析确定数据所在URL检查需要的请求头确认是否需要登录7.2 完整代码实现from fake_useragent import UserAgent import requests import time import random class BookSpider: def __init__(self): self.ua UserAgent() self.session requests.Session() def get_random_headers(self): return { User-Agent: self.ua.random, Accept: text/html,application/xhtmlxml, Accept-Language: zh-CN,zh;q0.9, Referer: https://book.douban.com/ } def crawl_page(self, page): url fhttps://book.douban.com/top250?start{page*25} headers self.get_random_headers() try: response self.session.get(url, headersheaders) response.raise_for_status() return response.text except Exception as e: print(f请求失败: {e}) return None def run(self): for page in range(10): html self.crawl_page(page) if html: # 这里添加解析逻辑 print(f成功获取第{page1}页数据) # 随机延迟 time.sleep(random.uniform(1, 3)) if __name__ __main__: spider BookSpider() spider.run()8. 常见问题与解决方案8.1 请求被拒绝(403)可能原因User-Agent被识别为爬虫缺少必要请求头IP被暂时封禁解决方案检查并完善请求头添加Referer等必要字段更换IP或等待一段时间8.2 登录状态不保持可能原因没有使用SessionCookie过期网站有额外验证解决方案确保使用requests.Session()检查Cookie有效期模拟完整的登录流程8.3 数据获取不完整可能原因数据是JavaScript动态加载需要特定请求参数分页逻辑有误解决方案检查Network中的XHR请求分析页面加载逻辑验证分页参数9. 高级技巧与优化建议请求头轮换不只是User-Agent其他头信息也可以定期更换IP代理池对于严格网站需要考虑使用代理IP浏览器指纹模拟一些网站会检测浏览器指纹特征请求间隔随机化更自然的访问间隔能降低检测概率错误重试机制对临时性错误实现自动重试一个带重试的请求示例def safe_request(url, max_retry3): for i in range(max_retry): try: response requests.get(url, timeout10) return response except Exception as e: print(f请求失败({i1}/{max_retry}): {e}) time.sleep(2**i) # 指数退避 return None在实际项目中我发现最有效的策略是尽可能模拟真实用户行为。不要追求极致的速度稳定性和可靠性才是长期运行的关键。对于重要项目建议实现完善的日志系统和监控机制能够及时发现和处理异常情况。