一、1688店群的切号地狱:六个运营,天天加班到十点
阿强是我认识的一个做1688铺货的老板。
他的模式很简单:开几百个1688店铺,把源头厂家的货铺上去,赚差价和返点。
但这种模式有个致命弱点:每个店铺都需要人工维护。
上架、改价、刷新、回复询盘,最要命的是——每天都要挨个登录。

他在广州番禺租了个小办公室,招了6个运营,工资不高,但加上提成,一个月也要出去五万多块。
去年双十一前夕,他给我打了个电话:
“林哥,我真受不了了。我这边六个小姑娘,从早上九点开始切号,一个店一个店登录,清缓存、换IP、再登下一个。三百多个店铺,光切号就要耗掉她们半条命。稍微快一点,就登错店,把A店的货传到了B店,平台提示‘同设备多账号’,封了我好几个。”
拼多多店群自动化报活动上架!
“我也找人写过脚本,什么按键精灵、影刀流程都试过。小批量跑还行,一到上百个店,浏览器一多就卡死,小姑娘们又得回去手动。”
他问我能不能做一套东西,把这套流程彻底自动化,最好连打开那个切号表格的动作都省掉。

我说:“这已经不是写个脚本的活了,得从浏览器底层开始重建。”
我把这件事作为一个机会,沉下心做了自己一直想做的事—— 从纯Python底层起步,造一套店群专用的商业级自动化软件。
这就是Alien系统的由来。
二、砍掉“切号”的第一步:让每个店铺有个家
为什么切号会这么痛苦?
因为每个店铺对运营来说,都只是一行账号密码,一段代理IP,外加一个Chrome快捷方式。

代理换了,Cookie清了,窗口关了再开, 脑子里还得时刻记着“刚才操作的是哪个店”。
我做的第一个大动作,就是打造Alien的 “环境管理中心”。
这玩意不是一个密码管理器,它是给每个店铺造了一间独立的“房子”。
软件界面上,它看起来像一个分组清晰的通讯录: 左边按平台和类目分组,比如“1688-女装”、“1688-数码配件”; 右侧每行一个店铺,清清楚楚写着店铺名、ID、代理IP、地区,最后活跃时间。
运营最常用的功能有三个,全是针对切号痛点的:
批量导入模板 以前阿强建一个店铺环境,至少五分钟。 填代理、绑指纹、创快捷方式,反复核对。 
现在他把代理和店名填进一个CSV,拖进Alien,三百多个环境全自动建好。
分组合规管理 不同类目的店铺分组管理,一个组要上架还是改价,一目了然。 以前是人脑Excel来回翻,现在是打开软件就看见树状图。
TEMU店群矩阵自动化运营核价报活动
手动打开选中环境 这是阿强说最救命的功能—— 想进去某个店瞅一眼,双击对应行,弹出一个浏览器窗口, 窗口标题上强制写着“店名+ID”,字号加大加粗。 “手滑传错店?现在闭着眼都不会点错。”
三、隔离才防串号,指纹不够独立都是假隔离
界面往下走,底层才是防止关联的核心。
多数人以为换个IP就隔离了。 根本不知道浏览器指纹里藏着多少雷。 
Canvas指纹、WebGL渲染器、字体列表、屏幕色深、AudioContext, 甚至你的键盘布局,这些就算清空Cookie也变不了。
如果三百个店铺都用同一个浏览器内核的默认指纹, 风控系统跑个聚类分析,瞬间就能认出是一波操作的。
Alien的环境隔离,从设计之初就定死了一条: 每个店铺,独立的用户数据目录+独立微调指纹+独立代理出口。
我用Python写了一个 BrowserProfileFactory, 每次创建环境,根据店铺ID用UUID5生成一个独一无二的目录名, 把这个店铺所有的Cookie、缓存、存储全部锁死在这个目录里。
指纹方面,我自己维护了一个从上百台真实机器采集来的指纹模板库。 创建环境时,随机取模板,再在Canvas噪点、WebGL参数上做几个像素的随机偏移, 确保三百个店哪怕用同一套模板,拿出来也是三百个“相似但不相同”的人。
代理、时区、语言,都跟着IP的归属地自动匹配。 一个挂日本代理的店铺,时区不可能还是北京时间。
这套机制的代码我已经打磨了很多版,这是最新一版的核心:

import os
import uuid
import json
import copy
import random
from pathlib import Path
class BrowserProfileFactory:
"""
隔离环境工厂:为每个店铺生成独立的浏览器数据目录与指纹
"""
def __init__(self, base_dir: str, fingerprint_lib: dict):
self.base_dir = base_dir
self.fp_lib = fingerprint_lib # 由真实设备采集的指纹模板库
def create(self, shop_id: str, shop_name: str, proxy_info: dict, tpl_id: str):
# 根据店铺ID生成唯一且可复现的目录哈希
dir_id = uuid.uuid5(uuid.NAMESPACE_DNS, shop_id)
profile_dir = os.path.join(self.base_dir, f"env_{dir_id}")
# 取模板,深拷贝后加入随机噪声
fp = copy.deepcopy(self.fp_lib.get(tpl_id, {}))
fp["canvas_noise"] = random.randint(0, 5) # Canvas像素偏移
fp["webgl_noise"] = random.randint(0, 3) # WebGL参数微调
if "fonts" in fp:
random.shuffle(fp["fonts"]) # 字体列表乱序
# 创建目录并落地代理和指纹配置
Path(profile_dir).mkdir(parents=True, exist_ok=True)
with open(os.path.join(profile_dir, "proxy.json"), "w") as f:
json.dump(proxy_info, f, indent=2)
with open(os.path.join(profile_dir, "fp.json"), "w") as f:
json.dump(fp, f, indent=2)
return {
"shop_id": shop_id,
"shop_name": shop_name,
"profile_dir": profile_dir,
"proxy": proxy_info,
"fingerprint": fp
}
```
有了这套工厂,阿强的三百多个1688店铺,
每一个启动时都是独立的身份,平台根本连不起来。
上线到现在,他的店铺再没因为“同设备关联”被封过。
## 四、砍掉“人工盯流程”:让任务像工厂流水线一样自己转
切号问题搞定后,下一个大活是让那三百个店自己干活。
以前阿强的运营,上架商品是这么干的:
打开Excel,找到今天要上架的店铺,挨个登录,进后台,填标题、传图、定价。
一个店折腾十几分钟,一个运营一天也就能弄二十个。
Alien第二个核心模块—— **“自动化编排流”** 就是来终结这种人力消耗的。
打开编排面板,左边放着阿强经常用的一些业务流程:
“1688批量上架”、“自动刷新橱窗”、“活动报名”、“询盘自动回复”。
右边是店铺列表,可以直接按分组拽进来。
阿强要做的事简化成了三步:
1. 把“批量上架”拖到中间
2. 2. 勾选“女装组”的80个店铺
3. 3. 设置最多同时跑20个窗口,点开始
接下来他可以去喝茶,系统自己在后台排队跑。
### 并发为什么不会崩?
一般人写并发,一百个店铺直接开一百个线程。
结果就是电脑蓝屏,小姑娘尖叫。
Alien的调度器是我从无数个惨痛线上事故里磨出来的,
就八个字:**槽位控制,僵尸必杀。**
每个“任务+店铺”变成一个任务包,丢进一个异步队列。
同时只允许固定个数(比如20个)在执行,其余的排队。
一个跑完,浏览器关掉,槽位还回来,下一个补上。
如果哪个任务卡住了,超时就直接调用系统命令杀进程,绝不拖延。
> 以前有一次,我贪快,把槽位设成30。
> > 跑了不到四十分钟,内存从4G窜到16G,整台机子卡住不动。
> > 查日志发现有几个商品上架流程结束后,浏览器弹了确认框没关闭,
> > 渲染进程赖在后台,像水蛭一样吸血。
> > 我当晚给调度器加了一条**看门狗协程**,每10秒扫描一次,
> > 凡是已经跑完但进程还活着的,一律`taskkill /F /T`。
> > 再压上去,20个窗口跑一天,稳得像山。
下面是调度器里看门狗和槽位控制的代码片段:
```python
import asyncio
class StoreTaskScheduler:
"""店群任务调度器:固定槽位并发 + 超时强杀 + 看门狗清僵尸"""
def __init__(self, max_slots=20, timeout=3600):
self.slots = asyncio.Semaphore(max_slots)
self.queue = asyncio.Queue()
self.timeout = timeout
self.running = {} # uid -> task
async def put(self, task):
await self.queue.put(task)
async def _worker(self, wid):
while True:
task = await self.queue.get()
async with self.slots:
self.running[task.uid] = task
try:
await asyncio.wait_for(task.execute(), timeout=self.timeout)
except asyncio.TimeoutError:
print(f"超时强杀: {task.name}")
task.kill()
except Exception as e:
print(f"异常: {task.name} -> {e}")
task.kill()
finally:
self.running.pop(task.uid, None)
self.queue.task_done()
async def _watchdog(self, interval=10):
"""巡检:杀掉已完成但进程未死的僵尸任务"""
while True:
dead = [uid for uid, t in self.running.items() if t.finished and t.alive]
for uid in dead:
print(f"看门狗清理: {self.running[uid].name}")
self.running[uid].kill()
del self.running[uid]
await asyncio.sleep(interval)
async def start(self, workers=20):
ws = [asyncio.create_task(self._worker(i)) for i in range(workers)]
dog = asyncio.create_task(self._watchdog())
await self.queue.join()
dog.cancel()
for w in ws:
w.cancel()
```
里面每一个 `task.execute()` 都会拉起对应店铺的隔离浏览器,跑影刀封装好的流程,
跑完自动销毁,结果写到本地报告里。
阿强现在每天晚上点一下开始,第二天早上到公司,
先打开Alien看昨晚的上架报告,一片绿,偶尔几个红的点一下“重试”,就全部搞定。
以前六个运营轮班熬夜,现在就留了一个人白天处理异常,
人力成本直降八成。
## 五、从代码到软件:让老板双击exe比装微信还简单
阿里云盘有个梗:程序员觉得交付完代码就结束了,老板觉得装环境比做生意还难。
Alien从一开始就不打算让用户碰任何命令行。
我用 **PyQt6** 把所有的操作都封装进了一个极简的管理面板,
四个Tab:环境、任务、监控、设置。
所有报错都是中文白话,没有半点Traceback。
发布时,我用 **Nuitka** 把Python代码编译成C,
连同内置的便携Chromium、影刀组件,打包成一个独立的exe。
阿强当时把U盘插上,拷到桌面,双击,
系统直接启动,所有店铺环境整整齐齐在列表里。
他愣了一会儿,说:“这就行了?”
“行了。”
“不用装Python?”
“不用。”
“不用配那个什么环境变量?”
“什么环境变量,你打开就能用。”
后来他还专门让公司那个最不懂电脑的财务大姐试了试,
大姐点了几下就会建环境、跑上架,说比公司报税软件还好用。
安全这块,我给Alien加上了离线+在线混合授权,
首次激活联网绑定机器码,日常离线也能跑,
定期校验一次授权,防止被盗版到处传。
## 六、真实的降本账:三百个店,年省几十万的运营费
系统上线快半年,阿强给我回了一条消息:
“林哥,今天算了一下,从上了你那套系统,
我把运营从6个减到1个,一年省了将近四十万工资。
而且我再也没因为切错号被封过店,以前一年怎么也得赔进去几万。
现在每天早上去公司,就喝杯咖啡看看报告。
这种感觉,以前想都不敢想。”
我把这段聊天记录截屏存了下来。
不是为了炫耀,而是这让我更确信一件事——
**技术存在的意义,就是让重复的痛苦消失。**
## 七、最后说两句
Alien这套系统,没有人工智能的噱头,也没有什么“黑科技”,
它就是用最扎实的Python工程,
把环境隔离、任务调度、用户体验,一个坑一个坑填出来的。
所有功能的设计原点,都来自于阿强,来自于像他一样被切号折磨的老板们。
如果你也在做着几百个店铺,每天被人力成本压得喘不过气,
被串号、封店、脚本卡死搞得心力交瘁,
不妨来找我聊聊。
我是林焱RPA,
一个用底层代码,把繁琐切号流程彻底干掉的独立开发者。
(全文完)






