

不用打开控制台、不用复杂调试,直接指令操控紫鸟浏览器! 全套指令开源可直接复用,轻松实现店铺启停、批量操作、自动化脚本开发,跨境店群、数据采集、RPA 自动化必备,简单高效易上手。
首先感谢罗大佬的分享紫鸟原代码
紫鸟webdriver影刀rpa指令集分享开源免费,无需打开控制台操作紫鸟浏览器就是如此简单_哔哩哔哩_bilibili
import xbot
from xbot import print, sleep
from .import package
from .package import variables as glv
import os
import platform
import shutil
import time
import traceback
import uuid
import json
from concurrent.futures import ThreadPoolExecutor
import requests
import subprocess
from DrissionPage import Chromium
from DrissionPage.common import By
import ctypes
def start_browser():
"""
启动客户端
:return:
"""
try:
client_path = glv['紫鸟路径']
socket_port = 11276
cmd = [client_path, '--run_type=web_driver', '--ipc_type=http', '--port=' + str(socket_port)]
subprocess.Popen(cmd)
time.sleep(5)
except Exception:
print('start browser process failed: ' + traceback.format_exc())
exit()
def update_core():
data = {
"action": "updateCore",
"requestId": str(uuid.uuid4()),
}
data.update(glv['紫鸟账号密码'])
while True:
result = send_http(data)
# print(result)
if result is None:
print("等待客户端启动...")
time.sleep(3)
continue
if result.get("statusCode") is None or result.get("statusCode") == -10003:
print("当前版本不支持此接口,请升级客户端")
return
elif result.get("statusCode") == 0:
return True
else:
print(f"等待更新内核: {json.dumps(result)}")
time.sleep(3)
def send_http(data):
"""
通讯方式
:param data:
:return:
"""
try:
socket_port = 11276
url = 'http://127.0.0.1:{}'.format(socket_port)
response = requests.post(url, json.dumps(data).encode('utf-8'), timeout=120)
return json.loads(response.text)
except Exception as err:
print(err)
def open_store(store_info, isWebDriverReadOnlyMode=0, isprivacy=0, isHeadless=0, cookieTypeSave=0, jsInfo=""):
request_id = str(uuid.uuid4())
data = {
"action": "startBrowser"
, "isWaitPluginUpdate": 0
, "isHeadless": isHeadless
, "requestId": request_id
, "isWebDriverReadOnlyMode": isWebDriverReadOnlyMode
, "cookieTypeLoad": 0
, "cookieTypeSave": cookieTypeSave
, "runMode": "1"
, "isLoadUserPlugin": True
, "pluginIdType": 1
, "privacyMode": isprivacy
}
data.update(glv['紫鸟账号密码'])
if store_info.isdigit():
data["browserId"] = store_info
else:
data["browserOauth"] = store_info
if len(str(jsInfo)) > 2:
data["injectJsInfo"] = json.dumps(jsInfo)
r = send_http(data)
if str(r.get("statusCode")) == "0":
return r["debuggingPort"]
elif str(r.get("statusCode")) == "-10003":
print(f"login Err {json.dumps(r, ensure_ascii=False)}")
exit()
else:
print(f"Fail {json.dumps(r, ensure_ascii=False)} ")
exit()
def close_store(browser_oauth):
request_id = str(uuid.uuid4())
data = {
"action": "stopBrowser"
, "requestId": request_id
, "duplicate": 0
, "browserOauth": browser_oauth
}
data.update(glv['gvar'])
r = send_http(data)
if str(r.get("statusCode")) == "0":
return r
elif str(r.get("statusCode")) == "-10003":
print(f"login Err {json.dumps(r, ensure_ascii=False)}")
exit()
else:
print(f"Fail {json.dumps(r, ensure_ascii=False)} ")
exit()
def get_browser_list() -> list:
request_id = str(uuid.uuid4())
data = {
"action": "getBrowserList",
"requestId": request_id
}
data.update(glv['紫鸟账号密码'])
r = send_http(data)
if str(r.get("statusCode")) == "0":
# print(r)
return r.get("browserList")
elif str(r.get("statusCode")) == "-10003":
print(f"login Err {json.dumps(r, ensure_ascii=False)}")
exit()
else:
print(f"Fail {json.dumps(r, ensure_ascii=False)} ")
exit()
def get_browser(port) -> Chromium:
browser = Chromium(port)
return browser
def open_ip_check(browser: Chromium, ip_check_url: str):
try:
tab = browser.latest_tab
tab.get(ip_check_url)
success_button = tab.ele((By.XPATH, '//button[contains(@class, "styles_btn--success")]'), timeout=60)
if success_button:
print("ip检测成功")
return True
else:
print("ip检测超时")
return False
except Exception as e:
print("ip检测异常:" + traceback.format_exc())
return False
def use_one_browser_run_task(browser):
store_id = browser.get('browserOauth')
store_name = browser.get("browserName")
print(f"=====打开店铺:{store_name}=====")
ret_json = open_store(store_id)
store_id = ret_json.get("browserOauth")
if store_id is None:
store_id = ret_json.get("browserId")
try:
browser = get_browser(ret_json.get('debuggingPort'))
if browser is None:
print(f"=====关闭店铺:{store_name}=====")
close_store(store_id)
return
ip_check_url = ret_json.get("ipDetectionPage")
if not ip_check_url:
print("ip检测页地址为空,请升级紫鸟浏览器到最新版")
print(f"=====关闭店铺:{store_name}=====")
close_store(store_id)
exit()
ip_usable = open_ip_check(browser, ip_check_url)
if ip_usable:
pass
else:
print("ip检测不通过,请检查")
except:
print("脚本运行异常:" + traceback.format_exc())
close_store(store_id)
def use_all_browser_run_task(browser_list):
# print(browser_list)
for browser in browser_list:
use_one_browser_run_task(browser)
def use_all_browser_run_task_with_thread_pool(browser_list, max_threads=1):
with ThreadPoolExecutor(max_workers=max_threads) as executor:
executor.map(use_one_browser_run_task, browser_list)
def main(args):
start_browser()
update_core()
browser_list=get_browser_list()
glv['紫鸟店铺信息列表']=browser_list


已投入生产,真实并发,70个店铺,提高了N倍的效率,原本影刀指令需要一天时间下载,并发提效就5个小时,效率提升5倍。
目前并发指令的有三个,一个是temu后台抓数,一个是店铺授权,一个是报表下载,如果有需要可以滴滴。
打开紫鸟浏览器客户端,在左侧导航栏点击【开放平台】,进入开放平台官网首页。如下图所示:

在开放平台官网首页,点击【开发者控制台】,系统将自动跳转至控制台页面(无需再次登录)。如下图所示:

进入开发者控制台首页,找到“自动化/通讯录同步”区域下的 Webdriver 设置,点击 “开启 Webdriver 状态”。

⚠️ 注意:此操作必须由 BOSS主账号 完成。如果当前账号尚未绑定紫鸟企业账号,系统会提示您进行绑定,请按照提示完成绑定后再继续。如何绑定紫鸟企业账号?请点击了解详细操作,如下图所示:

为避免影响主账号安全,建议创建一个专用于自动化的成员账号。
进入紫鸟浏览器的 企业管理 > 所有成员。
点击【添加成员】,创建一个新的成员账号(例如:自动化_Robot)。
创建成功后,在成员列表中找到该账号,点击【编辑】进入账号详情页。如下图所示:

验证新创建的成员账号(例如“自动化_Robot”)是否可以正常登录紫鸟浏览器客户端,并记录下该账号的【公司名】、【用户名】和【密码】,后续代码中将用到这些信息。
为确保自动化账号能正常获取店铺信息,请检查其权限:
进入 企业管理 > 角色管理,查看该账号所关联的角色是否拥有 “查看账号” 的权限。

完成 至此,Webdriver 权限已成功开通,专用账号也已准备就绪。
在开始操作前,请务必逐条确认以下关键信息,这能帮您避免绝大多数后续问题。
操作系统 | 支持版本 |
|---|---|
Windows | 紫鸟V5 (5.X.X.X) 或 紫鸟V6 (6.16.0.126及以上) |
macOS | 紫鸟V6 (6.15.0.44及以上) |
Linux | 紫鸟V6 (6.25.3.3及以上) |
在启动 Webdriver 进行自动化操作前,务必确保紫鸟浏览器的主进程已完全关闭,避免端口占用或冲突。
创建专用的自动化成员账号(命名示例:自动化_Robot)。
在正式使用前,验证该账号能否正常登录紫鸟浏览器客户端,确保账号基础功能可用。
问题场景:若自动化账号登录后无法获取店铺列表。
解决方案:登录企业管理后台,检查该账号的权限配置。需为其授予查看对应账号/店铺的权限(建议新建一个包含此权限的自定义角色并分配给该账号)。
考虑到启动店铺环境可能耗时较长,请将所有 HTTP 请求的超时时间统一设置为 120秒或以上,防止因等待响应超时而导致流程失败。
资源消耗:启动店铺窗口对 CPU 消耗较大。
并发建议:根据当前设备的硬件配置,合理控制并发启动的数量。建议错开各任务的启动时间,避免瞬时负载过高导致系统卡顿或崩溃。