Python 爬虫数据存储:TXT 文本存储指南

爬虫小白练手、临时项目存中间量、不想折腾依赖时,TXT 是你逃不开的「轻量级救星」——但怎么存才既快又清晰不丢数据?这篇给你讲透。

1. 为什么选 TXT?

别小瞧这个上世纪就有的格式,它有三个不可替代的核心优势

  • 零门槛上手:不用装任何库(json、csv、pandas 统统不需要),Python 自带的 open() 就能直接干活。
  • 全平台通吃:Windows 记事本、macOS 文本编辑、Linux 的 cat 命令,随便打开随便看,没有任何环境依赖。
  • 绝对轻量无冗余:没有 schema、没有表头、没有编码锁——只要记住强制指定 UTF-8,就不会出现乱码。

当然,缺点也摆在那里:

  • 没法快速按「评分 > 9」「科幻片」这类条件筛选。
  • 很难自动验证数据完整性(比如漏爬了上映时间,文件里完全看不出来)。
  • 大文件打开卡顿,修改效率极低。

适合的场景

✅ 爬虫练手、验证抓取结果
✅ 短期临时存 JSON / CSV 之前的「过渡数据」
✅ 简单的调试日志、监控记录
❌ 需要结构化的检索与统计
❌ 长期持久化的核心数据
❌ 百万级以上的海量数据处理


2. 实战示例:爬取示例电影网站存 TXT

我们拿公开的爬虫练习网站 https://ssr1.scrape.center/ 来演示。爬取首页 10 部电影的名称、类型、上映时间、评分,然后生成一份易读、带分隔线、UTF-8 编码的 TXT 文件。

2.1 完整可运行代码

import requests
from bs4 import BeautifulSoup
from typing import List, Dict
from datetime import datetime  # 示例追加模式会用到

def scrape_movies() -> List[Dict]:
    """爬取练习网站首页10部电影的结构化数据"""
    base_url = "https://ssr1.scrape.center/"
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
    }

    try:
        response = requests.get(base_url, headers=headers, timeout=10)
        response.raise_for_status()   # 自动抛出 HTTP 错误
        soup = BeautifulSoup(response.text, 'html.parser')
        movies = []

        for item in soup.select('.el-card'):
            name = item.select_one('h2').text.strip()
            categories = [c.text.strip() for c in item.select('.categories button')]
            # 注意:示例网站的上映时间藏在 .info 中
            published_at = item.select_one('.info:contains("上映")').text.split(':')[-1].strip()
            score = item.select_one('.score').text.strip()

            movies.append({
                'name': name,
                'categories': categories,
                'published_at': published_at,
                'score': score
            })

        return movies

    except requests.exceptions.RequestException as e:
        print(f"请求失败,原因:{e}")
        return []
    except AttributeError as e:
        print(f"解析 HTML 失败,检查选择器:{e}")
        return []

def save_to_txt(data: List[Dict], filename: str = 'movies_output.txt'):
    """将结构化电影数据保存为易读的 TXT 文件"""
    if not data:
        print("没有可保存的数据")
        return

    try:
        with open(filename, 'w', encoding='utf-8') as f:
            for idx, movie in enumerate(data, 1):
                f.write(f"【第{idx}部电影】\n")
                f.write(f"电影名称:{movie['name']}\n")
                f.write(f"类型标签:{', '.join(movie['categories'])}\n")
                f.write(f"上映时间:{movie['published_at']}\n")
                f.write(f"豆瓣评分(示例):{movie['score']}\n")
                f.write("=" * 60 + "\n\n")   # 分隔线,增强可读性

        print(f"✅ 成功保存{len(data)}部电影数据到:{filename}")

    except IOError as e:
        print(f"❌ 文件保存失败,原因:{e}")

if __name__ == '__main__':
    movies = scrape_movies()
    save_to_txt(movies)

2.2 代码亮点拆解

相比网上随手搜的「入门 TXT 爬虫代码」,这个版本做了几处实用改进:

  1. 类型注解清晰-> List[Dict] 这样的标注,写的时候不容易传参错,看的时候也一眼就能明白返回值结构。
  2. 完善的错误分支:把「请求失败」和「解析失败」分开处理,调试时不用瞎猜问题出在哪里。
  3. 强制指定 UTF-8 编码:彻底解决 Windows 记事本默认 GBK 打开会乱码的问题。
  4. 带序号、标签、强分隔线的输出:肉眼扫一遍就能快速定位到想看的电影。
  5. 先检查数据再保存:避免生成空文件,减少无意义的文件残留。

3. 必懂的 Python TXT 文件操作

前面的实战用了 w 写入模式,但 TXT 操作远不止这一种。核心就是掌握打开模式、with 语句、编码规范这三点。

3.1 核心打开模式对照表

模式全称核心行为必知细节适用场景
rread只读打开现有文件文件不存在会报错读取已经存好的 TXT 数据
wwrite覆盖式写入文件不存在会创建;存在会清空原内容重写第一次生成完整的结构化 TXT
aappend追加式写入文件不存在会创建;存在会在文件末尾添加爬虫增量抓取、日志记录
r+read+write读写打开现有文件覆盖从当前指针位置开始(默认开头)小范围修改已有 TXT

⚠️ 新手踩坑提醒:千万别用 w 模式去「修改已有文件的某一行」——直接用 r+ 或者「读取全部内容 → 修改 → 覆盖写入」更安全。

3.2 高级常用操作

3.2.1 增量追加模式(爬虫爬多页时最常用)

def append_to_txt(movie: Dict, filename: str = 'movies_append.txt'):
    """单条追加电影数据到 TXT"""
    try:
        with open(filename, 'a', encoding='utf-8') as f:
            # 加当前时间戳,方便追溯是哪次爬取的
            timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            f.write(f"[{timestamp}] ")
            f.write(f"电影:{movie['name']} | 类型:{', '.join(movie['categories'])} | 评分:{movie['score']}\n")
    except IOError as e:
        print(f"追加失败:{e}")

# 调用示例
if movies:
    append_to_txt(movies[0])

3.2.2 批量写入提升性能

如果要写入上万条数据,不要用 for 循环一行一行 f.write(),应该用 f.writelines(),一次写入性能更高:

# 先生成所有要写入的字符串列表
lines_to_write = []
for idx, movie in enumerate(movies, 1):
    lines_to_write.append(f"【第{idx}部】{movie['name']}\n")
    lines_to_write.append(f"类型:{', '.join(movie['categories'])}\n")
    lines_to_write.append("-" * 30 + "\n")

# 一次性写入
with open('bulk_movies.txt', 'w', encoding='utf-8') as f:
    f.writelines(lines_to_write)

4. 安全避坑指南

虽然 TXT 很简单,但也有几个容易踩的「小雷」:

  1. 乱码雷:不管你用的是什么操作系统,但凡写文本文件,请一定加上 encoding='utf-8'
  2. 路径雷:用 pathlib.Path 自动适配跨平台路径,远离手写 \/ 的烦恼:
    from pathlib import Path
    
    output_dir = Path("output")
    output_dir.mkdir(exist_ok=True)   # 文件夹已存在也不会报错
    
    safe_file = output_dir / "safe_movies.txt"
  3. 权限雷:如果存入的是敏感数据,可以在 Linux/macOS 上设置更严格的文件权限:
    import os
    
    if os.name == "posix":   # 仅对 macOS/Linux 生效
        os.chmod(safe_file, 0o600)   # 只有文件所有者可读可写

5. 总结

TXT 不是万能药,但在「快速验证、临时过渡、轻量日志」这三个场景下,它绝对是性价比最高的选择。当你后续需要结构化检索时,也可以很轻松地把 TXT 转为 JSON / CSV,或者导入 SQLite 数据库——这也正是我们下一篇要聊的内容。

你平时用 TXT 存过哪些爬虫数据?欢迎在评论区交流 😉