rea_history.py 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. # -*- coding: utf-8 -*-
  2. # Author : Charley
  3. # Python : 3.12.10
  4. # Date : 2026/07/10
  5. """
  6. REA (collectrea.com) 全量历史爬虫(一次性脚本)
  7. 逻辑(两阶段,与 wheatland 一致):
  8. 阶段一 列表:GET /search 解析「全部」场次(RECENT + AUCTION ARCHIVE 两个 tab,去重 84 场)
  9. → 逐场次翻页抓 lot 列表入库(state 默认 0)
  10. 阶段二 详情:扫库 state != 1 的记录 → 逐条进详情页抓「标题 + 5 字段 + 多图」写回
  11. 适用场景:初始化数据库时跑一次。后续日常增量由 rea_spider.py 负责。
  12. """
  13. import sys
  14. import random
  15. from curl_cffi import requests
  16. from loguru import logger
  17. from mysql_pool import MySQLConnectionPool
  18. from rea_core import (
  19. client_identifier_list,
  20. crawl_one_auction,
  21. get_auction_list,
  22. update_details_for_pending,
  23. )
  24. logger.remove()
  25. logger.add("./logs/his_{time:YYYYMMDD}.log", encoding="utf-8", rotation="00:00",
  26. format="[{time:YYYY-MM-DD HH:mm:ss.SSS}] {level} {message}",
  27. level="DEBUG", retention="7 day")
  28. # —— 调试开关 ——
  29. # 只抓前 N 个场次,None 表示全抓(生产);测试时设小一点,比如 1
  30. DEBUG_AUCTION_LIMIT = None
  31. def run_history(log, sql_pool):
  32. """全量抓取所有场次(RECENT + AUCTION ARCHIVE)。
  33. Args:
  34. log: logger 对象。
  35. sql_pool: MySQL 连接池;传 None 时不入库,仅翻页抓取并 print 样本。
  36. """
  37. impersonate = random.choice(client_identifier_list)
  38. with requests.Session() as session:
  39. try:
  40. auctions = get_auction_list(log, session, impersonate, only_recent=False)
  41. # print(auctions)
  42. except Exception as e:
  43. log.error(f"获取场次列表失败: {e}")
  44. return
  45. # 调试模式裁剪场次数量
  46. if DEBUG_AUCTION_LIMIT is not None:
  47. auctions = auctions[:DEBUG_AUCTION_LIMIT]
  48. log.warning(f"[DEBUG] 调试模式,仅抓前 {len(auctions)} 个场次")
  49. for idx, auc in enumerate(auctions, 1):
  50. log.info(f"========== [{idx}/{len(auctions)}] 开始抓场次 {auc['auction_key']} ({auc['auction_name']}) ==========")
  51. try:
  52. lots = crawl_one_auction(log, sql_pool, session, impersonate, auc)
  53. if sql_pool is None:
  54. for row in lots[:2]:
  55. print(row)
  56. except Exception as e:
  57. log.error(f"场次 {auc['auction_key']} 抓取异常: {e}")
  58. continue
  59. def rea_history_main(log):
  60. """全量历史抓取入口。
  61. Args:
  62. log: logger 对象。
  63. """
  64. log.info(f"开始运行 {sys._getframe().f_code.co_name} 全量爬虫任务 ...")
  65. sql_pool = MySQLConnectionPool(log=log)
  66. if not sql_pool:
  67. log.error("MySQL数据库连接失败")
  68. raise Exception("MySQL数据库连接失败")
  69. try:
  70. # 阶段一:抓列表入库
  71. # run_history(log, sql_pool)
  72. # 阶段二:扫库 state != 1 的记录补抓详情
  73. if sql_pool is not None:
  74. update_details_for_pending(log, sql_pool)
  75. except Exception as e:
  76. log.error(f"{sys._getframe().f_code.co_name} error: {e}")
  77. finally:
  78. log.info(f"爬虫程序 {sys._getframe().f_code.co_name} 运行结束")
  79. if __name__ == "__main__":
  80. rea_history_main(log=logger)