系列导航(20+ 天)
✅ Day1 | ✅ Day2(上) | ▶ Day3(下) | Day4 HTTP 协议 | Day5 TCP/IP | ...
上篇回顾(Day 2):数据类型总览、字符串清洗、列表推导式、字典与集合的爬虫应用。本文接上篇,讲文件操作、异常处理、面向对象。
五、文件操作 — 数据持久化的第一步
爬虫拿到数据后,必须存下来。面试常考三个问题:with open 为什么比 open 好?CSV 写入有什么坑?JSON 怎么正确处理中文?
| 步骤 | 知识点 | 代码 / 坑点 |
| ① | with open 上下文管理器 自动关闭文件,不用手动 f.close() | with open("data.txt","w") as f: f.write(content) |
| ② | CSV 写入的编码坑 Windows 用 utf-8-sig,否则 Excel 乱码 | open("out.csv","w", encoding="utf-8-sig", newline="") |
| ③ | JSON 中文不转义 ensure_ascii=False,否则中文变 \uXXXX | json.dump(data,f, ensure_ascii=False) |
面试常考:with open 底层调用了 __enter__ 和 __exit__ 魔术方法,即使代码抛异常也会自动关闭文件。这就是「上下文管理器」协议。
六、异常处理 — 爬虫不死的关键
爬虫在线上跑,网络超时、JSON 格式错误、Key 不存在——这些天天发生。没做好异常处理,爬虫跑 5 分钟就崩。
| 异常类型 | 触发场景 | 应对策略 |
| requests.Timeout | | |
| JSONDecodeError | | |
| KeyError | | |
| ConnectionError | | |
千万别写裸 except:except: 会吃掉所有异常(包括 KeyboardInterrupt),爬虫卡死都不知道为什么。至少指定异常类型:except requests.Timeout:。
最佳实践:try/except 只包裹可能出错的代码行,不要把整个爬虫塞进一个 try 里。每个独立操作(发请求、解析、写文件)各自 try/except + 各自日志。
七、面向对象 — 为 Scrapy 打地基
Scrapy 框架的核心就是面向对象:Spider 类继承、Item 数据模型、Pipeline 处理链。不懂类继承,Scrapy 就只会照抄模板。
| 概念 | 一句话 | 爬虫应用 |
| 类继承 | | Scrapy 所有 Spider 继承 scrapy.Spider |
| @dataclass | | |
| 方法重写 | | 重写 parse()、start_requests() |
面试能加分:能说出 super().__init__() 的作用(调用父类初始化),说明你理解继承链,不只是会用。Scrapy 源码里大量用到 super()。
提升问答:这段代码里用到了 set 去重、@dataclass 数据类、requests 发请求、try/except 精确捕获 Timeout、CSV/JSON 写入。你能逐行解释每个元素的类型和作用吗?
———— 基础语法篇完结 ————
自查提问(每题 30 秒,先自己想再看提示)
Q1 with open 比 open 好在哪里?底层协议叫什么?
💡 提示:自动关闭、__enter__/__exit__、上下文管理器
Q2 Windows 下写 CSV 为什么乱码?两个参数怎么设?
💡 提示:BOM、utf-8-sig、newline=""
Q3 为什么不能写裸 except?应该怎么做?
💡 提示:KeyboardInterrupt、精确捕获、每个操作单独 try
下篇预告(Day 4)— HTTP 协议全解析
请求报文结构 · HTTP/1.0 → 2.0 演进 · GET vs POST 六大差异关键请求头(UA/Cookie/Referer)· 状态码应对策略 · HTTPS 为什么不能随便 verify=False
Python 爬虫系列 · 20+ 天 · 难度层层递进
下一篇:Day 4 — HTTP 协议全解析