闲鱼自动收货Python源码解析:从接口模拟到工程化部署
2026/9/20 22:18:03 网站建设 项目流程

简介:这份源码面向闲鱼/咸鱼卖家及PHP开发者,实现自动收货功能:通过生成运费保价页面,买家确认开通并支付后,系统自动触发发货与收货流程,免去手动确认步骤,适合二手交易频繁、追求效率的个人卖家或小型团队使用。压缩包共129个文件,约1.18MB,以73个PHP文件为核心,配套CSS样式、JavaScript交互脚本、Markdown说明文档、JSON配置、图片素材以及license、gitignore等工程文件,结构完整。系统基于PHP 7.4运行,无需数据库,后台可自定义价格、规则与条件,部署门槛较低。目前已有4134人学习浏览。解压后按安装说明配置域名及后台路径即可使用,默认后台账号密码已注明,可作为电商自动化交易场景的快速落地方案,也适合学习PHP后台开发与订单流程设计的参考案例。

1. 咸鱼自动收货源码.zip:下载后先别急着运行

在搜索框里输入“咸鱼自动收货源码.zip”,能翻到大量打包好的Python脚本,标题一个比一个夸张,有的写“全自动稳定版”,有的写“防封号”。但把zip包下载下来,真正能直接跑起来的并不多。我见过太多人卡在同一个地方:解压后装满依赖,却因为cookie格式不对、接口路径过期,脚本一分钟内就报错退出。要想让自动收货脚本真正工作,你得先理解闲鱼订单的生命周期:买家拍下、卖家发货、等待确认、自动确认、订单完成。所谓自动收货,就是在这个周期里替用户找到那个“可确认收货”的时间点,然后自动调用确认接口。这个动作可以用接口模拟实现,也可以用UI模拟实现,但工程化质量和风控策略决定脚本能活多久。这里会按“接口模拟 + Python源码 + zip工程化”的路线,把每一步拆开讲,适合有Python基础、想自己动手改造源码的开发者。

2. 自动收货的两条实现路径:接口模拟与UI自动化

“自动收货”听起来是个小功能,但落地方式直接决定脚本能跑多久。你在搜索时看到的自动收货源码zip包,绝大多数走的是HTTP接口模拟,少数走UI自动化。两条路各有什么代价,需要先讲清楚。

2.1 为什么接口模拟是源码包的主流方案

接口模拟的基本思路是:用抓包工具截获闲鱼App或Web端的订单请求,找到“确认收货”对应的API,然后用Python的requests库带着同样的cookie和token去重放。这样做的优势是速度极快,一次确认只发一个HTTP请求,毫秒级返回,而且不依赖屏幕分辨率和App界面。批量处理订单时,接口模拟可以写一个for循环连续执行,UI自动化则每一步都要等界面渲染。

但接口模拟有个绕不过去的门槛:闲鱼的接口带有签名参数,很多请求体里的字段是二进制或加密过的。纯requests脚本没法在本地重新生成签名,所以源码通常依赖“长稳cookie + token”来通过鉴权,而token过期后必须手动更新。这也是那类源码包维护成本最高的地方。抓包时用Charles或Fiddler都可以,手机上配置好Charles代理后,手动操作一次下单和确认收货,把所有请求记录下来,重点看请求URL和请求头。一般来说,订单列表和确认操作各对应一个接口,把这两个接口的路径和参数摘出来,源码就完成一大半了。

2.2 UI自动化的适用场景与边界

UI自动化的思路是用pyautogui或uiautomator2模拟点击、滑动。脚本启动后打开闲鱼App,进入订单列表,按坐标或图像模板找到“确认收货”按钮,点击后再截图校验。下面是一个用pyautogui定位按钮的最小示例:

import pyautogui button = pyautogui.locateOnScreen("confirm_button.png", confidence=0.8) if button: pyautogui.click(pyautogui.center(button)) else: print("confirm button not found")

这段代码做的事情是,在屏幕中查找名为confirm_button.png的模板图,找到后计算中心点并点击。confidence=0.8表示允许20%的匹配误差,值越低越容易误匹配。这种方法在Android模拟器或真机上可行,但缺点是UI一改版,模板图就失效,而且屏幕分辨率或DPI变化也会影响匹配结果。弹窗、来电、通知栏下拉都会让脚本点错位置,所以UI自动化更适合固定环境、单账号、低频率的验证场景。

2.3 技术选型对比:从稳定性和维护成本两个维度看

下面这个表我整理了两种方案的核心差异,用来帮你判断把手上的自动收货源码zip包解压后,看到的文件到底属于哪一类。

维度接口模拟UI自动化
执行速度毫秒级请求秒级,依赖界面切换
稳定性受接口变动影响受App版本和屏幕影响
签名处理需要抓包获取token不需要
运行环境纯命令行,可挂服务器需要Android设备或模拟器
批量处理循环调用,容易扩展操作慢,容易误触
风控难度依赖cookie质量和频率依赖操作节奏

如果你解压后看到的是auto_confirm.pyrequirements.txt,大概率是接口模拟;如果里面还有.png图片和.yaml坐标配置,那多半是UI自动化。后面的章节我以接口模拟为主线展开,因为这是能支撑无人值守、批量运行的首选方案。但无论哪种方案,订单状态的判断逻辑是共通的,这一点在下一章详细讲。

3. 用Python写自动收货核心逻辑:从订单查询到确认

这一章直接进入Python源码的实现。我会按“登录态初始化 -> 订单列表查询 -> 到期时间判断 -> 确认接口调用 -> 定时轮询”的顺序,把每个函数拆开讲。代码中的接口路径和字段名是示例,你需要用自己抓包拿到的真实值替换。

3.1 登录态初始化:cookie和token缺一不可

自动收货脚本本质上是一个有状态的HTTP客户端,状态就是登录态。闲鱼接口鉴权通常依赖两个值:cookie和token。cookie里包含账号身份,token用于防止CSRF。源码里我习惯先定义一个AutoConfirm类,构造函数接收这两个值,并统一设置到requests.Session中。

import requests class AutoConfirm: def __init__(self, cookie: str, token: str): self.session = requests.Session() self.session.headers.update({ "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X)", "Cookie": cookie, "x-csrf-token": token, "Content-Type": "application/json", }) self.processed = set()

这段代码最容易被忽略的是User-Agent。你抓包时用的是什么设备和环境,就必须在脚本里保持一致的User-Agent,否则后端可能因为设备指纹不一致拒绝请求。cookie携带登录凭证,有有效期,失效后接口会返回401,需要重新抓包。x-csrf-token是请求头里的防跨站标记,很多新抓包的人只复制cookie而忘记token,导致请求返回“无权限”。

3.2 订单列表查询与可确认时间判断

拿到登录态之后,脚本进入轮询流程。第一步是拉取“待确认收货”状态的订单。这里必须使用抓包时看到的真实接口路径,常见的形式是/order/list带分页参数。下面这段代码用params携带过滤条件:

def fetch_wait_confirm_orders(self, page: int = 1, page_size: int = 20) -> list: params = { "page": page, "size": page_size, "status": "WAIT_CONFIRM", "tab": "sell", } resp = self.session.get( "https://api.example.com/order/list", params=params, timeout=10, ) data = resp.json() if data.get("success") is not True: raise RuntimeError(f"list order failed: {data.get('error')}") return data["data"]["items"]

代码里的status参数表示只返回待确认的订单,tab=sell表示卖家视角。不同版本的源码对状态字段的命名不一样,有的叫orderStatus,有的叫statusValue,你需要先打印返回的JSON,确认你的字段名是什么。timeout=10表示超过10秒没有响应就报错,避免轮询时卡死。

拿到订单后,还需要判断可确认时间。闲鱼在交易流程中有一个“自动确认收货倒计时”,发货后一段时间才允许确认。这个时间点通常由服务端下发,字段名可能是confirmTimecanConfirmTime。我的判断逻辑如下:

import time def is_confirmable(self, order: dict) -> bool: confirm_time = order.get("confirm_time") if not confirm_time: return False return int(confirm_time) <= int(time.time() * 1000)

这里有一个单位问题:Python的time.time()返回的是秒,而服务端返回的时间戳通常是毫秒,所以必须乘以1000再比较。如果漏了这一步,所有订单都会被判断为未到时间,脚本看起来正常运行但什么都不做。我见过不少源码包就是在这个换算上写错,用户还以为是接口变了。

3.3 确认收货接口调用与幂等处理

确认接口是整个脚本的终点。它的调用参数一般只需订单ID,但为了应对轮询中重复处理同一个订单,我建议在内存里维护一个已处理订单的集合。下面这段代码展示了基础实现:

def confirm_order(self, order_id: str) -> bool: if order_id in self.processed: return True payload = {"orderId": order_id, "confirmSource": "auto"} resp = self.session.post( "https://api.example.com/order/confirm", json=payload, timeout=10, ) data = resp.json() if data.get("success") is True: self.processed.add(order_id) return True print(f"confirm failed: {order_id}, {data.get('error')}") return False

self.processed集合的作用是防止同一个订单在一轮轮询中被重复提交。确认成功后,订单ID被加入集合,后续轮询直接跳过。confirmSource是可选字段,具体参数名以抓包为准,不要照抄。如果确认接口返回success=false,需要打印完整返回信息,方便定位是token过期还是订单状态变化。

需要注意的是,self.processed是内存集合,脚本重启后会清空。为了在重启后还能继续跳过已确认订单,可以把确认成功的订单ID追加写入本地文件,启动时加载。这个文件在工程化章节会详细说明。

3.4 定时轮询的调度参数

核心函数完成后,需要一个循环把整个流程串起来。最小实现是while Truetime.sleep,但要把异常捕获放在循环内部,否则一次网络抖动就会让整个脚本退出。

import time def run_loop(self, interval_seconds: int = 60): while True: try: orders = self.fetch_wait_confirm_orders() for order in orders: if self.is_confirmable(order): self.confirm_order(order["order_id"]) except Exception as e: print(f"loop error: {e}") time.sleep(interval_seconds)

循环里每一步都有失败可能:拉单失败、确认失败、JSON解析失败。把异常捕获在这一层,可以保证脚本不会因为单个错误退出。interval_seconds决定了轮询频率,我用下面这个表给出不同场景的参数建议。

场景interval_seconds随机延迟范围
测试环境100~5秒
个人少量订单600~20秒
批量多订单3000~60秒

测试环境可以短一些,方便快速看到效果;真实运行建议至少300秒,并引入随机延迟。随机延迟是在sleep前加上random.randint(0, max_delay),避免固定间隔被风控识别为机器行为。

4. 把自动收货脚本打包成zip源码工程

当你的自动收货脚本写完并跑通后,下一步通常是整理成zip压缩包分享给别人,或者自己归档到Git仓库。这一章讲源码工程怎么组织、依赖怎么声明、配置怎么脱敏,以及从zip包运行时的常见坑。

4.1 源码工程的目录结构与功能划分

一个可以发出去的源码zip包,至少要让人一眼知道入口在哪。我见过太多自动收货源码是把所有代码堆在一个main.py里,运行前要手动改代码里的cookie,别人拿到后很难维护。下面是我常用的目录结构:

xianyu_auto_confirm/ ├── main.py # 入口:加载配置并启动轮询 ├── auto_confirm.py # 自动收货核心逻辑类 ├── config.example.yaml # 配置模板,不含真实密钥 ├── config.yaml # 本地配置,被gitignore忽略 ├── requirements.txt # 依赖清单 ├── logs/ # 运行日志和已处理订单记录 └── README.md # 使用说明和风险提示

main.py负责加载YAML配置并启动AutoConfirmauto_confirm.py只关心业务逻辑,配置和代码分离,多人协作时能减少改代码的低级错误。这里我把config.yamlconfig.example.yaml分开,前者的职责是让使用者拷贝模板后填入自己的cookie,后者作为提交到git或打进zip包的默认文件,防止密钥泄露。

main.py的内容通常只有十几行:

from auto_confirm import AutoConfirm import yaml def main(): with open("config.yaml", "r", encoding="utf-8") as f: cfg = yaml.safe_load(f) acct = cfg["account"] runner = AutoConfirm(cookie=acct["cookie"], token=acct["token"]) runner.run_loop(interval_seconds=cfg["schedule"]["interval_seconds"]) if __name__ == "__main__": main()

这段代码把读取配置和启动循环分开,main函数只做装配,不包含业务逻辑。cfg["account"]cfg["schedule"]对应YAML中的两段结构,如果配置里缺少字段,会抛KeyError,所以跑之前先检查YAML格式是否正确。

4.2 requirements.txt与依赖管理

自动收货源码最小依赖是requests和PyYAML,requirements.txt如下:

requests>=2.28.0 PyYAML>=6.0

依赖声明里指定最低版本,是为了避免低版本缺特性。安装时直接执行pip install -r requirements.txt。如果源码里用了from __future__ import annotations这类语法,Python版本最好在3.9以上。解压zip包后如果运行时报ModuleNotFoundError,几乎都是没有安装依赖或安装到了错误的Python环境。这时候先用pip list确认包是否存在,再检查当前pythonpip是否指向同一个解释器。

4.3 配置文件与敏感信息脱敏

cookie和token属于敏感信息,直接写死在源码里是最大的安全隐患。我把cookie和token放到YAML配置文件中,并把示例配置留空,方便使用者复制。config.example.yaml的内容如下:

account: cookie: "" token: "" schedule: interval_seconds: 300 enable_random_delay: true random_delay_max: 60

cookietoken留空,enable_random_delay控制是否启用随机延迟,random_delay_max是延迟上限。读取时用yaml.safe_load即可,不要用yaml.load,后者可能执行任意代码,有安全风险。打包zip时不要包含真实配置,建议在README里写明“复制config.example.yaml并改名config.yaml”。

4.4 从zip包运行时的常见坑

自动收货源码zip包下载后,解压、安装依赖、改配置,这三步看似简单,但每一步都有常见坑。我在下表里整理了error现象和解决方案。

error现象可能原因处理方式
ModuleNotFoundError依赖未安装或Python环境不对执行pip install -r requirements.txt
invalid zip archive压缩包下载不完整重新下载并检查文件大小
yaml.YAMLLoadWarningPyYAML版本过低升级到6.0
运行后无任何请求记录cookie过期或格式不对重新抓包并填入完整cookie
HTTP 401token或cookie失效重新获取token
FileNotFoundError未创建config.yaml复制示例配置并改名

这里特别说一下invalid zip archive,很多人在下载github上的zip项目时遇到过这个错误,通常是下载过程中断导致文件损坏。判断方法是看压缩包大小是否与页面标注一致,恢复下载后重试。另一个容易混淆的问题是“网页上能登录但脚本返回401”,这不是接口路径错了,而是token过期,需要回到抓包工具重新复制最新的token。

5. 自动收货脚本上线前要做的验证与防封

脚本写好后直接跑并不是最佳姿势。我建议先做一轮“单订单验证”,再逐步提高执行频率。这一节我会给一个日志验证方案和几个防封参数,顺便把合规边界说清楚。

5.1 用日志和已处理记录验证触发条件

确认收货的触发条件有两层:订单状态可确认、当前时间到达或超过可确认时间。为了验证条件是否生效,我在确认接口前后分别打日志。下面这段代码用标准库logging实现:

import logging logging.basicConfig( filename="logs/confirm.log", level=logging.INFO, format="%(asctime)s %(message)s", ) # 在confirm_order成功分支 def confirm_order(self, order_id: str) -> bool: if order_id in self.processed: return True ... if data.get("success") is True: self.processed.add(order_id) logging.info(f"CONFIRM_OK {order_id}") return True logging.warning(f"CONFIRM_FAIL {order_id} {data.get('error')}") return False

日志输出的时间戳可以用来核对脚本是否按预期周期运行。如果CONFIRM_OK出现在订单可确认时间之前,说明时间判断写错了;如果一次都没有,说明订单状态过滤条件有问题。单独看日志可能看不出所以然,建议把confirm_time也打出来,和当前时间对比确认单位是毫秒还是秒。

5.2 风控维度的参数调优

防封的关键是让请求节奏接近真人操作。除了间隔时间,我还会加一个运行时段配置,比如每天只运行8小时,其他时间自动暂停。在run_loop里可以这样处理:

import datetime def should_run_now(self) -> bool: hour = datetime.datetime.now().hour return 9 <= hour <= 23

should_run_now会在整点范围内返回布尔值,循环里配合一个sleep实现暂停,避免深夜频繁请求。这个控制虽然粗糙,但对账号友好度提升明显。

5.3 合规提醒

自动收货脚本只应该用在自己拥有完全控制权的账号上,并且要对可能违反平台用户协议的行为有预期。如果脚本被用于批量操作他人账号,可能涉及账号安全、隐私保护等问题。我的建议是:这类源码zip包适合在学习HTTP自动化和工程化时参考,不要直接投入生产环境,也不要传播衍生版本。

最后,记得给确认接口加一个文件锁。具体来说,在confirm_order第一次执行前用fcntl.flock锁住日志文件,确认完成后再释放,这样即使你后续接入了多线程或定时任务,也不会出现同一个订单被重复提交的情况。这个小技巧比任何限流都更能保护你的订单数据。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询