🧠 一、爬虫基础概念
1.1 爬虫定义
爬虫(Web Crawler)是模拟浏览器行为,自动向服务器发送请求并获取响应数据的一种程序。 主要用于从网页中提取结构化数据,供后续分析、展示或存储使用。
1.2 爬虫特点
数据碎片化:网页数据分散、不规则。 模拟用户行为:爬虫需要尽可能模拟正常用户的请求行为,以绕过反爬机制。 目标明确:聚焦爬虫有明确的目标网站与数据需求。
1.3 爬虫分类
类型 描述 通用爬虫 面向大量网站抓取数据,如搜索引擎使用的爬虫 聚焦爬虫 有特定目标网站的数据采集任务
聚焦爬虫细分:
功能性爬虫 :不直接获取数据,而是实现某些功能(如投票、抢票、短信轰炸等)数据增量爬虫 :持续获取新数据用于分析,常见于新闻资讯、价格监控等领域
1.4 爬虫流程
确认目标URL -> 发送请求 -> 获取响应 -> 提取数据 -> 处理/保存数据↖_____________可能继续解析新的URL__________________↙
1.5 Robots协议
是一个约定俗成的协议文件(robots.txt
),用于告知爬虫哪些页面可以访问,哪些不能。 并非强制性标准,但应尊重该协议以避免法律风险。
1.6 爬虫的作用
数据采集(电商价格、天气预报、股票行情等) 软件测试(自动化测试接口) 抢票、刷票、短信轰炸(需谨慎使用) 网络安全(漏洞扫描、安全检测)
🔌 二、网络通信原理
2.1 基本流程
浏览器输入 URL(如 www.baidu.com
) DNS 解析域名,返回 IP 地址 客户端(浏览器)通过 TCP/IP 协议连接服务器 发送 HTTP 请求 服务器处理请求并返回响应 客户端接收响应并渲染页面(HTML/CSS/JS)
2.2 URL 统一资源定位符
示例:https://www.baidu.com/s?wd=搜索词
结构: 协议(http/https) 域名(主机名) 端口(默认80或443) 路径(路径+查询参数)
2.3 请求方法(HTTP Methods)
方法 描述 GET 请求获取资源,参数在URL中 POST 提交数据给服务器,参数在请求体中 PUT 更新资源 DELETE 删除资源
2.4 请求组成
请求行(Method + Path + HTTP Version) 请求头(Headers) 请求体(Body,仅POST/PUT等有)
2.5 响应状态码
状态码 描述 备注 200 请求成功 表示服务器已成功处理了请求,并返回请求的数据。 302 临时重定向 服务器要求客户端执行临时重定向(原始为GET请求),新的URL位于响应头中的 Location
字段。 303 查看其他位置 对于 POST 请求的响应,浏览器会自动重定向至新的 URL,该新地址位于 Location
中。 307 临时重定向 (GET) 类似于 302,但明确指示 GET 请求应保持原样,不改变为 POST 或其他方法。 403 禁止访问 服务器理解请求,但拒绝执行它。可能是由于权限不足或被封禁 IP。 404 找不到页面 服务器找不到与请求 URI 相匹配的任何资源。 500 内部服务器错误 服务器遇到意外情况,无法完成请求。 503 服务不可用 通常是因为服务器正在进行维护或过载。可能会在响应中携带 Retry-After
头来提示客户端何时可以再次尝试连接。
📡 三、HTTP & HTTPS 协议详解
3.1 HTTP 协议
超文本传输协议,默认端口:80 明文传输,易被监听或篡改
3.2 HTTPS 协议
HTTP + SSL/TLS 加密层,默认端口:443 更安全,防止中间人攻击 性能略低于 HTTP
3.3 SSL/TLS 的作用
数据加密:保证传输过程中的隐私 身份验证:确保客户端连接的是正确的服务器
🕵️♂️ 四、浏览器开发者工具(F12)
4.1 使用 F12 查看请求信息
打开“开发者工具” → Network(网络)面板 可查看: 请求 URL 请求方法(GET/POST) 请求头(Headers) 请求体(Body) 响应数据(Response) 响应状态码(Status Code)
4.2 注意事项
实际响应数据才是判断依据,不要依赖 Elements 中的 HTML 渲染结果。 有些数据由 JavaScript 动态加载,需查看 XHR/Fetch 请求。
📦 五、Requests 模块详解
5.1 requests 模块介绍
Python 第三方库,用于发送 HTTP 请求 支持 GET、POST、PUT、DELETE 等多种方法 安装命令:
pip install requests -i https://pypi.tuna.tsinghua.edu.cn/simple
5.2 常用方法
import requestsurl = "https://www.baidu.com"
response = requests.get(url)print(response.status_code) # 响应状态码
print(response.text) # 响应文本(str类型)
print(response.content) # 响应字节流(bytes类型)
print(response.headers) # 响应头
print(response.url) # 最终请求的URL(可能重定向)
5.3 response.text vs response.content
属性 类型 特点 .text
str 自动解码(可能乱码) .content
bytes 原始字节流,适合下载图片、视频等二进制数据
5.4 设置编码格式
response.encoding = 'utf-8' # 手动指定解码方式
5.5 下载图片示例
url = "https://example.com/image.jpg"
res = requests.get(url)
with open("image.jpg", "wb") as f:f.write(res.content)
🧪 六、User-Agent 和 Headers 设置
6.1 User-Agent 概述
标识客户端身份(浏览器型号、操作系统等) 服务器会根据 UA 判断是否为合法浏览器 如果 UA 不合法,可能被识别为爬虫,返回 403 或 503 错误
6.2 构建请求头
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36..."
}
response = requests.get(url, headers=headers)
6.3 构建 User-Agent 池
user_agents = ["Mozilla/5.0 (Windows NT 10.0; Win64; x64)...","Mozilla/5.0 (iPad; CPU OS 16_6 like Mac OS X)...",...
]
import random
headers = {"User-Agent": random.choice(user_agents)}
6.4 使用 fake_useragent 库
pip install fake_useragent -i https://pypi.tuna.tsinghua.edu.cn/simple
from fake_useragent import UserAgent
ua = UserAgent()
headers = {"User-Agent": ua.random}
🌐 七、带参数请求(GET)
7.1 参数传递方式
URL 编码参数(GET 请求) 表单数据(POST 请求)
元素 说明 键(Key) 参数名称,如 q
, form
值(Value) 对应的参数值,如 学习
, QBLH
分隔符 使用 =
连接键与值,多个参数之间使用 &
分隔
7.2 URL 参数传参
params = {"q": "学习"}
response = requests.get("https://cn.bing.com/search", params=params)
7.3 urllib.parse 模块
from urllib.parse import quote, unquoteprint(quote("学习")) # 输出:%E5%AD%A6%E4%B9%A0
print(unquote("%E5%AD%A6%E4%B9%A0")) # 输出:学习
🛡️ 八、反爬机制与应对策略
8.1 常见反爬手段
类型 描述 IP 封锁 识别频繁访问的IP地址 UA 识别 检查 User-Agent 是否异常 Cookie 限制 登录后才可访问 JS 渲染限制 数据由 JavaScript 异步加载 CAPTCHA 验证 图形验证码拦截爬虫 请求频率控制 单位时间内请求数量限制
8.2 反反爬策略
方法 描述 使用代理IP池 避免固定IP被封锁 随机 User-Agent 模拟不同浏览器 添加 Referer 模拟从其他页面跳转而来 设置延迟 控制请求频率(time.sleep()) 使用 Selenium 模拟浏览器操作动态网页 使用 Headless 浏览器 如 Puppeteer、Playwright
📌 九、实战案例:构建简单搜索引擎爬虫
import requests
from fake_useragent import UserAgent
from urllib.parse import quoteua = UserAgent()
headers = {"User-Agent": ua.random}keyword = input("请输入你要搜索的内容:")
encoded_kw = quote(keyword)
url = "https://cn.bing.com/search"
params = {"q": encoded_kw}response = requests.get(url, headers=headers, params=params)
print(response.text)
✅ 十、注意事项与最佳实践
遵守 robots.txt :避免非法抓取敏感数据。设置请求间隔 :使用 time.sleep()
防止频繁请求。使用代理 IP 池 :提高稳定性与隐蔽性。记录日志 :便于调试与追踪问题。异常处理 :添加 try-except 捕获网络异常。合理设置超时时间 :requests.get(timeout=5)
定期更新 User-Agent 池 关注网站结构变化 :防止因页面结构调整导致解析失败