# -*- coding: utf-8 -*- # Author : Charley # Python : 3.12.10 # Date : 2026/07/10 """ REA (collectrea.com) 全量历史爬虫(一次性脚本) 逻辑(两阶段,与 wheatland 一致): 阶段一 列表:GET /search 解析「全部」场次(RECENT + AUCTION ARCHIVE 两个 tab,去重 84 场) → 逐场次翻页抓 lot 列表入库(state 默认 0) 阶段二 详情:扫库 state != 1 的记录 → 逐条进详情页抓「标题 + 5 字段 + 多图」写回 适用场景:初始化数据库时跑一次。后续日常增量由 rea_spider.py 负责。 """ import sys import random from curl_cffi import requests from loguru import logger from mysql_pool import MySQLConnectionPool from rea_core import ( client_identifier_list, crawl_one_auction, get_auction_list, 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): """全量抓取所有场次(RECENT + AUCTION ARCHIVE)。 Args: log: logger 对象。 sql_pool: MySQL 连接池;传 None 时不入库,仅翻页抓取并 print 样本。 """ impersonate = random.choice(client_identifier_list) with requests.Session() as session: try: auctions = get_auction_list(log, session, impersonate, only_recent=False) # print(auctions) 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['auction_key']} ({auc['auction_name']}) ==========") try: 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['auction_key']} 抓取异常: {e}") continue def rea_history_main(log): """全量历史抓取入口。 Args: log: logger 对象。 """ 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: # 阶段一:抓列表入库 # run_history(log, sql_pool) # 阶段二:扫库 state != 1 的记录补抓详情 if sql_pool is not None: 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__": rea_history_main(log=logger)