电商桌面自动化实战:用RPA实现抖店批量铺货

电商桌面自动化实战:用RPA实现抖店批量铺货


做电商多店铺运营的都知道,铺货是最典型的重复性劳动------筛选、编辑、定价、发布,每个商品都要走一遍相同的流程。

本文从技术角度解析如何用桌面自动化(RPA)实现抖店批量铺货,以及实际落地中遇到的几个关键问题。


一、铺货自动化的核心流程

手动铺货的完整流程:

  1. 打开抖店货源页面
  2. 按条件筛选商品(类目、价格、好评率、发货率等)
  3. 逐个点击"去铺货"
  4. 进入商品编辑页
  5. 处理主图(裁剪比例、生成视频)
  6. 计算并设置价格
  7. 填写商品信息
  8. 发布

自动化需要解决的,就是把这8个步骤全部程序化。


二、技术架构设计

2.1 整体架构

复制代码
┌─────────────────────────────────────────┐
│           用户交互层                    │
│   对话式UI(自然语言指令解析)           │
├─────────────────────────────────────────┤
│           任务调度层                    │
│   任务队列 + 排队机制 + 定时触发         │
├─────────────────────────────────────────┤
│           自动化执行层                  │
│   浏览器自动化 + 页面元素操作            │
├─────────────────────────────────────────┤
│           数据管理层                    │
│   本地SQLite + 独立浏览器配置           │
└─────────────────────────────────────────┘

核心设计要点:

  • 每个店铺独立浏览器实例,避免Cookie/Session串号
  • 任务队列机制,同一店铺的任务串行执行,避免并发冲突
  • 对话式指令解析,降低用户学习成本

2.2 独立浏览器环境

多店铺管理的核心技术难点是浏览器隔离:

python 复制代码
import os

class BrowserManager:
    """每个店铺使用独立的浏览器配置目录"""

    def __init__(self, base_data_dir: str):
        self.base_data_dir = base_data_dir

    def get_browser_profile(self, shop_id: str) -> str:
        """
        为每个店铺返回独立的浏览器配置目录
        确保Cookie、Session、缓存完全隔离
        """
        profile_dir = os.path.join(
            self.base_data_dir, 'browsers', f'shop_{shop_id}'
        )
        os.makedirs(profile_dir, exist_ok=True)
        return profile_dir

    def launch_browser(self, shop_id: str, url: str):
        """启动指定店铺的浏览器实例"""
        profile = self.get_browser_profile(shop_id)
        # 使用独立的用户数据目录启动浏览器
        browser = launch(
            headless=False,
            user_data_dir=profile,
            args=['--no-sandbox']
        )
        page = browser.new_page()
        page.goto(url)
        return browser, page

三、选品策略的实现

3.1 筛选条件数据模型

python 复制代码
from dataclasses import dataclass, field
from typing import Optional

@dataclass
class SelectionStrategy:
    """选品策略配置"""
    name: str                          # 策略名称
    category: Optional[str] = None     # 类目筛选
    price_min: float = 0               # 最低价格
    price_max: float = 9999            # 最高价格
    min_rating: float = 0.95           # 最低好评率
    min_ship_rate: float = 0.98        # 最低发货率
    max_return_rate: float = 0.05      # 最高退货率
    free_shipping: bool = True         # 是否包邮
    seven_day_return: bool = True      # 是否7天无理由
    blocked_suppliers: list = field(default_factory=list)  # 屏蔽供应商
    blocked_keywords: list = field(default_factory=list)   # 屏蔽关键词
    target_count: int = 50             # 目标铺货数量

    def should_include(self, product: dict) -> bool:
        """判断商品是否符合筛选条件"""
        # 供应商屏蔽
        if product.get('supplier') in self.blocked_suppliers:
            return False

        # 关键词屏蔽
        title = product.get('title', '')
        for kw in self.blocked_keywords:
            if kw in title:
                return False

        # 条件筛选
        if not (self.price_min <= product.get('price', 0) <= self.price_max):
            return False
        if product.get('rating', 0) < self.min_rating:
            return False
        if product.get('ship_rate', 0) < self.min_ship_rate:
            return False
        if product.get('return_rate', 1) > self.max_return_rate:
            return False

        return True

3.2 自动筛选与执行

python 复制代码
class ListingBot:
    """铺货自动化执行引擎"""

    def __init__(self, strategy: SelectionStrategy, browser_manager: BrowserManager):
        self.strategy = strategy
        self.browser_mgr = browser_manager
        self.success_count = 0
        self.fail_count = 0

    async def run(self, shop_id: str):
        """执行完整的铺货流程"""
        browser, page = self.browser_mgr.launch_browser(
            shop_id,
            'https://fxg.jinritemai.com/ffp/goods/source'
        )

        # 第一步:按策略筛选商品
        products = await self._filter_products(page)

        # 第二步:逐个执行铺货
        for product in products[:self.strategy.target_count]:
            try:
                await self._list_product(page, product)
                self.success_count += 1
            except Exception as e:
                self.fail_count += 1
                self._log(f'商品 {product["title"]} 铺货失败: {e}')

        await browser.close()

    async def _filter_products(self, page) -> list:
        """在货源页面按策略条件筛选商品"""
        products = []
        items = await page.query_selector_all('.product-item')

        for item in items:
            product_data = {
                'title': await item.inner_text('.product-title'),
                'price': float(await item.inner_text('.price')),
                'rating': float(await item.inner_text('.rating')),
                'supplier': await item.inner_text('.supplier-name'),
            }

            if self.strategy.should_include(product_data):
                products.append(product_data)

        return products

    async def _list_product(self, page, product: dict):
        """执行单个商品的铺货操作"""
        # 点击"去铺货"
        await page.click('.list-btn')
        await page.wait_for_load_state('networkidle')

        # 设置价格(加价逻辑)
        base_price = product['price']
        final_price = base_price * (1 + self.markup_rate / 100) + self.fixed_markup
        await page.fill('.price-input', str(round(final_price, 2)))

        # 处理主图
        await self._process_main_image(page)

        # 发布
        await page.click('.publish-btn')
        await page.wait_for_selector('.success-toast')

四、定价逻辑的实现

python 复制代码
class PriceCalculator:
    """定价计算器"""

    def __init__(self, markup_rate: float = 100, fixed_markup: float = 0):
        """
        markup_rate: 加价百分比(100 = 基准价的2倍)
        fixed_markup: 固定加价金额
        """
        self.markup_rate = markup_rate
        self.fixed_markup = fixed_markup

    def calculate(self, supply_price: float) -> float:
        """
        计算最终售价
        供货价50 + 加价100% + 固定加价10 = 50*2 + 10 = 110
        """
        return supply_price * (1 + self.markup_rate / 100) + self.fixed_markup

五、任务队列与调度

多店铺场景下,任务调度是关键:

python 复制代码
import asyncio
from collections import defaultdict

class TaskScheduler:
    """
    任务调度器
    同一店铺的任务串行执行,不同店铺的任务并行执行
    """

    def __init__(self):
        self.queues = defaultdict(asyncio.Queue)  # 每个店铺一个队列
        self.running = {}

    async def submit(self, shop_id: str, task):
        """提交任务到指定店铺的队列"""
        await self.queues[shop_id].put(task)

    async def run_shop(self, shop_id: str):
        """消费指定店铺的任务队列"""
        while True:
            task = await self.queues[shop_id].get()
            self.running[shop_id] = task
            try:
                await task.execute()
            finally:
                self.running.pop(shop_id, None)
                self.queues[shop_id].task_done()

    def is_shop_busy(self, shop_id: str) -> bool:
        """检查店铺是否正在执行任务"""
        return shop_id in self.running

六、落地过程中的几个问题

问题一:页面元素变化导致脚本失效

抖店的页面结构会不定期更新,选择器会失效。建议用文本匹配+属性匹配的组合定位,而不是依赖固定的CSS选择器。

问题二:操作频率过高被检测

建议每次操作之间加随机延迟(2-5秒),模拟人工操作节奏。任务之间也要有间隔。

问题三:浏览器进程泄漏

长时间运行后,浏览器进程可能没有正确关闭。建议定期检查并清理僵尸进程。

问题四:登录状态过期

Cookie和Session有有效期,需要定期检测登录状态,过期后提醒用户重新授权。


七、总结

电商铺货自动化的核心难点不是技术实现,而是稳定性和可维护性。页面结构会变、登录状态会过期、操作频率要控制------这些都是生产环境中必须处理的问题。

建议采用"对话式UI + 任务队列 + 独立浏览器"的架构,既能降低用户操作门槛,又能保证多店铺并发的稳定性。

相关推荐
甲维斯1 天前
Kimi版超级玛丽效果“惊人”,配额不足5厘米!
前端·人工智能
aosky1 天前
一台电脑配置多个 SSH Key 对应不同的 GitHub 账号
运维·ssh·github
console.log('npc')1 天前
AI前端工程与生成式UI学习路线
前端·人工智能·ui
huangdong_1 天前
淘宝商品SKU图自动分类技术深度解析:从DOM解析到智能归档
开发语言·javascript·ecmascript
阿正的梦工坊1 天前
【Rust】12-借用检查器与非词法生命周期
开发语言·后端·rust
云登指纹浏览器1 天前
WebDriver反检测技术详解:如何让自动化脚本看起来像真实浏览器
运维·自动化·跨境电商
qq_2518364571 天前
基于java Web网络订餐系统设计与实现 源码文档
java·开发语言·前端
xmtxz1 天前
计算机网络基础课程学习心得:从理论抽象到硬核实战的进阶之路
运维·学习
秋91 天前
3年经验Python后端转AI Engineer:3个月实战转型计划(2026版)
开发语言·人工智能·python
圣殿骑士-Khtangc1 天前
GPT-5.5 技术深度解析与企业级生产落地实战:从幻觉率下降到百万Token工程化
人工智能·gpt