feat(monitor): 关掉链接校验 —— 认不出来的目标原样收下
以前新建任务粘目标时是白名单校验:链接形状不匹配平台的规则就拒收(「无法从链接中 解析出博主主页 ID」/「无法识别的目标」),而 v.douyin.com 那种分享短链是**明确** 拒绝的。平台一改链接形状,用户粘一个完全正确的链接也只能干瞪眼。 现在认不出来的一律原样存下(截到 128 字符,external_id 是 varchar(128),而带参数的 完整链接常常 130+)。只留两件不能省的事: * 空值仍然拒收 —— 空目标连库都写不进去; * **不许跨平台误抠** —— 小红书的正则不会从抖音链接里抠出一个 id。那是「看起来正常 但完全错误」的目标,比原样存更糟。这条有测试钉着。 代价(已知并接受):认不出的值会变成永远抓不到东西的目标。好在不静默 —— 跑完一轮 ingest 会发现「一条都没抓到」并报出来,而且会先排除登录问题。 顺带删掉 short_link_hosts:现在没人读它了,留着会让下一个人以为短链还是被拒的。
This commit is contained in:
@@ -82,9 +82,6 @@ class PlatformAdapter:
|
||||
# 也允许直接粘贴裸 id —— 但两边的 id 形状不同,所以分开。
|
||||
creator_bare_re: Pattern
|
||||
note_bare_re: Pattern
|
||||
# 短链(v.douyin.com 这种)无法在不发请求的情况下还原出 id,解析时单独报错,
|
||||
# 好过存一个聚不出目标的值进去。
|
||||
short_link_hosts: Tuple[str, ...]
|
||||
|
||||
note_fields: Mapping[str, str]
|
||||
comment_fields: Mapping[str, str]
|
||||
@@ -155,7 +152,6 @@ XHS = PlatformAdapter(
|
||||
),
|
||||
creator_bare_re=_XHS_BARE_RE,
|
||||
note_bare_re=_XHS_BARE_RE,
|
||||
short_link_hosts=(),
|
||||
note_fields={
|
||||
"note_id": "note_id",
|
||||
"title": "title",
|
||||
@@ -204,7 +200,6 @@ DY = PlatformAdapter(
|
||||
# 又不会把 19 位的作品号误当成博主。
|
||||
creator_bare_re=re.compile(r"^[A-Za-z0-9_-]{20,128}$"),
|
||||
note_bare_re=re.compile(r"^\d{8,25}$"),
|
||||
short_link_hosts=("v.douyin.com",),
|
||||
note_fields={
|
||||
"note_id": "aweme_id",
|
||||
"title": "title",
|
||||
|
||||
+28
-14
@@ -96,9 +96,20 @@ def parse_target_input(
|
||||
Storing the id separately from the token is what keeps a long-running task
|
||||
alive: tokens expire, ids do not.
|
||||
|
||||
URL shapes are platform-specific and come from ``adapters``. A platform with
|
||||
no adapter is rejected here as well as at task creation -- parsing a Douyin
|
||||
link as if it were a Xiaohongshu one would be worse than refusing it.
|
||||
**认不出来的一律原样存下,不报错。**(2026-10-12 按用户要求关掉了链路校验。)
|
||||
以前这里是白名单:链接不匹配平台的形状就拒收。问题是平台一改链接形状,用户粘一个
|
||||
完全正确的链接也只能干瞪眼 —— 而拒收换来的那点保护,代价是「任务建不出来」。
|
||||
|
||||
现在只保留两件不能省的事:
|
||||
|
||||
* **空值仍然拒收** —— 空目标连库都写不进去;
|
||||
* **不许跨平台误抠** —— 小红书的正则不会从抖音链接里抠出一个 id 来。那会造出一个
|
||||
**看起来正常但完全错误**的目标,比原样存下来糟得多。
|
||||
|
||||
平台没有适配器仍然拒收:那不是校验链接,是「这个平台我们根本采不了」。
|
||||
|
||||
代价(已知并接受):认不出的值会变成一个永远抓不到东西的目标。好在那不会静默 ——
|
||||
跑完一轮 ingest 就会发现「一条都没抓到」并报出来。
|
||||
"""
|
||||
if not adapters.has_adapter(platform):
|
||||
raise TargetParseError(f"暂不支持解析该平台({platform})的目标链接")
|
||||
@@ -109,26 +120,29 @@ def parse_target_input(
|
||||
raise TargetParseError("Empty target")
|
||||
|
||||
creator_mode = mode == MODE_CREATOR
|
||||
expected = "博主主页" if creator_mode else "笔记"
|
||||
|
||||
external_id = ""
|
||||
if raw.startswith("http") or "/" in raw:
|
||||
if any(host in raw for host in spec.short_link_hosts):
|
||||
# 短链要联网跳一次才知道指向谁,而这里没有网络可跳。明确拒绝好过存一个
|
||||
# 解析不出 id 的值 —— 那会变成一个永远抓不到东西、还不报错的任务。
|
||||
raise TargetParseError(f"{expected}短链无法解析,请粘贴完整链接:{raw}")
|
||||
patterns = spec.creator_url_res if creator_mode else spec.note_url_res
|
||||
for pattern in patterns:
|
||||
match = pattern.search(raw)
|
||||
if match:
|
||||
external_id = match.group(1)
|
||||
break
|
||||
if not external_id:
|
||||
raise TargetParseError(f"无法从链接中解析出{expected} ID:{raw}")
|
||||
elif (spec.creator_bare_re if creator_mode else spec.note_bare_re).match(raw):
|
||||
external_id = raw
|
||||
else:
|
||||
raise TargetParseError(f"无法识别的目标:{raw}")
|
||||
|
||||
# **认不出来就原样存,不拦。**(2026-10-12 按用户要求关掉校验。)
|
||||
#
|
||||
# 代价必须写在明处:`external_id` 是采集时**唯一**拿去请求的东西,所以一个认不出的
|
||||
# 值会变成一个「永远抓不到东西」的目标。好在不会静默 —— 那一轮跑完 ingest 会发现
|
||||
# 「一条都没抓到」并报出来,而且会先排除登录问题(其他任务正常时提示检查这个目标)。
|
||||
#
|
||||
# 之所以能接受:解析规则是**平台相关的白名单**(比如抖音博主链接必须含
|
||||
# `douyin.com/user/`,`v.douyin.com` 那种分享短链现在也放行),平台一改形状就会把
|
||||
# 正常链接拦在外面 —— 而拦在门外时用户只能干瞪眼,放进来至少还有得查。
|
||||
if not external_id:
|
||||
# `external_id` 是 varchar(128),而带参数的完整链接常常就 130+ 字符
|
||||
# (抖音 sec_uid 本身 66 位)。不截断的话这一条会直接写库失败。
|
||||
external_id = raw[:128]
|
||||
|
||||
params = parse_qs(urlparse(raw).query) if raw.startswith("http") else {}
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user