replenish_accounts.py 5.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. # -*- coding: utf-8 -*-
  2. # Author : Charley
  3. # Python : 3.12.10
  4. # Date : 2026/09/09
  5. """账号池一键补号脚本(经接码平台自动注册 = 登录即注册)。
  6. 用法:
  7. python spiders/replenish_accounts.py # 默认单次最多补 5 个(分天补,降连坐)
  8. python spiders/replenish_accounts.py --batch 3 # 本次最多补 3 个
  9. python spiders/replenish_accounts.py --target 20 --batch 20 # 补满 20(⚠️ 一次爆量连坐风险高)
  10. python spiders/replenish_accounts.py --loop # 常驻定时模式:每 2h 巡检补一次(供 start_all 长跑)
  11. 补货前会先释放 dead 号占用的专属 IP(不复活、仅回收 IP),故 dead 掉号后 healthy 能自动被新号补回。
  12. 风控提醒:得卡强风控,短时间同机批量注册新号是最典型连坐信号。默认单次限 5 个、每号错峰
  13. 30~90s,建议分几天补满 POOL_TARGET_SIZE(20),让号陆续自然增长,别一次爆量。
  14. """
  15. # ---------- bootstrap:定位新根 + 挂 common 到 sys.path + chdir 新根(共用根 application.yml/logs)----------
  16. import os
  17. import sys
  18. _ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
  19. sys.path.insert(0, os.path.join(_ROOT, "common"))
  20. os.chdir(_ROOT)
  21. import argparse
  22. import time
  23. import schedule
  24. from loguru import logger
  25. from mysql_pool import MySQLConnectionPool
  26. from account_pool import AccountPool, POOL_TARGET_SIZE
  27. # 定时模式默认巡检间隔(小时):常驻跑时每隔 N 小时补一次;只在 healthy 不足时才真买号,够用即空跑
  28. REPLENISH_EVERY_HOURS = 2
  29. # 日志:按天切分,保留 7 天
  30. logger.remove()
  31. logger.add(sys.stderr, format="[{time:HH:mm:ss}] {level} {message}", level="INFO")
  32. logger.add("./logs/replenish_{time:YYYYMMDD}.log", encoding="utf-8", rotation="00:00",
  33. format="[{time:YYYY-MM-DD HH:mm:ss}] {level} {message}", level="INFO", retention="7 day")
  34. def main(target: int, batch: int) -> None:
  35. """补号主流程:把账号池 healthy 数补到 target,单次最多补 batch 个。
  36. Args:
  37. target (int): 账号池目标 healthy 数(补到此值为止)。
  38. batch (int): 本次运行最多新增几个号(分批/分天控节奏、降连坐)。
  39. """
  40. pool = MySQLConnectionPool(log=logger)
  41. if not pool.check_pool_health():
  42. logger.error("数据库连接池异常,退出")
  43. return
  44. ap = AccountPool(pool, log=logger, task_tag="replenish")
  45. ap.revive_cooling() # 先把冷却(cooling)到期的号恢复 healthy,再统计是否需补(避免多注册)
  46. cur = ap.count_healthy()
  47. # 单次限量:本次目标 = min(总目标, 当前 + batch),避免一次爆量
  48. run_target = min(target, cur + batch)
  49. logger.info(f"补号开始:当前 healthy={cur},总目标={target},本次补到={run_target}(单次限 {batch} 个)")
  50. if cur >= run_target:
  51. logger.info("已达标,无需补货")
  52. return
  53. added = ap.auto_replenish(target_min=run_target, target_max=run_target)
  54. logger.info(f"补号结束:本次新增 {added} 个,当前 healthy={ap.count_healthy()}(总目标 {target})")
  55. def schedule_loop(target: int, batch: int, hours: int) -> None:
  56. """常驻定时补号:先立即补一次,之后每 hours 小时巡检补一次(供 start_all 拉起长跑)。
  57. 每轮内部会先释放 dead 号占用的专属 IP 再补(见 AccountPool.auto_replenish),故 dead 号
  58. 掉了也能被新号顶替、healthy 自动回到 target;只在 healthy < 目标时才真向接码平台买号。
  59. Args:
  60. target (int): 账号池目标 healthy 数。
  61. batch (int): 单轮最多新增几个号(分批错峰、降连坐)。
  62. hours (int): 巡检间隔小时数。
  63. """
  64. logger.info(f"账号池自动补货常驻启动:每 {hours} 小时巡检一次,目标 {target},单轮限 {batch} 个")
  65. main(target=target, batch=batch) # 启动即补一次,先把当前缺口补上
  66. schedule.every(hours).hours.do(main, target=target, batch=batch)
  67. while True:
  68. schedule.run_pending()
  69. time.sleep(1)
  70. if __name__ == "__main__":
  71. parser = argparse.ArgumentParser(description="账号池一键补号(接码平台自动注册)")
  72. parser.add_argument("--target", type=int, default=POOL_TARGET_SIZE, help=f"池子总目标数,默认 {POOL_TARGET_SIZE}")
  73. parser.add_argument("--batch", type=int, default=5, help="单次/单轮最多补几个(分批降连坐),默认 5")
  74. parser.add_argument("--loop", action="store_true", help="常驻定时模式:每 --hours 小时巡检补一次(供 start_all 长跑)")
  75. parser.add_argument("--hours", type=int, default=REPLENISH_EVERY_HOURS, help=f"定时模式巡检间隔小时,默认 {REPLENISH_EVERY_HOURS}")
  76. args = parser.parse_args()
  77. if args.loop:
  78. schedule_loop(target=args.target, batch=args.batch, hours=args.hours) # 常驻定时
  79. else:
  80. main(target=args.target, batch=args.batch) # 一次性补