从零到一:手写简易爬虫脚本的完整指南(附Python代码与反爬策略)
目录导读
- 爬虫原理与法律边界(你凭什么能爬?哪些不能碰?)
- 环境搭建与核心库选择(Requests + BeautifulSoup 还是 Scrapy?)
- 四步写出你的第一个爬虫脚本(请求→解析→提取→存储)
- 实战案例:抓取豆瓣电影Top250(含翻页与数据清洗)
- 反爬虫机制与应对策略(Headers伪装、限速、代理IP)
- 常见问题与调试技巧(编码混乱、动态加载、超时处理)
- 问答环节(Q&A:新手最纠结的5个问题)
爬虫原理与法律边界
很多人误以为爬虫就是“复制粘贴”的高阶版,但本质上它是一个自动化HTTP请求-响应循环:程序模拟浏览器向服务器发送请求,接收HTML/JSON数据,再按规则提取关键信息。“能爬”不等于“可爬”,根据《网络安全法》与《反不正当竞争法》,涉及个人隐私、商业机密或需登录授权的数据(如微信好友、电商订单)严禁爬取,建议阅读目标网站的robots.txt(例如https://www.douban.com/robots.txt)确认抓取范围。

环境搭建与核心库选择
对于简易爬虫,推荐Python + Requests + BeautifulSoup组合,理由:
- Requests:处理HTTP请求,自动管理cookies与重定向。
- BeautifulSoup:解析HTML,用CSS选择器定位元素,比正则表达式更人性化。
- Lxml(可选):作为BS4的解析引擎,速度提升10倍。
若目标是JSON接口(如手机App),直接使用requests.get(url).json()更高效。Scrapy框架虽强大,但学习曲线陡峭,不适合“简易”场景。
四步写出你的第一个爬虫脚本
以抓取“某新闻网站标题”为例,核心代码仅12行:
import requests
from bs4 import BeautifulSoup
url = 'https://example.com/news'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'} # 伪装浏览器
response = requests.get(url, headers=headers, timeout=5)
soup = BeautifulSoup(response.text, 'lxml')s = soup.select('h2.news-title a') # CSS选择器
for t in titles:
print(t.text.strip())
关键点:必须设置headers,否则多数网站直接返回403。timeout防止程序卡死。
实战案例:抓取豆瓣电影Top250
这个经典案例能演示翻页、数据清洗、CSV存储,观察URL规律:https://movie.douban.com/top250?start=0(每页25条,start递增25),完整脚本逻辑:
- 循环
start从0到225,每次获取一页。 - 提取字段:电影名称、评分、评价人数、经典台词。
- 用
pandas.to_csv()保存,注意编码设置utf-8-sig防乱码。
避坑提示:豆瓣会检测高频请求,建议在循环中添加time.sleep(2)。
反爬虫机制与应对策略
当你“裸奔”访问时,服务器能通过IP、Cookie、JS指纹识别爬虫,简易应对三板斧:
- Headers伪装:复制浏览器请求的完整Header,包括
Referer和Accept-Language。 - 限速:每秒请求不超过1次,模仿人类阅读速度。
- 代理IP池:免费代理不稳定,可尝试
free-proxy-list.net,但需写失败重试逻辑。
若遇到“验证码”,说明目标网站防御较强,建议直接放弃,以免触法。
常见问题与调试技巧
- 乱码:
response.encoding = 'utf-8',或从响应头charset参数判断。 - 动态加载数据:简易方案是寻找XHR接口,按F12查看Network面板,直接请求JSON数据。
- 超时重试:封装一个
safe_request()函数,用try-except捕获异常,循环3次。 - 日志记录:使用
logging模块,记录每次请求的URL与状态码,便于排查。
问答环节(Q&A)
Q1:我爬到的数据是空的,但浏览器能看到?
A:90%是因为网页数据由JavaScript动态渲染,此时要么找底层的XHR接口,要么用Selenium模拟浏览器(但会牺牲速度)。
Q2:如何避免爬虫脚本被网站封IP?
A:遵守robots.txt,设置随机延迟(如time.sleep(1+random.random())),并在请求头中添加Connection: keep-alive。
Q3:爬取图片或文件时,怎么实现多线程下载?
A:使用concurrent.futures.ThreadPoolExecutor,分片下载,但需控制并发数不超过5,否则会被限流。
Q4:macOS与Windows的爬虫脚本有区别吗?
A:核心代码一致,唯一区别是文件路径分隔符( vs ),建议用os.path.join()解决。
Q5:可以爬取需要登录的数据吗?
A:简易爬虫可借助requests.Session()保持登录状态,先手动登录并复制Cookie到脚本中,但禁止爬取私密信息。
写一个简易爬虫脚本,本质上就是“明确目标→分析请求→模拟伪装→解析数据”的工程闭环,新手务必从静态网页练手,逐步增加复杂度。技术无罪,但滥用有罪,如遇到法律模糊地带,请咨询专业律师,祝你在数据海洋中,捞到合法且有用的金子。