AI微小说

大模型写微小说

项目背景

最近启动了一个新项目:电影台词AI文学创作系统
该系统旨在将电影台词转化为AI文学创作的灵感源泉,通过以下三个核心模块实现:

  1. 字幕抓取与清洗 → 获得纯净文本;
  2. 台词分段与解析 → 理解电影语境;
  3. AI识别与创作 → 输出微小说。

最终实现从影视语言到文学作品的智能转换。

项目内容逐渐丰富,便想到利用手头闲置的域名搭建展示页面,顺便记录一下 Hexo Next 主题添加 Google 服务的方法。


1. 添加 Google Analytics

环境信息

  • Hexo 版本:8.1.1
  • 主题:Next
  • 部署方式:本地部署

配置步骤

  1. 将主题文件夹下的 _config.yml 复制到项目根目录,并重命名为 _config.next.yml
  2. _config.next.yml 中找到以下配置段:
1
2
3
4
5
6
# Google Analytics
# See: https://analytics.google.com
google_analytics:
tracking_id: G-WJ48W3LM1R
# By default, NexT will load an external gtag.js script on your site.
# If you only need the pageview feature, set the following option to true to get a better performance.

将 tracking_id 替换为你自己的 Google Analytics 测量 ID(如 G-XXXXXXXXXX)。

无需手动插入 Google 提供的 JavaScript 代码,NexT 主题会自动加载 gtag.js。

2. 添加 Google Adsense

步骤一:放置 ads.txt

在 Hexo 项目根目录的 source 文件夹下,新建 ads.txt 文件,内容粘贴 Google Adsense 提供的验证信息。

步骤二:插入 Adsense 代码

打开主题布局文件:

next/layout/_partials/head/head.njk

在文件底部插入 Google Adsense 提供的 JavaScript 代码片段。

3. 生成与部署

配置完成后,在项目根目录执行以下命令:

1
hexo clean && hexo g && hexo d

在wsl下python3.10.16 torch2.4.0 cuda12.1微调笔记

0.屏蔽wsl中windows的环境变量

1
2
3
4
5
6
7
8
9
10
11
#屏蔽wsl中的windows环境变量
1.在wsl 的 ubuntu中编辑/etc/wsl.conf,输入:

[interop]
enabled = false
appendWindowsPath = false

退出保存之后,需要重启wsl。
在cmd中,输入:

wsl --shutdown

1.环境配置

1.1安装nvidia驱动,最新版即可

https://www.nvidia.cn/geforce/drivers/ ,选择自己的型号,这次安装了NVIDIA Studio 驱动程序 - WHQL

驱动程序版本: 572.60 - 发行日期: 2025-2-27

安装后运行nvidia-smi,这里在windows下安装完,wsl中也可以执行

(u2) zk@baize:~/ai$ whereis nvidia-smi
nvidia-smi: /usr/bin/nvidia-smi /usr/lib/wsl/lib/nvidia-smi /usr/share/man/man1/nvidia-smi.1.gz

1
2
3
4
5
6
7
8
9
10
11
12
13
(u2) zk@baize:~/ai$ nvidia-smi
Wed Mar 12 10:53:45 2025
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 525.105.17 Driver Version: 572.60 CUDA Version: 12.8 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|===============================+======================+======================|
| 0 NVIDIA GeForce ... On | 00000000:01:00.0 On | N/A |
| 41% 46C P8 38W / 420W | 1003MiB / 24576MiB | 9% Default |
| | | N/A |
+-------------------------------+----------------------+----------------------+
1.2conda开虚拟环境
1
2
3
conda create --name u2 \
python=3.10 \
-y
1.3安装xformers 0.0.27.post1版本
1
pip install -U xformers==0.0.27.post1

安装0.0.27.post1对应python310的torch版本为2.4.0,安装后cuda12.1也跟着装好了。

检查xformers情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
(u2) zk@baize:~/ai$ python -m xformers.info
is_triton_available: True
pytorch.version: 2.4.0+cu121
pytorch.cuda: available
gpu.compute_capability: 8.6
gpu.name: NVIDIA GeForce RTX 3090
dcgm_profiler: unavailable
build.info: available
build.cuda_version: 1201
build.hip_version: None
build.python_version: 3.10.14
build.torch_version: 2.4.0+cu121
build.env.TORCH_CUDA_ARCH_LIST: 6.0+PTX 7.0 7.5 8.0+PTX
build.env.PYTORCH_ROCM_ARCH: None
build.env.XFORMERS_BUILD_TYPE: Release
build.env.XFORMERS_ENABLE_DEBUG_ASSERTIONS: None
build.env.NVCC_FLAGS: None
build.env.XFORMERS_PACKAGE_FROM: wheel-v0.0.27.post1
build.nvcc_version: 12.1.66
source.privacy: open source

这里可以看到pytorch.version: 2.4.0+cu121,build.torch_version: 2.4.0+cu121,这两个必须一致,前期安装好几次都不一致。

1.4检查cuda安装,nvcc
1
2
3
4
5
6
(u2) zk@baize:~/ai$ nvcc -V
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2023 NVIDIA Corporation
Built on Tue_Feb__7_19:32:13_PST_2023
Cuda compilation tools, release 12.1, V12.1.66
Build cuda_12.1.r12.1/compiler.32415258_0
1.5检查cuda激活
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
(u2) zk@baize:~/ai$ python
Python 3.10.16 (main, Dec 11 2024, 16:24:50) [GCC 11.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import torch
>>> print(torch.__version__)
2.4.0+cu121
>>> print(torch.cuda.is_available())
True
>>> print(torch.cuda.get_device_name(torch.cuda.current_device()))
NVIDIA GeForce RTX 3090
>>> print(torch.cuda.device_count())
1
>>> print(torch.cuda.get_device_properties(torch.cuda.current_device()))
_CudaDeviceProperties(name='NVIDIA GeForce RTX 3090', major=8, minor=6, total_memory=24575MB, multi_processor_count=82)
>>> print(torch.version.cuda)
12.1
>>> print(torch.backends.cudnn.version())
90100
>>> print(torch.cuda.get_arch_list())
['sm_50', 'sm_60', 'sm_70', 'sm_75', 'sm_80', 'sm_86', 'sm_90']
1.6安装unsloth

unsloth官网example,根据cuda和torch版本选择

1
2
3
4
5
6
7
8
9
10
pip install "unsloth[cu121-ampere-torch240] @ git+https://github.com/unslothai/unsloth.git"
pip install "unsloth[cu118-ampere-torch240] @ git+https://github.com/unslothai/unsloth.git"
pip install "unsloth[cu121-torch240] @ git+https://github.com/unslothai/unsloth.git"
pip install "unsloth[cu118-torch240] @ git+https://github.com/unslothai/unsloth.git"

pip install "unsloth[cu121-torch230] @ git+https://github.com/unslothai/unsloth.git"
pip install "unsloth[cu121-ampere-torch230] @ git+https://github.com/unslothai/unsloth.git"

pip install "unsloth[cu121-torch250] @ git+https://github.com/unslothai/unsloth.git"
pip install "unsloth[cu124-ampere-torch250] @ git+https://github.com/unslothai/unsloth.git"

这里要注意,有坑。找到pip install “unsloth[cu121-torch240] @ git+https://github.com/unslothai/unsloth.git"符合版本,下载过程中发现他去下载xformers-0.0.28.post1,这会把torch和cuda又改变版本,需要加参数--no-deps

1
2
pip install "unsloth[cu121-torch240] @ git+https://github.com/unslothai/unsloth.git" --no-deps
#这里安装完毕因为no deps没拉去了unsloth_zoo,应该加上unsloth_zoo

安装unsloth所需其他依赖

1
2
3
pip install --no-deps trl peft accelerate bitsandbytes

pip install unsloth_zoo #zoo不会改变torch和cuda版本
1.7预先编译好llama.cpp

调用gpu编译llama.cpp

1
2
3
#官方帮助文档:https://github.com/ggml-org/llama.cpp/blob/master/docs/build.md
cmake -B build -DGGML_CUDA=ON
cmake --build build --config Release

编译后,在/home/zk/ai/llama.cpp/build/bin下要有llama-quantize和llama-cli这两个主要文件。

2.微调

2.1微调主代码

这里把基础模型和数据集都改写成本地调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import os
from unsloth import FastLanguageModel
import torch
from trl import SFTTrainer
from transformers import TrainingArguments
from datasets import load_dataset

# 加载模型
max_seq_length = 2048
dtype = None
load_in_4bit = True
model, tokenizer = FastLanguageModel.from_pretrained(
model_name = "/home/zk/ai/base_model/llama-3-8b-bnb-4bit",
max_seq_length = max_seq_length,
dtype = dtype,
load_in_4bit = load_in_4bit,
)

# 准备训练数据
alpaca_prompt = """Below is an instruction that describes a task, paired with an input that provides further context. Write a response that appropriately completes the request.
### Instruction:
{}
### Input:
{}
### Response:
{}"""

EOS_TOKEN = tokenizer.eos_token # 必须添加 EOS_TOKEN
def formatting_prompts_func(examples):
instructions = examples["instruction"]
inputs = examples["input"]
outputs = examples["output"]
texts = []
for instruction, input, output in zip(instructions, inputs, outputs):
# 必须添加EOS_TOKEN,否则无限生成
text = alpaca_prompt.format(instruction, input, output) + EOS_TOKEN
texts.append(text)
return {"text": texts}
pass

# 本地数据集
dataset = load_dataset("json", data_files = "/home/zk/ai/dataset/caishui_2011_100hao.json", split="train")
dataset = dataset.map(formatting_prompts_func, batched = True)

# 设置训练参数
model = FastLanguageModel.get_peft_model(
model,
r = 16,
target_modules = ["q_proj", "k_proj", "v_proj", "o_proj",
"gate_proj", "up_proj", "down_proj", ],
lora_alpha = 16,
lora_dropout = 0,
bias = "none",
use_gradient_checkpointing = True,
random_state = 3407,
max_seq_length = max_seq_length,
use_rslora = False,
loftq_config = None,
)

trainer = SFTTrainer(
model = model,
train_dataset = dataset,
dataset_text_field = "text",
max_seq_length = max_seq_length,
tokenizer = tokenizer,
args = TrainingArguments(
per_device_train_batch_size = 1,
gradient_accumulation_steps = 4,
warmup_steps = 2,
max_steps = 20,
fp16 = not torch.cuda.is_bf16_supported(),
bf16 = torch.cuda.is_bf16_supported(),
logging_steps = 1,
output_dir = "outputs",
optim = "adamw_8bit",
weight_decay = 0.01,
lr_scheduler_type = "linear",
seed = 3407,
learning_rate = 2e-5,
),
)

# 开始训练
trainer.train()

# 保存微调模型
model.save_pretrained("lora_model")

# 选项:保存为16位hf模型
save_16bit = input("是否保存为16位hf模型?(y/n): ")
if save_16bit.lower() == "y":
model.save_pretrained_merged("outputs", tokenizer, save_method="merged_16bit")

# 选项:保存为gguf模型
save_gguf = input("是否保存为gguf模型?(y/n): ")
if save_gguf.lower() == "y":
os.system("python /home/zk/ai/llama.cpp/convert_hf_to_gguf.py --outfile /home/zk/ai/gguf_model/lm38b_tax_jzjt.gguf /home/zk/ai/outputs")

# 选项:量化为4位gguf模型
quantize_4bit = input("是否量化为4位gguf模型?(y/n): ")
if quantize_4bit.lower() == "y":
os.system("/home/zk/ai/llama.cpp/build/bin/llama-quantize /home/zk/ai/gguf_model/QWQ_tax_jzjt.gguf /home/zk/ai/gguf_model/lm38b_tax_jzjt-Q4_K_M.gguf Q4_K_M")

电影台词智能分析工具:基于AI的影视内容深度解析

🎬 项目简介

这是一个利用人工智能技术自动分析电影台词内容的智能工具。通过简单的文本输入,程序能够:

  • 自动识别电影名称:从台词内容或文件名智能推断
  • 提炼经典台词:筛选最具代表性的10句精彩对白
  • 创作微小说:基于电影主题创作现代化改编故事
  • 支持长文本处理:智能分段处理超长电影台词

✨ 核心功能

🔍 智能电影分析

  • 自动推断电影名称和基本信息
  • 深度理解剧情脉络和人物关系
  • 提取最具代表性的经典台词

📝 创意内容生成

  • 基于电影主题创作全新微小说
  • 现代背景下的故事改编
  • 保持原作风味的同时创新叙事

⚡ 技术优势

  • 流式处理:支持超长台词分段分析
  • 多模型支持:兼容DeepSeek、通义千问等主流模型
  • 智能记忆:完整接收台词后再统一分析

🛠️ 技术架构

核心技术

  • AI模型:DeepSeek-R1推理模型(支持思维链)
  • API接口:硅基流动平台(OpenAI兼容)
  • 处理引擎:Python + OpenAI SDK

💡 代码解析

1. 智能分段处理长文本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def split_text_into_parts(text_content, part_length=3000):
"""智能文本分段,避免截断完整句子"""
parts = []
sentences = re.split(r'(?<=[。!?!?])', text_content)

current_part = ""
for sentence in sentences:
if len(current_part) + len(sentence) <= part_length:
current_part += sentence
else:
if current_part:
parts.append(current_part)
current_part = sentence

if current_part:
parts.append(current_part)

return parts

2. 电影名称提取

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
def extract_movie_name(file_path):
"""从复杂文件名中智能提取电影名称"""
filename = Path(file_path).stem

# 移除下载站点标记
clean_name = re.sub(r'^\[.*?\]', '', filename)

# 移除分辨率、编码等信息
patterns_to_remove = [
r'\d{4}p', # 1080p, 720p等
r'BluRay', 'DVD', 'WEB-DL',
r'x\d{3}', 'H\.?264', 'HEVC',
r'\d{4}\.\d{2}\.\d{2}', # 日期
r'[A-Z][A-Za-z]+-?Team', # 发布组
]

for pattern in patterns_to_remove:
clean_name = re.sub(pattern, '', clean_name, flags=re.IGNORECASE)

# 清理多余字符
clean_name = re.sub(r'[_-]+', ' ', clean_name)
clean_name = re.sub(r'\s+', ' ', clean_name).strip()

return clean_name

3. 上下文记忆管理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class ConversationManager:
"""管理多轮对话上下文"""
def __init__(self, max_context_tokens=4000):
self.history = []
self.max_tokens = max_context_tokens

def add_message(self, role, content):
"""添加消息并维护上下文长度"""
self.history.append({"role": role, "content": content})
self._trim_history()

def _trim_history(self):
"""智能修剪历史记录,保留最重要的对话"""
total_tokens = sum(len(msg["content"]) for msg in self.history)

while total_tokens > self.max_tokens and len(self.history) > 2:
# 移除最旧的非系统消息
for i, msg in enumerate(self.history):
if msg["role"] != "system":
removed = self.history.pop(i)
total_tokens -= len(removed["content"])
break

🎯 Prompt工程

1. 分段发送策略

1
2
3
4
5
6
7
8
9
10
# 第一阶段:告知模型准备接收长内容
initial_prompt = f"""我将分{parts_count}次发送电影《{movie_name}》的完整台词给你。
请你先接收所有台词内容,不要立即分析。
等我发送完所有部分后,我会让你开始分析。

这是第1部分,共{parts_count}部分:
{first_part}

请回复"收到第1部分,等待后续内容。"
"""

2. 格式约束技巧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
analysis_prompt = f"""请根据所有台词内容完成以下分析,严格按照要求的格式输出:

电影名称:{movie_name}
经典台词:
1. [第一句经典台词]
2. [第二句经典台词]
...(必须输出10句)

微小说:[根据台词创作的300字微小说。]

要求(重要指令):
1. 根据你所知道的给出该电影超级简单的介绍
2. 经典台词要选择最具代表性、最打动人心的10句
3. 微小说要基于所有台词的意境和主题创作,保持故事完整性
4. 注意:不要和原电影叙事年代相同,尽量用现在的年代
5. 记得为微小说写题目
6. 禁止:不要输出任何评价性内容,只输出要求的格式内容

严格按照上述格式,不要添加额外说明!"""

3. 角色设定增强效果

1
2
3
4
5
6
7
system_prompt = """你是一位资深的电影评论家和小说作家,具有以下特点:
1. 对电影艺术有深刻理解,能准确把握电影主题
2. 擅长从台词中提炼精华,识别经典对白
3. 具有出色的改编能力,能将经典故事现代化
4. 严格遵守格式要求,输出结构清晰

你的任务是根据提供的电影台词,完成专业分析。"""

4. 分阶段处理长文本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
def create_staged_prompts(movie_name, parts):
"""创建分阶段的prompt序列"""
prompts = []

# 阶段1:建立上下文
prompts.append({
"role": "system",
"content": f"你将接收电影《{movie_name}》的完整台词,请先专心接收,不要分析。"
})

# 阶段2:分段发送内容
for i, part in enumerate(parts, 1):
if i == 1:
content = f"开始发送《{movie_name}》台词,这是第{i}部分:\n\n{part}\n\n请确认收到。"
else:
content = f"继续发送《{movie_name}》台词,第{i}部分:\n\n{part}\n\n请确认收到。"
prompts.append({"role": "user", "content": content})

# 阶段3:分析指令
prompts.append({
"role": "user",
"content": """现在你已经接收了完整台词,请开始分析。注意以下关键要求:
1. 输出10句经典台词,必须编号1-10
2. 微小说要现代背景,300字左右
3. 不要评价,只输出结果"""
})

return prompts

📋 使用示例

输入电影台词文件(如《倩女幽魂2》台词):

1
2
宁采臣:这里阴气太重,我们快走吧。
聂小倩:公子,你可知道前世今生?

输出分析结果:

1
2
3
4
5
6
7
8
电影名称:倩女幽魂2
经典台词:
1. "人间道,鬼道,各有各的轮回"
2. "爱情如果能超越生死,那该多好"
3. ...
微小说:《数字时代的灵异情缘》
2024年,程序员宁晨在修复一个古老的数据库时,
发现了一段被遗忘的AI代码"小倩"...

🚀 快速开始

环境要求

1
pip install openai

配置使用

1
2
3
4
# 简单三步配置
API_KEY = "您的API密钥"
INPUT_FILE_PATH = "电影台词.txt"
MODEL_NAME = "deepseek-ai/DeepSeek-R1"

运行脚本

1
python movie_analysis.py

🎪 项目特色

🔥 技术创新点

  • 智能上下文管理:自动维护对话历史,优化token使用
  • 动态prompt调整:根据输入内容自动调整指令细节
  • 错误恢复机制:网络异常时自动重试,保证任务完成
  • 进度实时反馈:流式输出让用户看到处理过程

🎨 Prompt设计哲学

  1. 明确指令优先:使用编号、强调等让模型准确理解
  2. 格式强制约束:通过具体示例规范输出格式
  3. 分阶段处理:复杂任务拆解为简单步骤
  4. 角色代入法:赋予模型特定角色提升质量

🔧 应用场景

影视行业

  • 剧本分析和优化建议
  • 经典台词数据库建设
  • 跨时代故事改编创意

教育研究

  • 电影文学课程辅助工具
  • 叙事结构分析研究
  • 跨文化影视对比

个人兴趣

  • 观影笔记智能整理
  • 电影主题深度理解
  • 创意写作灵感来源

📊 项目亮点

  1. 智能化程度高:自动识别电影、分析主题、提取精华
  2. 创作能力强:不仅能分析,还能创作全新内容
  3. 用户体验好:一键式操作,结果清晰易懂
  4. 扩展性强:支持多种AI模型和API平台
  5. 实用价值大:适合影视爱好者、创作者、研究者

一个简单高效的Python工具,用于清理ASS和SRT字幕文件,提取纯文本台词,去除所有格式标记、时间码和特效代码。

🎯 项目简介

在日常的视频处理、字幕制作或文本分析工作中,我们经常需要从字幕文件中提取纯文本内容。然而,原始的字幕文件包含大量的格式信息(如时间码、样式定义、特效代码等),这些信息会干扰我们对纯文本内容的使用。这个工具可以自动批量处理ASS和SRT字幕文件,提取干净的台词文本。

✨ 主要功能

  • 支持多种格式:自动识别并处理ASS和SRT两种主流字幕格式
  • 智能清理
    • ASS文件:去除[Script Info][V4 Styles]Format:等格式信息
    • SRT文件:去除序号、时间码行(如00:00:24,290 --> 00:00:27,700
    • 通用处理:去除所有花括号内的特效代码(如{\3c&HFF8000&}
  • 批量处理:一键处理整个文件夹中的所有字幕文件
  • 编码兼容:自动检测并处理UTF-8、GBK、GB2312、UTF-16等多种编码
  • 保持原结构:按原始文件名生成对应的清理后文件

📁 项目结构

1
2
3
4
5
6
7
8
9
10
subtitle-cleaner/
├── clean_subtitles.py # 主程序文件
├── download_srt/ # (输入)原始字幕文件存放目录
│ ├── video1.ass
│ ├── video2.srt
│ └── ...
└── cleaned_srt/ # (输出)清理后的文本文件目录
├── video1_cleaned.txt
├── video2_cleaned.txt
└── ...

🚀 快速开始

安装要求

  • Python 3.6+
  • 无需安装额外依赖库

使用方法

  1. 准备文件:将所有要处理的ASS和SRT字幕文件放入download_srt文件夹

  2. 运行脚本

    1
    python clean_subtitles.py
  3. 查看结果:清理后的纯文本文件将保存在cleaned_srt文件夹中

运行示例

1
2
3
4
5
6
7
8
9
10
11
12
输入文件夹: download_srt
输出文件夹: cleaned_srt
开始处理字幕文件...
已处理: example.ass -> example_cleaned.txt
生成台词: 5 行
前几句台词:
1. 明朝景泰年间 宦官专权
2. 在京城设立十二监 十三库
3. 四司 八局及二十四衙门
--------------------------------------------------
处理完成!共处理 1 个字幕文件
清理后的文件保存在: cleaned_srt

🔧 技术特点

ASS文件处理逻辑

  1. 只提取以Dialogue:开头的行
  2. 分割并获取第10个逗号后的文本内容
  3. 去除所有{...}格式的特效代码

SRT文件处理逻辑

  1. 跳过纯数字的序号行
  2. 跳过包含-->的时间码行
  3. 保留纯文本台词行,同样去除特效代码

编码处理机制

脚本会自动尝试多种编码格式读取文件:

  • UTF-8
  • GBK
  • GB2312
  • UTF-16

💡 应用场景

  1. 视频内容分析:提取视频对话用于文本分析
  2. 字幕翻译辅助:获取干净文本进行翻译
  3. 学习笔记制作:从教学视频中提取讲解内容
  4. 内容摘要生成:基于字幕文本生成视频摘要
  5. 语音识别校对:对比语音识别结果与原始字幕

📝 代码示例

核心清理函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
def clean_srt_content(content):
"""清理SRT字幕文件内容"""
lines = content.split('\n')
cleaned_lines = []
i = 0
n = len(lines)

while i < n:
line = lines[i].strip()

# 跳过序号行和时间码行
if line.isdigit() or '-->' in line:
i += 1
continue

# 保留并清理台词行
if line:
line = re.sub(r'\{[^}]*\}', '', line)
line = line.strip()
if line:
cleaned_lines.append(line)

i += 1

return '\n'.join(cleaned_lines)

🔄 扩展性

项目具有良好的扩展性,可以轻松添加以下功能:

  1. 支持更多字幕格式:如SSA、VTT等
  2. 添加文本后处理:如去除广告词、标准化标点
  3. 集成翻译API:自动翻译提取的文本
  4. 导出多种格式:如JSON、CSV、Markdown

📊 性能特点

  • 高效处理:单文件处理时间通常在毫秒级
  • 内存友好:逐行处理,避免大文件内存溢出
  • 容错性强:单个文件出错不影响其他文件处理
  • 日志详细:实时显示处理进度和结果预览

这是一个用于自动化下载字幕网站字幕文件的Python爬虫工具。是一个知名的字幕分享网站,但手动下载大量字幕文件比较繁琐。这个工具可以自动批量下载字幕文件,支持日期页面和顺序页面两种URL格式,每个页面只下载第一个可用的字幕文件。

功能特点

🚀 核心功能

  • 自动登录:使用Cookie实现免验证码登录
  • 批量下载:支持批量下载日期页面和顺序页面的字幕文件
  • 智能解析:自动解析页面结构,定位下载链接
  • 文件名处理:自动处理中文乱码,保持原始文件名
  • 速率控制:可配置的下载间隔,减轻服务器负担

📁 支持的格式

  • 字幕文件:.srt, .ass, .ssa, .sub
  • 压缩包:.zip, .rar, .7z

🔧 技术特性

  • 使用Requests库进行HTTP请求
  • 使用BeautifulSoup解析HTML
  • 自动处理Cookie会话
  • 智能编码转换,解决中文乱码问题
  • 完善的错误处理和日志记录

安装与配置

环境要求

  • Python 3.6+
  • 依赖库:
    1
    pip install requests beautifulsoup4

配置文件

  1. 在代码中设置Cookie:

    1
    cookie = "PHPSESSID=your_session_id; zmk_home_view_subid=your_subid; security_session_verify=your_verify"
  2. 配置下载参数:

    • 下载间隔:self.delay = 5(默认5秒)
    • 保存目录:self.download_dir = "download_srt"

使用方法

基本用法

1
2
3
4
5
6
7
8
# 创建下载器实例
downloader = SubtitleDownloader(cookie)

# 下载日期页面字幕
downloader.download_from_date_pages(start_year=2024, start_month=3, end_month=12)

# 下载顺序页面字幕
downloader.download_from_sequence_pages(start_id=151336, end_id=151400)

命令行运行

1
python spider_.py

项目结构

1
2
3
4
5
6
7
8
9
spider_.py
├── SubtitleDownloader类
│ ├── __init__() # 初始化,设置Cookie和headers
│ ├── decode_filename() # 解码文件名,处理乱码
│ ├── download_subtitle() # 下载单个字幕文件
│ ├── parse_page() # 解析页面获取下载链接
│ ├── download_from_date_pages() # 批量下载日期页面
│ └── download_from_sequence_pages() # 批量下载顺序页面
└── main()函数 # 程序入口

详细配置说明

Cookie获取方法

  1. 使用浏览器登录网站
  2. 打开开发者工具(F12)
  3. 在Application/Cookies中查找相关Cookie
  4. 复制完整的Cookie字符串

页面URL格式

  1. 日期页面https://.org/dld/202403.html

    • 格式:YYYYMM.html
    • 示例:202403表示2024年3月
  2. 顺序页面https://.org/dld/151336.html

    • 格式:数字ID.html
    • ID范围可自定义

下载策略

  • 每个页面只下载第一个有效链接
  • 遇到”该字幕不可下载!”提示时跳过
  • 文件名重复时自动添加序号
  • 默认5秒下载间隔,避免被封禁

高级功能

自定义下载范围

1
2
3
4
5
# 下载2024年全年的字幕
downloader.download_from_date_pages(start_year=2024, start_month=1, end_month=12)

# 下载大量顺序页面
downloader.download_from_sequence_pages(start_id=150000, end_id=160000)

错误处理

  • 自动检测无效页面
  • 网络异常重试
  • 详细的错误日志输出

性能优化

  • 会话保持,减少登录开销
  • 流式下载,节省内存
  • 智能编码检测,提高兼容性

注意事项

⚠️ 使用限制

  1. 遵守robots.txt:请尊重网站的爬虫协议
  2. 合理使用:避免高频请求,建议保持5秒以上间隔
  3. 版权尊重:仅用于个人学习研究,请勿用于商业用途
  4. 账号安全:不要分享个人Cookie信息

🔒 隐私保护

  • Cookie信息本地存储,不上传任何服务器
  • 仅下载公开可访问的字幕文件
  • 不收集用户个人信息

故障排除

常见问题

  1. 下载失败:检查网络连接和Cookie有效性
  2. 文件名乱码:自动解码功能会处理大多数情况
  3. 找不到链接:确认页面结构是否变化,可能需要调整选择器

调试方法

启用详细日志:

1
2
# 在parse_page()方法中添加调试信息
print(f"页面响应:{response.text[:500]}")

扩展开发

添加新功能

  1. 代理支持:在session中配置代理
  2. 多线程下载:使用concurrent.futures模块
  3. 断点续传:记录已下载的文件ID
  4. GUI界面:使用tkinter或PyQt5
0%