
简介这份源码面向闲鱼/咸鱼卖家及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, confidence0.8) if button: pyautogui.click(pyautogui.center(button)) else: print(confirm button not found)这段代码做的事情是在屏幕中查找名为confirm_button.png的模板图找到后计算中心点并点击。confidence0.8表示允许20%的匹配误差值越低越容易误匹配。这种方法在Android模拟器或真机上可行但缺点是UI一改版模板图就失效而且屏幕分辨率或DPI变化也会影响匹配结果。弹窗、来电、通知栏下拉都会让脚本点错位置所以UI自动化更适合固定环境、单账号、低频率的验证场景。2.3 技术选型对比从稳定性和维护成本两个维度看下面这个表我整理了两种方案的核心差异用来帮你判断把手上的自动收货源码zip包解压后看到的文件到底属于哪一类。维度接口模拟UI自动化执行速度毫秒级请求秒级依赖界面切换稳定性受接口变动影响受App版本和屏幕影响签名处理需要抓包获取token不需要运行环境纯命令行可挂服务器需要Android设备或模拟器批量处理循环调用容易扩展操作慢容易误触风控难度依赖cookie质量和频率依赖操作节奏如果你解压后看到的是auto_confirm.py加requirements.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, paramsparams, timeout10, ) data resp.json() if data.get(success) is not True: raise RuntimeError(flist order failed: {data.get(error)}) return data[data][items]代码里的status参数表示只返回待确认的订单tabsell表示卖家视角。不同版本的源码对状态字段的命名不一样有的叫orderStatus有的叫statusValue你需要先打印返回的JSON确认你的字段名是什么。timeout10表示超过10秒没有响应就报错避免轮询时卡死。拿到订单后还需要判断可确认时间。闲鱼在交易流程中有一个“自动确认收货倒计时”发货后一段时间才允许确认。这个时间点通常由服务端下发字段名可能是confirmTime或canConfirmTime。我的判断逻辑如下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, jsonpayload, timeout10, ) data resp.json() if data.get(success) is True: self.processed.add(order_id) return True print(fconfirm failed: {order_id}, {data.get(error)}) return Falseself.processed集合的作用是防止同一个订单在一轮轮询中被重复提交。确认成功后订单ID被加入集合后续轮询直接跳过。confirmSource是可选字段具体参数名以抓包为准不要照抄。如果确认接口返回successfalse需要打印完整返回信息方便定位是token过期还是订单状态变化。需要注意的是self.processed是内存集合脚本重启后会清空。为了在重启后还能继续跳过已确认订单可以把确认成功的订单ID追加写入本地文件启动时加载。这个文件在工程化章节会详细说明。3.4 定时轮询的调度参数核心函数完成后需要一个循环把整个流程串起来。最小实现是while True加time.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(floop 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.yaml和config.example.yaml分开前者的职责是让使用者拷贝模板后填入自己的cookie后者作为提交到git或打进zip包的默认文件防止密钥泄露。main.py的内容通常只有十几行from auto_confirm import AutoConfirm import yaml def main(): with open(config.yaml, r, encodingutf-8) as f: cfg yaml.safe_load(f) acct cfg[account] runner AutoConfirm(cookieacct[cookie], tokenacct[token]) runner.run_loop(interval_secondscfg[schedule][interval_seconds]) if __name__ __main__: main()这段代码把读取配置和启动循环分开main函数只做装配不包含业务逻辑。cfg[account]和cfg[schedule]对应YAML中的两段结构如果配置里缺少字段会抛KeyError所以跑之前先检查YAML格式是否正确。4.2 requirements.txt与依赖管理自动收货源码最小依赖是requests和PyYAMLrequirements.txt如下requests2.28.0 PyYAML6.0依赖声明里指定最低版本是为了避免低版本缺特性。安装时直接执行pip install -r requirements.txt。如果源码里用了from __future__ import annotations这类语法Python版本最好在3.9以上。解压zip包后如果运行时报ModuleNotFoundError几乎都是没有安装依赖或安装到了错误的Python环境。这时候先用pip list确认包是否存在再检查当前python和pip是否指向同一个解释器。4.3 配置文件与敏感信息脱敏cookie和token属于敏感信息直接写死在源码里是最大的安全隐患。我把cookie和token放到YAML配置文件中并把示例配置留空方便使用者复制。config.example.yaml的内容如下account: cookie: token: schedule: interval_seconds: 300 enable_random_delay: true random_delay_max: 60cookie和token留空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.txtinvalid zip archive压缩包下载不完整重新下载并检查文件大小yaml.YAMLLoadWarningPyYAML版本过低升级到6.0运行后无任何请求记录cookie过期或格式不对重新抓包并填入完整cookieHTTP 401token或cookie失效重新获取tokenFileNotFoundError未创建config.yaml复制示例配置并改名这里特别说一下invalid zip archive很多人在下载github上的zip项目时遇到过这个错误通常是下载过程中断导致文件损坏。判断方法是看压缩包大小是否与页面标注一致恢复下载后重试。另一个容易混淆的问题是“网页上能登录但脚本返回401”这不是接口路径错了而是token过期需要回到抓包工具重新复制最新的token。5. 自动收货脚本上线前要做的验证与防封脚本写好后直接跑并不是最佳姿势。我建议先做一轮“单订单验证”再逐步提高执行频率。这一节我会给一个日志验证方案和几个防封参数顺便把合规边界说清楚。5.1 用日志和已处理记录验证触发条件确认收货的触发条件有两层订单状态可确认、当前时间到达或超过可确认时间。为了验证条件是否生效我在确认接口前后分别打日志。下面这段代码用标准库logging实现import logging logging.basicConfig( filenamelogs/confirm.log, levellogging.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(fCONFIRM_OK {order_id}) return True logging.warning(fCONFIRM_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 23should_run_now会在整点范围内返回布尔值循环里配合一个sleep实现暂停避免深夜频繁请求。这个控制虽然粗糙但对账号友好度提升明显。5.3 合规提醒自动收货脚本只应该用在自己拥有完全控制权的账号上并且要对可能违反平台用户协议的行为有预期。如果脚本被用于批量操作他人账号可能涉及账号安全、隐私保护等问题。我的建议是这类源码zip包适合在学习HTTP自动化和工程化时参考不要直接投入生产环境也不要传播衍生版本。最后记得给确认接口加一个文件锁。具体来说在confirm_order第一次执行前用fcntl.flock锁住日志文件确认完成后再释放这样即使你后续接入了多线程或定时任务也不会出现同一个订单被重复提交的情况。这个小技巧比任何限流都更能保护你的订单数据。本文还有配套的精品资源点击获取