浏览本文有很可能会触犯所在地区法律,请三思而后行。


身为一名老司机,管理自己的影片库存是一件很大的事。恰好 Windows 有丰富的文件元数据管理,可将影片的演员和标题写入元数据,便能实现在文件管理器中按其排序或筛选等。

最终效果如图,需要勾选对应的元数据
最终效果如图,需要勾选对应的元数据

我选择的的刮削网站是,因为不带封面图,加载起来比较快。需要注意,这个网站只包括 DMM 和 FANZA 的 JAV 影片,不含无码和 FC2 等。运行前需要安装 ExifTool(终端执行 winget install exiftool)和 ffmpeg(终端执行 winget install ffmpeg),并把 Windows 的语言编码改为 UTF-8(可参阅修改 windows 终端 cmd 控制台默认编码为 utf-8 - luckyangg - 博客园)。下面是代码和讲解。

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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import re
import os
import pathlib
import requests
import shutil
import subprocess
from bs4 import BeautifulSoup
from tkinter import filedialog

# 刮削
def scrape(movie_id):
url = f"https://javtxt.com/search?type=id&q={movie_id}"
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"}

# 设置 HTTP 或 SOCKS5 代理(根据需要修改)
proxies = {
"http": "http://localhost:7890",
"https": "http://localhost:7890",
}

response = requests.get(url, headers=headers, proxies=proxies, timeout=10)
if response.status_code != 200:
print(f"请求失败,状态码: {response.status_code}")
return None

soup = BeautifulSoup(response.text, "html.parser")

work = soup.find("a", class_="work")
if not work:
print("未找到影片信息")
return {}

# 标题
title = work.find("h4", class_="work-title").text.strip()
# 演员(多个则按,分割)
artist = work.find("div", class_="work-actresses").text.strip()
artist = ",".join(artist.split())

return {"标题": title, "演员": artist}

# 正则表达式匹配番号
def recognize(s):
pattern = r"([a-zA-Z]{2,}[-_ ]?[0-9]{2,}[-_0-9]{0,})"
match = re.findall(pattern, s)
if not match:
pattern = r"([n][0-9]{4,})"
match = re.findall(pattern, s)
if not match:
pattern = r"([0-9]{3,}[-_]?[0-9]{0,})"
match = re.findall(pattern, s)

if match:
temp = match[-1]
if "_" in temp:
temp = temp.replace("_", "-")
if temp[-1] == "-":
temp = temp[:-1]

# 把 abc123 修改为 abc-123
pattern = r"^([a-zA-Z]{3,})([0-9]{3,})$"
match = re.match(pattern, temp)
if match:
temp = match.group(1) + "-" + match.group(2)

return temp
else:
return None


# 遍历mp4
def scanDir(dir):
dir = pathlib.Path(dir)
return dir.glob("*.mp4")

# 要遍历的文件夹
origin_folder = filedialog.askdirectory(title="请选择一个文件夹")
print(origin_folder)
exit(0) if len(origin_folder) == 0 else 0

# 移动到目标文件夹
target_folder = r""

# 遍历
for i in scanDir(origin_folder):
movie_id = recognize(i.stem)
metadata = scrape(movie_id)
if metadata:
title = metadata["标题"]
artist = metadata["演员"]
else:
continue

try:
try:
# 先使用exiftool
t = subprocess.run(
f'exiftool "{i}" -Title="{title}" -Artist="{artist}" -overwrite_original -api largefilesupport=1',
shell=True,
check=True,
encoding="utf-8",
stdout=subprocess.PIPE,
)
shutil.move(i, target_folder)
print("\033[0;32msuccess\n\033[0m")
# 失败则使用ffmpeg
except subprocess.CalledProcessError:
print(f"try to use ffmpeg {i}")
t = subprocess.run(
f'ffmpeg -i "{i}" -metadata title="{title}" -metadata artist="{artist}" -c copy "{target_folder}\\{i.name}"',
shell=True,
check=True,
encoding="utf-8",
stdout=subprocess.PIPE,
)
os.remove(i)
print("\033[0;32msuccess\n\033[0m")
# 其他失败
except Exception as e:
print(f"\033[0;31merror {e}\n \033[0m")

# 检查有无遗漏
moives = []
for path, subdirs, files in os.walk(origin_folder):
for name in files:
filename = os.path.join(path, name)
if not name.startswith(".") and os.path.splitext(filename)[1] in [".mp4", ".MP4"]:
moives.append(filename)
if len(moives):
pass
else:
print("未处理的影片:")
for moive in moives:
print(moive)


网站地图 | 状态监测 | 全球节假日日历 | 皮带张力测试 | File Server | 博友圈 | 博客说
Copyright 2022-2026 | Powered by Hexo 7.3.0 & Stellar 1.33.1
总访问量次 |