Files
Jack f1ce583fd1 feat: 发布三笙AI情报局独立版公司研发基线
同步家纺情报 v2 数据、59 个严格权威源、趋势图库、移动端交互、Google/Yandex 翻译门控及静态 SEO/GEO 构建。

补充面向 C# 研发的 README,明确当前无 LLM、多模态与生图模型,记录翻译请求参数、缓存与失败策略、数据处理边界、前端职责和无 GitHub Pages 部署流程。

新增按日期倒序维护的 CHANGELOG,记录影响、验证与代码/数据/dist 回滚方法。

验证:11 个 Python 契约测试、13 个 Node 前端测试通过;静态构建生成 1096 个 Sitemap URL。
2026-08-14 19:26:39 +08:00

94 lines
4.1 KiB
Python

"""家纺与时装 RSS 来源及相关性筛选。"""
from __future__ import annotations
import re
from typing import Any
FASHION_TREND_FEEDS: list[dict[str, Any]] = [
{
"name": "Hypebeast 中文",
"url": "https://hypebeast.cn/fashion/feed",
"category": "时装趋势",
"category_key": "fashion_trends",
},
{
"name": "GQ Hong Kong",
"url": "https://gqhongkong.com/style/feed/",
"category": "时装趋势",
"category_key": "fashion_trends",
},
{
"name": "Citta Bella 都会佳人",
"url": "https://cittabella.my/category/fashion/feed/",
"category": "时装趋势",
"category_key": "fashion_trends",
},
]
CURATED_TREND_PAGES: list[dict[str, str]] = [
{
"name": "ASInsight",
"url": "https://www.asinsight.com/report/US/cooling-duvet-cover",
"category": "趋势博客",
"category_key": "trend_blogs",
},
]
FREE_TREND_FEEDS: list[dict[str, Any]] = [
{"name": "Dezeen - Textiles", "url": "https://www.dezeen.com/tag/textiles/feed/"},
{"name": "Dezeen - Fashion", "url": "https://www.dezeen.com/tag/fashion-tag/feed/"},
{"name": "Dezeen - Clothing", "url": "https://www.dezeen.com/tag/clothing/feed/"},
{"name": "Dezeen - Homeware", "url": "https://www.dezeen.com/tag/homeware/feed/"},
{"name": "ArchDaily - Fabrics", "url": "https://www.archdaily.com/tag/fabrics/feed/"},
{"name": "Trendland", "url": "https://trendland.com/feed/"},
{"name": "Design Milk", "url": "https://design-milk.com/feed/"},
{"name": "Designboom", "url": "https://www.designboom.com/feed/"},
{"name": "Fibre2Fashion - Textiles", "url": "https://feeds.feedburner.com/fibre2fashion/textile-news"},
{"name": "Fibre2Fashion - Fashion", "url": "https://feeds.feedburner.com/fibre2fashion/fashion-news"},
] + FASHION_TREND_FEEDS
FASHION_REFERENCE_KEYWORDS: tuple[str, ...] = (
"runway", "lookbook", "fashion week", "couture", "ready-to-wear", "menswear", "womenswear",
"tailoring", "apparel", "garment", "outfit", "textile", "fabric",
"embroidery", "knit", "woven", "jacquard", "denim", "dress", "shirt", "jacket", "coat",
"trousers", "pants", "skirt", "suit", "home textile", "bedding", "bed linen",
"時裝", "时装", "秀場", "秀场", "時裝週", "时装周", "大秀", "春夏", "秋冬",
"男裝", "男装", "女裝", "女装", "成衣", "高訂", "高定", "型錄", "型录",
"服裝", "服装", "服飾", "服饰", "穿搭", "剪裁", "廓形", "面料", "布料",
"織物", "织物", "印花", "刺繡", "刺绣", "針織", "针织", "提花", "牛仔",
"西裝", "西装", "襯衫", "衬衫", "外套", "洋裝", "洋装", "紡織", "纺织",
"家紡", "家纺", "床品", "床上用品",
)
SURFACE_DESIGN_KEYWORDS: tuple[str, ...] = (
"pattern", "texture", "motif", "surface design", "紋樣", "纹样", "圖案", "图案",
"紋理", "纹理", "肌理", "流行趨勢", "流行趋势",
)
NON_TEXTILE_TITLE_KEYWORDS: tuple[str, ...] = (
"watch", "watches", "jewelry", "jewellery", "eyewear", "sunglasses", "handbag", "footwear",
"sneaker", "perfume", "fragrance", "cosmetic", "腕表", "腕錶", "手表", "手錶", "珠宝", "珠寶",
"首饰", "首飾", "眼镜", "眼鏡", "太阳镜", "太陽鏡", "包袋", "手袋", "手包", "鞋", "靴",
"香水", "香氛", "彩妆", "彩妝", "美妆", "美妝",
)
def is_fashion_reference(title: str, content: str) -> bool:
"""判断内容是否具备服装、秀场或纺织设计参考价值。"""
title_text = title.lower()
haystack = f"{title} {content}".lower()
def contains(text: str, keyword: str) -> bool:
token = keyword.lower()
if token.isascii():
return re.search(rf"(?<![a-z]){re.escape(token)}(?![a-z])", text) is not None
return token in text
if any(contains(title_text, keyword) for keyword in NON_TEXTILE_TITLE_KEYWORDS):
return False
if any(contains(haystack, keyword) for keyword in FASHION_REFERENCE_KEYWORDS):
return True
return any(contains(title_text, keyword) for keyword in SURFACE_DESIGN_KEYWORDS)