Files
omni-parse/tools/wave_cn.py
ENI 2320acf3c5
Some checks failed
ci / test (3.10) (push) Has been cancelled
ci / test (3.11) (push) Has been cancelled
ci / test (3.12) (push) Has been cancelled
vault ключей + мост abuse-radar + китайские источники: всё в одном реестре
- omni/vault.py: пул ключей парсеров (env-first, data/vault.json, ротация, cooldown 401/402/403=1ч, 429=10м), только маски в выводе
- tools/build_vault.py: сборка пула из MASTER_KEYS.csv и локальных дампов (значения не в git)
- tools/vault_check.py: живая проверка с маскированием
- searchers: firecrawl/tavily/exa/serper/jina/apify берут ключ из vault, если нет env
- omni radar: домены+каналы из radar_server.db -> реестр, --import-posts заливает посты каналов
- radar-источники помечены opt_in: общий обход не тормозят (869 против 3337 всего)
- omni/sources_cn.py + tools/wave_cn.py: 9 живых китайских источников (52pojie, nodeseek, kanxue, anquanke, 4hou, xz.aliyun, ithome, cnbeta, v2ex)
- net.get(proxy=...): принудительный прокси для CF-площадок
- /api/keys + строка ключей в панели
- tests/test_vault_radar.py: 7 тестов, всего 29 passed
2026-10-26 23:31:37 +03:00

86 lines
4.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Волна по китайским/азиатским источникам: форумы, реверс, security-новости.
Проверяет кандидатов живыми запросами (лента / список тем), пишет живые в
omni/sources_cn.py. Запуск: python tools/wave_cn.py [--apply]
"""
import sys
import time
from pathlib import Path
import requests
ROOT = Path(__file__).resolve().parents[1]
OUT = ROOT / "omni" / "sources_cn.py"
UA = ("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/131.0 Safari/537.36")
# name, url, adapter, category, tags, limit
CAND = [
("cn_52pojie", "https://www.52pojie.cn/forum.php?mod=guide&view=new", "html_listing", "forum", ("cn", "reverse", "abuse"), 20),
("cn_nodeseek", "https://www.nodeseek.com/", "html_listing", "forum", ("cn", "hosting"), 20),
("cn_freebuf", "https://www.freebuf.com/", "html_listing", "security", ("cn", "security"), 20),
("cn_seebug", "https://paper.seebug.org/", "html_listing", "security", ("cn", "papers", "security"), 15),
("cn_anquanke", "https://www.anquanke.com/", "html_listing", "security", ("cn", "security"), 20),
("cn_4hou", "https://www.4hou.com/", "html_listing", "security", ("cn", "security"), 15),
("cn_kanxue", "https://bbs.kanxue.com/", "html_listing", "forum", ("cn", "reverse"), 20),
("cn_ithome", "https://www.ithome.com/rss/", "rss", "news", ("cn", "tech"), 20),
("cn_cnbeta", "https://www.cnbeta.com.tw/backend.php", "rss", "news", ("cn", "tech"), 20),
("cn_sspai", "https://sspai.com/feed", "rss", "news", ("cn", "tech"), 15),
("cn_chiphell", "https://www.chiphell.com/forum.php?mod=guide&view=new", "html_listing", "forum", ("cn", "hardware"), 15),
("cn_52pojie_rss", "https://www.52pojie.cn/forum.php?mod=rss", "rss", "forum", ("cn", "reverse"), 15),
("cn_v2ex_rss", "https://www.v2ex.com/index.xml", "rss", "forum", ("cn", "community"), 20),
("cn_linuxdo_rss", "https://linux.do/latest.rss", "rss", "forum", ("cn", "community", "ai"), 20),
("cn_hostloc_rss", "https://hostloc.com/forum.php?mod=rss", "rss", "forum", ("cn", "hosting"), 15),
("cn_baidu_sec", "https://xz.aliyun.com/", "html_listing", "security", ("cn", "security"), 15),
("cn_secfree", "https://www.secfree.com/", "html_listing", "security", ("cn", "security"), 10),
("cn_tttang", "https://tttang.com/", "html_listing", "security", ("cn", "security"), 10),
]
def probe(url, adapter="html_listing"):
try:
r = requests.get(url, headers={"User-Agent": UA}, timeout=18, allow_redirects=True)
except Exception as e:
return 0, type(e).__name__, 0
if adapter == "rss":
n_links = r.text.count("<item") + r.text.count("<entry")
else:
n_links = r.text.count("<a ")
return r.status_code, "", n_links
def main():
apply = "--apply" in sys.argv
live, dead = [], []
for name, url, adapter, cat, tags, lim in CAND:
code, err, links = probe(url, adapter)
ok = code == 200 and links >= 30
print("%-18s %-3s links %-5d %s" % (name, code or err, links, "LIVE" if ok else "—"))
if ok:
live.append((name, url, adapter, cat, tags, lim))
else:
dead.append(name)
time.sleep(0.8)
print("\nживых %d, мёртвых %d" % (len(live), len(dead)))
if not apply:
print("dry-run: --apply чтобы записать omni/sources_cn.py")
return 0
body = ['"""Китайские и азиатские источники (проверены живыми запросами tools/wave_cn.py).',
'', 'Форумы реверса/хостинга, security-новости, tech-ленты. Все — публичные списки,',
'без ключей и кук. Подключаются в реестр omni как категории forum/security/news.',
'"""', '', 'CN = [']
for name, url, adapter, cat, tags, lim in live:
t = ", ".join('"%s"' % x for x in tags)
body.append(' {"name": "%s", "category": "%s", "kind": "site", "url": "%s",'
' "adapter": "%s", "tags": (%s), "limit": %d},' % (name, cat, url, adapter, t, lim))
body.append(']')
OUT.write_text("\n".join(body) + "\n", encoding="utf-8", newline="\n")
print("записано", OUT, "| источников", len(live))
return 0
if __name__ == "__main__":
sys.exit(main())