diff --git a/app/modules/themoviedb/scraper.py b/app/modules/themoviedb/scraper.py
index ff6768bdb..a785d9767 100644
--- a/app/modules/themoviedb/scraper.py
+++ b/app/modules/themoviedb/scraper.py
@@ -233,6 +233,15 @@ class TmdbScraper:
return _episode_info
return {}
+ @staticmethod
+ def __normalize_tmdb_id(value: object) -> Optional[int]:
+ """将外部集数据中的 TMDB ID 规范化为正整数。"""
+ try:
+ normalized = int(str(value).strip())
+ except (TypeError, ValueError):
+ return None
+ return normalized if normalized > 0 else None
+
@staticmethod
def __gen_common_nfo(
mediainfo: MediaInfo, doc: minidom.Document, root: minidom.Element
@@ -404,12 +413,13 @@ class TmdbScraper:
doc = minidom.Document()
root = DomUtils.add_node(doc, doc, "episodedetails")
# TMDBID
- uniqueid = DomUtils.add_node(doc, root, "uniqueid", str(episodeinfo.get("id")))
- uniqueid.setAttribute("type", "tmdb")
- uniqueid.setAttribute("default", "true")
- # tmdbid
- # 应与uniqueid一致 使用剧集id 否则jellyfin/emby会将此id覆盖上面的uniqueid
- DomUtils.add_node(doc, root, "tmdbid", str(episodeinfo.get("id")))
+ episode_tmdb_id = TmdbScraper.__normalize_tmdb_id(episodeinfo.get("id"))
+ if episode_tmdb_id:
+ uniqueid = DomUtils.add_node(doc, root, "uniqueid", str(episode_tmdb_id))
+ uniqueid.setAttribute("type", "tmdb")
+ uniqueid.setAttribute("default", "true")
+ # 应与uniqueid一致,使用剧集id否则Jellyfin/Emby会覆盖上面的uniqueid。
+ DomUtils.add_node(doc, root, "tmdbid", str(episode_tmdb_id))
# 标题
DomUtils.add_node(
doc, root, "title", episodeinfo.get("name") or "第 %s 集" % episode
diff --git a/tests/test_tmdb_episode_nfo.py b/tests/test_tmdb_episode_nfo.py
new file mode 100644
index 000000000..e09d8bae5
--- /dev/null
+++ b/tests/test_tmdb_episode_nfo.py
@@ -0,0 +1,26 @@
+import pytest
+
+from app.modules.themoviedb.scraper import TmdbScraper
+
+
+@pytest.mark.parametrize(
+ ("episode_id", "expected_tmdb_id"),
+ ((None, None), ("None", None), ("not-a-number", None), (129, "129")),
+)
+def test_episode_nfo_omits_invalid_tmdb_id(episode_id, expected_tmdb_id):
+ """集查询返回无效 ID 时应省略身份节点,但保留其余集元数据。"""
+ document = TmdbScraper._TmdbScraper__gen_tv_episode_nfo_file(
+ tmdbid=100,
+ episodeinfo={"id": episode_id, "name": "测试集"},
+ season=2,
+ episode=3,
+ )
+
+ xml = document.toxml()
+ if expected_tmdb_id is None:
+ assert "