| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- # -*- coding: utf-8 -*-
- # Author : Charley
- # Python : 3.12.10
- # Date : 2026/07/15
- """
- SCP Auctions (catalogs.scpauctions.com) 全量历史爬虫(一次性脚本)
- 逻辑(两阶段):
- 阶段一 列表:GET /auctions/past 翻页解析「全部」历史拍卖会 → 逐场入库 scp_auction,
- 再逐场翻页抓 lot 列表入库 scp_lot(state 默认 0)
- 阶段二 详情:扫库 scp_lot 中 state != 1 的记录 → 逐条进详情页抓
- 「标题 + 成交价 + 属性(Collection/Sport/Type/Athlete/Team) + 多图」写回
- 适用场景:初始化数据库时跑一次。后续每周增量由 scp_spider.py 负责。
- """
- import sys
- import random
- from curl_cffi import requests
- from loguru import logger
- from mysql_pool import MySQLConnectionPool
- from scp_core import (
- client_identifier_list,
- crawl_one_auction,
- get_auction_list,
- save_auction,
- update_details_for_pending,
- )
- logger.remove()
- logger.add("./logs/his_{time:YYYYMMDD}.log", encoding="utf-8", rotation="00:00",
- format="[{time:YYYY-MM-DD HH:mm:ss.SSS}] {level} {message}",
- level="DEBUG", retention="7 day")
- # —— 调试开关 ——
- # 只抓前 N 个拍卖会,None 表示全抓(生产);测试时设小一点,比如 1
- DEBUG_AUCTION_LIMIT = None
- def run_history(log, sql_pool):
- """全量抓取所有历史拍卖会及其 lot 列表(阶段一)。
- Args:
- log: logger 对象。
- sql_pool: MySQL 连接池;传 None 时不入库,仅翻页抓取并 print 样本。
- Returns:
- None: 结果直接入库,无返回值。
- """
- impersonate = random.choice(client_identifier_list)
- with requests.Session() as session:
- try:
- auctions = get_auction_list(log, session, impersonate, only_first_page=False)
- except Exception as e:
- log.error(f"获取拍卖会列表失败: {e}")
- return
- if DEBUG_AUCTION_LIMIT is not None:
- auctions = auctions[:DEBUG_AUCTION_LIMIT]
- log.warning(f"[DEBUG] 调试模式,仅抓前 {len(auctions)} 场拍卖会")
- for idx, auc in enumerate(auctions, 1):
- log.info(f"========== [{idx}/{len(auctions)}] 拍卖会 {auc['event_id']} ({auc['auction_name']}) ==========")
- try:
- save_auction(log, sql_pool, auc) # 先入库拍卖会本身
- lots = crawl_one_auction(log, sql_pool, session, impersonate, auc)
- if sql_pool is None:
- for row in lots[:2]:
- print(row)
- except Exception as e:
- log.error(f"拍卖会 {auc['event_id']} 抓取异常: {e}")
- continue
- def scp_history_main(log):
- """全量历史抓取入口。
- Args:
- log: logger 对象。
- Returns:
- None: 无返回值。
- """
- log.info(f"开始运行 {sys._getframe().f_code.co_name} 全量爬虫任务 ...")
- sql_pool = MySQLConnectionPool(log=log)
- if not sql_pool:
- log.error("MySQL数据库连接失败")
- raise Exception("MySQL数据库连接失败")
- try:
- # 阶段一:抓拍卖会 + lot 列表入库
- run_history(log, sql_pool)
- # 阶段二:扫库 state != 1 的 lot 补抓详情
- update_details_for_pending(log, sql_pool)
- except Exception as e:
- log.error(f"{sys._getframe().f_code.co_name} error: {e}")
- finally:
- log.info(f"爬虫程序 {sys._getframe().f_code.co_name} 运行结束")
- if __name__ == "__main__":
- scp_history_main(log=logger)
|