Files
pod_trend_agent/pinterest_scraper/scraper.py
T
3218485270 3dc594cf57 v92-v105 多国适配 + 模板导出增强 + 生图可靠性优化
- 新增韩国(KR)适配:countries/pinterest 种子词、K-pop 提示词、UI 国家列表
- 爬虫跨运行持久化已采集 URL(.collected_urls.json),同关键词重复搜索采新图
- 模板导出增强:SPU 商品属性列名前缀剥离匹配、尺码下拉框 INDIRECT 动态引用、
  SPU 字段映射(袖长/门襟/胸垫等)、季节/印花图案女装映射、建议售价统一必填、
  SKU 分类/数量/单位直接填默认值
- 自定义模式:多模态提示词独立(custom_analyze_*)、生图提示词模板可配置
- Pinterest:空选品守卫、连续空分析保护(max_empty_analyze)、flat_prompt 配置覆盖
- 生图可靠性:开始/完成进度日志、异步任务轮询超时 60s→300s
2026-08-31 18:35:51 +08:00

90 lines
4.1 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.
"""Pinterest 爬取封装:把 pinterest_image_capture 的 CLI 逻辑封装成可调用函数,供 UI/节点后台线程调用。
用法:
from pinterest_scraper.scraper import scrape_pinterest
files = scrape_pinterest("vintage 70s", count=40, save_dir="output/pinterest_ref/US/vintage_70s")
增量续采:每个 save_dir 下维护 .collected_urls.json(该关键词历史已采集 URL 集合)。
重复搜索同一关键词时自动跳过旧图、往下拉采集新图,避免反复下载顶部重复图片。
"""
import asyncio
import json
import os
from pathlib import Path
from typing import List, Optional, Set
from pinterest_scraper.pinterest_image_capture import (
detect_proxy,
download_all,
get_system_proxy,
scrape,
)
def _load_collected_urls(save_dir: str) -> Set[str]:
"""读该关键词历史已采集 URL.collected_urls.json),不存在/损坏返回空集。"""
p = Path(save_dir) / ".collected_urls.json"
if not p.exists():
return set()
try:
data = json.loads(p.read_text(encoding="utf-8"))
return {str(u) for u in data if str(u).strip()}
except Exception: # noqa: BLE001
return set()
def _save_collected_urls(save_dir: str, urls: Set[str]) -> None:
"""把已采集 URL 集合持久化到 .collected_urls.json(供下次增量续采)。"""
try:
p = Path(save_dir) / ".collected_urls.json"
p.write_text(json.dumps(sorted(urls), ensure_ascii=False), encoding="utf-8")
except Exception as e: # noqa: BLE001
print(f"[pinterest] 已采集 URL 持久化失败: {e}")
def scrape_pinterest(keyword: str, count: int = 40, save_dir: Optional[str] = None,
proxy: Optional[str] = None, headless: bool = False,
cdp_url: Optional[str] = None,
login_wait: bool = False) -> List[str]:
"""按关键词爬取 Pinterest 图片并下载到 save_dir,返回下载成功的文件路径列表。
- proxy 为 None 时自动探测(环境变量/系统代理/本地常见端口);空字符串显式禁用。
- login_wait=False(默认):运行时检测到未登录时不阻塞,直接返回空列表(由调用方跳过并告警);
login_wait=True:弹出 Chrome 窗口等待手动登录一次,登录态缓存在
pinterest_scraper/.chrome_session,之后自动复用。
- 增量续采:读取 save_dir/.collected_urls.json 历史已采集 URL,滚动时跳过旧图往下拉,
只下载新图,并把新 URL 合并写回(种子词用尽复用同一关键词时自动采集更靠后的新图)。
"""
# 代理解析:显式传入 > 自动探测 > 直连
if proxy is None:
proxy = detect_proxy() or get_system_proxy()
if proxy:
print(f"[pinterest] 使用代理: {proxy}")
else:
print("[pinterest] 未检测到代理,将直连(如无法访问请手动指定代理)")
proxy = proxy or None
out = save_dir or os.path.join(os.getcwd(), "output", "img", keyword)
os.makedirs(out, exist_ok=True)
print(f"[pinterest] 关键词: {keyword} | 数量: {count} | 保存目录: {out}")
# 跨运行已采集 URL:重复搜索同一关键词时跳过旧图、往下拉续采
known = _load_collected_urls(out)
if known:
print(f"[pinterest] 该关键词已采集过 {len(known)} 个 URL,将跳过旧图往下拉续采新图")
imgs_url = asyncio.run(scrape(keyword, count, headless, proxy, cdp_url, login_wait,
known_urls=known))
if not imgs_url:
print(f"[pinterest] 未收集到新图片(可能未登录、搜索无结果或该关键词已无新图): {keyword}")
return []
asyncio.run(download_all(imgs_url, out, proxy))
# 合并本次新采集 URL 到持久化集合,供下次增量续采
known |= imgs_url
_save_collected_urls(out, known)
files = [str(p) for p in sorted(Path(out).iterdir()) if p.is_file()]
print(f"[pinterest] 完成,本次新增 {len(imgs_url)} 张图片(累计已采集 {len(known)} 个 URL: {keyword}")
return files