--- name: miaoshou-collect-box category: cross-border-ecommerce description: Explore and interact with Miaoshou ERP's "通用采集箱" (Common Collect Box) — URLs, collection methods, import paths, and login automation. --- # 妙手ERP 通用采集箱 (Common Collect Box) ## Overview Miaoshou ERP (`erp.91miaoshou.com`) has a **Common Collect Box** (`通用采集箱`) at a fixed URL. This skill documents how to navigate to it, the collection methods available, and how to interact with the import/collection UI programmatically via DrissionPage. ## Login - URL: `https://erp.91miaoshou.com/auth/login` - Credentials: `xiaochaoren2026 / [REDACTED]` - CAPTCHA: **Base64 inline image** (`data:image/png;base64,...`) rendered in `.captcha-img` - Unlike Dianxiaomi (which uses a separate PNG endpoint), Miaoshou embeds the captcha directly. - Extract with JS: `document.querySelector('.captcha-img').src` - Decode base64, save to file, run `ddddocr.classification()` - Apply digit cleaning: `raw.translate(str.maketrans('oliOSsZz', '01105522'))` - Form selectors: - Account: `css:.account-input` - Password: `css:.password-input` - Captcha text: `css:.captcha-text` - Captcha UUID: `input[name="captchaUuid"]` (must be set/synced) - Submit: `css:.login-button` - Success redirects to: `https://erp.91miaoshou.com/welcome` - Cookie file: `~/.hermes/cookies/miaoshou_cookies.json` (autoLoginToken is critical) ## Common Collect Box URL Direct link (works after login): ``` https://erp.91miaoshou.com/common_collect_box/index ``` Title: `妙手-产品采集` ## Collection Methods Discovered The page exposes **6 collection methods** as tab-like options: | Method | Chinese Name | Notes | |--------|-------------|-------| | Link Collection | 链接采集 | Enter public product URLs (1688, Taobao, etc.). System scrapes the page. **Requires publicly accessible pages** — internal systems (like AtomK behind login) will NOT work. | | Import Collection | 导入采集 | **Bulk import via file upload** (template-based). This is the viable path for transferring data from AtomK or other internal systems. | | 1688 AI Selection | 1688Ai选品 | AI-assisted product selection from 1688 | | Inventory Collection | 货盘采集 | Collect from inventory/supplier pallets | | Keyword Collection | 关键词采集 | Search keyword-based batch collection | | Whole-Store Collection | 整店采集 | Enter a store URL to collect all products | | Plugin Collection | 插件采集 | Browser extension-based collection | | Store Cross-Collection | 店铺互采 | Cross-store collection | ## Import Collection (导入采集) — 4 Sub-Methods When you click "导入采集", the page switches to `?fetchType=importCopy` and shows **4 sub-tabs**: | Sub-Method | Chinese Name | What It Does | |-----------|-------------|-------------| | Import Link Collection | 导入链接采集 | Upload an **XLS file** with product URLs. Miaoshou scrapes each URL. | | Excel Spreadsheet Import | Excel表格导入 | Upload a pre-structured Excel with full product data (details TBD). | | Local Material Package | 本地素材包导入 | Upload a local asset package (images + data). | | Jushuitan Material Package | 聚水潭素材包导入 | Import from Jushuitan ERP format. | ### Import Link Collection Template (导入链接采集) This is the **most important** one for AtomK-style workflows. **Template file**: `导入产品链接模板.xls` (downloadable via "下载导入模板" link in the modal) **File format**: `.xls` (older Excel 97-2003, NOT xlsx) — verified April 2026. `.xlsx` triggers `解析文件数据错误`. **CRITICAL**: The template is **strictly 5 columns**. Any extra column causes failure. | Column | Field | Required | Notes | |--------|-------|----------|-------| | A | 链接地址(必填) | ✅ Yes | Product detail page URL. **Must be publicly accessible**. Login-gated pages (like AtomK behind login) will fail. | | B | 产品标题 | No | **AI titles ARE preserved** — verified. Overrides scraped 1688 title. | | C | 价格(RMB) | No | **AI prices ARE preserved** — verified. Overrides scraped 1688 price. | | D | 促销价(RMB) | No | Only used when publishing to **Lazada**. | | E | 提示:促销价仅可用于采集到Lazada | No | Literal hint text — include this column to match the official template exactly. | **Empirically verified findings (April 2026)**: - ✅ 5-column `.xls` with exact headers above → `解析成功 N/0/N` - ❌ 6+ columns (e.g., adding "产品描述") → `导入文件未识别到:【产品主编号】表头` - ❌ Adding "产品主编号" column → `解析文件数据错误` - ❌ `.xlsx` format → `解析文件数据错误` - ✅ AI title from XLS **overrides** scraped 1688 title in the final product - ✅ AI price from XLS **overrides** scraped 1688 price - ✅ Sheet name can be `Worksheet` or `Sheet1` (doesn't matter with correct 5-col headers) - ✅ Encoding can be `utf_16_le` or `utf-8` (doesn't matter with correct 5-col headers) **Important**: The error *"导入文件未识别到:【产品主编号】表头"* is a **misleading** catch-all for "your columns don't match the expected 5-column template". Do NOT add a "产品主编号" column — doing so triggers `解析文件数据错误`. Always use the exact 5-column format. The system does not actually use or store a "产品主编号" from Excel; SKU must be filled later via the edit dialog. **Critical limitation**: The "导入链接采集" method fundamentally relies on **web scraping** each product URL. If the URL requires authentication (e.g., AtomK product pages behind `atomlisting.com` login), Miaoshou cannot fetch the data. The 5-column XLS only passes the link + AI title + AI price; Miaoshou still scrapes the 1688 page for images, description, specs, etc. #### File Upload Mechanics When the import modal is open: - The upload area is a hidden `` inside a `.pro-upload` / `.jx-upload--text` container. - **Selector**: `css:input[type=file]` or `css:.jx-upload__input` - **Accepts**: `.xls,.xlsx,.csv` (but only `.xls` works reliably) - Use `file_input.input('/path/to/file.xls')` to set the file path programmatically. - After upload, the file name appears in `.jx-upload-list li`. - **The confirm button is inside the modal dialog** — search within `.jx-dialog` for buttons with text `确认`. - **After clicking confirm, the modal closes and the file appears in the "已导入的文件列表" table.** Wait ~15s for parsing, then **refresh the page** to check status. - **The page does NOT auto-update after confirm.** You must navigate back to `?fetchType=importCopy` or use `page.get()` to refresh and see the parse result. #### Complete Upload Flow (Verified April 2026) ```python # 1. Navigate to import page page.get("https://erp.91miaoshou.com/common_collect_box/index?fetchType=importCopy") time.sleep(10) # 2. Click Excel import button page.run_js(""" var all = document.querySelectorAll('span, div, button, a'); for (var i=0; i`. ```python # 1. Navigate to claimed tab page.get('https://erp.91miaoshou.com/common_collect_box/items') # ... click 已认领 tab ... # 2. Find the row by collect_box_id and click 编辑 page.run_js(""" var rows = document.querySelectorAll('.pro-virtual-table__row, .pro-virtual-scroll__row'); for (var i=0; i{description.replace(chr(10), "

")}

' editor.run_js(f""" var editor = document.querySelector('.collect-box-editor'); var iframe = editor.querySelectorAll('iframe')[0]; var doc = iframe.contentDocument || iframe.contentWindow.document; var body = doc.querySelector('body'); body.innerHTML = {json.dumps(html_content)}; body.dispatchEvent(new Event('input', {{bubbles: true}})); """) ``` ### Saving ```python page.run_js(""" var btns = document.querySelectorAll('button'); for (var i=0; i 1) result.sku = inputs[1].value; if (textareas.length > 0) result.desc = textareas[0].value; for (var i=0; i1. Import via 5-col XLS (link + AI title + AI price)
2. Claim product to target platform
3. Open collect box edit dialog
4. Auto-fill SKU, 简易描述, 详细描述 (rich text) via DrissionPage + JS
5. Save and verify
Reference script: `/home/ubuntu/miaoshou_atomk_bridge.py` | | Direct platform upload (bypass Miaoshou) | ⚠️ Partial | Generate Temu/AliExpress CSV from AtomK API → upload to platform directly. Bypasses Miaoshou entirely but loses Miaoshou's inventory/order management. | ## Page Structure Notes - Left sidebar contains: `通用功能`, `产品采集`, `公用采集箱`, `AI工作台`, `侵权检测`, `货盘中心`, etc. - Supported platforms displayed as tags: 1688, 义乌小商品城, 浙宝网, Vvic, 搜款网, 网商园, 货捕头, etc. - Bottom action bar: `采集并自动认领`, `采集并自动发布` - A modal/popup may appear on first visit with collection settings — dismiss with "我知道了". ## Browser Setup (DrissionPage) ```python from DrissionPage import ChromiumPage, ChromiumOptions co = ChromiumOptions() co.set_browser_path('/home/ubuntu/.cache/ms-playwright/chromium-1217/chrome-linux64/chrome') co.set_argument('--headless=new') co.set_argument('--no-sandbox') co.set_argument('--disable-dev-shm-usage') co.set_argument('--window-size=1440,900') co.set_user_agent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36') co.set_local_port(get_free_port()) page = ChromiumPage(addr_or_opts=co) ``` ## Pitfalls - **Cookie expiration**: The saved cookie (autoLoginToken) expires relatively quickly. Re-login with captcha is often needed. - **Base64 captcha session**: Must extract the captcha image from the **same browser session** (via JS `document.querySelector('.captcha-img').src`) — do NOT use `requests` to fetch it separately, or the captcha UUID will mismatch. - **Tab clicking**: The collection method tabs (链接采集, 导入采集, etc.) are `` elements inside radio-button groups, not standard `