From 8808e5b3ebec2073833b0e134a57b91d6120d03f Mon Sep 17 00:00:00 2001 From: admin9webs Date: Fri, 10 Jul 2026 16:12:08 +0800 Subject: [PATCH] Add cross-border-ecommerce/ozon-operations --- .../ozon-operations/SKILL.md | 221 ++++++++++++++++++ 1 file changed, 221 insertions(+) create mode 100644 skills/cross-border-ecommerce/ozon-operations/SKILL.md diff --git a/skills/cross-border-ecommerce/ozon-operations/SKILL.md b/skills/cross-border-ecommerce/ozon-operations/SKILL.md new file mode 100644 index 0000000..25029a8 --- /dev/null +++ b/skills/cross-border-ecommerce/ozon-operations/SKILL.md @@ -0,0 +1,221 @@ +--- +name: ozon-operations +description: "Ozon e-commerce operations: scraping product pages, seller API (import/pricing/attributes), and CDP auto-surf data collection." +version: 1.2.0 +author: Hermes Agent +license: MIT +metadata: + hermes: + tags: [ozon, e-commerce, scraping, seller-api, cdp, russia, cross-border] + related_skills: [proxy-management, camoufox-google-2fa-login, node-playwright-web-automation, cross-border-social-marketing] +--- + +# Ozon Operations + +Three workflows for working with Ozon (Russian e-commerce platform): scraping, seller API, and automated data collection. + +## Workflow Overview + +| Workflow | Purpose | Method | +|----------|---------|--------| +| **Product Page Scraping** | Extract product data from ozon.ru | CamouFox + Russia proxy + slider CAPTCHA | +| **Seller API** | Import, pricing, attributes, health analysis | REST API (v3) | +| **CDP Auto-Surf** | Continuous product data collection | CDP tunnel, random page hopping | +| **CDP Seller Login** | Automate Ozon Seller web UI via Bridge CDP | CDP Input.dispatchMouseEvent | +| **Product Health Audit** | Analyze product availability & fix issues | v3 API + availability triage | +| **Messenger Management** | Read & manage platform notifications | CDP evaluate (read-only); manual mark-read only | + +## Section 0: CDP Interaction with Ozon Seller UI + +Ozon Seller (`seller.ozon.ru`) is a React SPA that rejects standard JS `click()` and requires **CDP `Input.dispatchMouseEvent`** for button interactions. Never use `element.click()` or `dispatchEvent(new MouseEvent('click'))` — these are silently ignored by React/Vue synthetic event handlers. + +**Reliable click pattern:** +```python +# Get button position, then: +cdp('Input.dispatchMouseEvent', {'type': 'mouseMoved', 'x': x, 'y': y}) +cdp('Input.dispatchMouseEvent', {'type': 'mousePressed', 'x': x, 'y': y, 'button': 'left', 'clickCount': 1}) +time.sleep(0.15) +cdp('Input.dispatchMouseEvent', {'type': 'mouseReleased', 'x': x, 'y': y, 'button': 'left', 'clickCount': 1}) +``` + +**Also needed:** `Input.insertText` for form fields (textareas/inputs ignore `value=` assignment + event dispatch in React). + +**UI limitations:** +- Product filter tabs (错误, 待修改, etc.) cannot be activated via URL params or DOM clicks — they use internal React state +- Product detail pages don't support deep-linking (`/app/products/CODE` renders empty) +- Product list uses lazy loading — scrolling down doesn't load more; must navigate page-by-page +- "生成密钥" button opens an inline form (not a modal); the form uses permission checkboxes + text input + +**See:** `references/ozon-cdp-interaction.md` + +**Sidebar navigation URLs** and common 404 traps are documented in `references/ozon-seller-navigation.md` — use for direct CDP navigate between sections without clicking. + +## Section 1: Product Page Scraping + +Scrape Ozon.ru product pages using CamouFox anti-detection browser with Russian proxy and slider CAPTCHA auto-solve. + +**When to use:** Extracting product data (title, price, rating, images) from specific Ozon product pages. + +**Key challenges:** +- Anti-bot detection (Cloudflare, slider CAPTCHA) +- Geo-restricted content (Russia-only products) +- Dynamic pricing and availability + +**Quick start:** +```bash +# Use Russian SOCKS5 proxy with CamouFox +python3 scripts/ozon_scraper.py --proxy socks5://ru-proxy:1080 --url "https://ozon.ru/product/..." +``` + +**Pitfalls:** +- Must use Russian proxy for full product data +- Slider CAPTCHA requires CamouFox (not standard Playwright) +- Request frequency triggers rate limiting + +**See:** `references/ozon-ru-scraper.md` for full scraping guide, proxy selection, and CAPTCHA handling. + +## Section 2: Seller API + +Ozon Seller API for product import, review, pricing, categories, attributes, and product health analysis. + +**When to use:** Programmatic product management on Ozon — importing listings, updating prices, checking review status, auditing product health. + +### API Key Acquisition + +API keys for Ozon stores are stored in AtomK backend: +```python +# Login to AtomK +r = requests.post('https://atomlisting.com/api/v1/auth/login', + json={'username': 'admincao', 'password': 'Tt123456!'}, verify=False) +token = r.json()['token'] + +# Get stores with extra_data.api_key +r = requests.get('https://atomlisting.com/api/v1/stores', + headers={'Authorization': f'Bearer {token}'}, verify=False) +for store in r.json(): + extra = store.get('extra_data', {}) + # extra['api_key'] — Ozon API Key + # extra['client_id'] — Ozon Client-Id +``` + +**Pitfall:** API keys can be **deactivated** by Ozon. If the API returns `{"code":7,"message":"Api-key is deactivated"}`, you must generate a new key at `seller.ozon.ru/app/settings/api-keys` using the CDP mouse-event pattern (Section 0). + +### Product Health Audit (v3 API) + +Use `POST /v3/product/list` + `POST /v3/product/info/list` to audit all products. The critical field is **`availabilities`**, NOT `status.state`: + +```python +av = product.get("availabilities", [{}])[0] +status = av.get("availability") # "AVAILABLE", "UNAVAILABLE", "HIDDEN" +reasons = [r["human_text"]["text"] for r in av.get("reasons", [])] +``` + +**Common states:** +| State | Meaning | Typical fix | +|-------|---------|-------------| +| `AVAILABLE` | Active for sale | None | +| `HIDDEN` | "Нарушен запрет на копирование" — copy prohibition | Replace images/description with original content | +| `UNAVAILABLE` | "Неактуальный товар" — stale product | Update stock, pricing, or re-activate | +| `NO_DATA` | Empty availabilities array | May need manual review | + +**Full audit script:** See `references/ozon-product-audit.md`. + +**Key features:** +- v3/import for product creation (use `desc_cat_id` + `type_id` for categories) +- Attribute API: use `id` not `attribute_id`, dictionary attributes need `dict_id` +- Pricing: must be in CNY +- Review: check image-to-category matching + +**Quick start:** +```bash +curl -s "https://api-seller.ozon.ru/v3/product/import" \ + -H "Client-Id: $CLIENT_ID" \ + -H "Api-Key: $API_KEY" \ + -H "Content-Type: application/json" \ + -d @product_import.json +``` + +**Pitfalls:** +- Category: use `description_category_id` + `type_id`, NOT `category_id` +- Attributes: use `attribute.id`, NOT `attribute.attribute_id` +- Dictionary attributes: must include `dictionary_attribute_id` (alias `dict_id`) +- Price must be in CNY +- v3/import is the current endpoint — earlier versions are deprecated + +**See:** `references/ozon-seller-api.md` for full API reference with import, pricing, and attribute guides. + +## Section 4: Messenger & Notifications Management + +The Ozon Seller messenger (`/app/messenger?group=*`) shows system notifications, +support chats, and buyer messages. Unread counts appear on the dashboard and top nav. + +### Group Structure + +| Group | URL param | Typical content | +|-------|-----------|-----------------| +| 主要 (Main) | `?group=main` | Platform announcements, policy updates | +| 客服 (Support) | `?group=support_v2` | Automated system messages (product issues, archivals) | +| 通知 (Notifications) | `?group=system` | FBS orders, returns, quality alerts | +| 推广 (Promotions) | `?group=promotion` | Marketing tools, ad features | + +### Critical Limitations + +**No programmatic mark-read available.** The Ozon messenger React SPA: +- Has no "mark all as read" button in any group +- Ignores all JS `element.click()`, `dispatchEvent(MouseEvent)`, and CDP mouse events — clicks are consumed but read state never changes +- No discoverable REST API (all attempts return 404; uses gRPC) +- Direct CDP navigate to messenger URLs causes SPA hydration failure (shell loads but Vue doesn't bootstrap) + +**Only manual mark-read works** — user must click messages in their Desktop browser. + +### Navigation + +Access must go through the SSO flow — direct CDP navigate to messenger routes fails: +1. Navigate to `seller.ozon.ru/app/registration/signin` +2. SSO auto-login → company selection → "下一步" +3. Dashboard loads with top-nav messenger links showing unread counts +4. Click the count badge to enter messenger (triggers proper SPA routing) + +The dashboard (`#__ozon`) and messenger (`#app`) use different SPA frameworks — see `bridge-cdp-agent` skill reference `references/ozon-dual-spa-frameworks.md`. + +### Reading Content + +Message content IS accessible via CDP evaluate — the DOM shows message text in `.m9d-c2` elements. Use this to extract and summarize visible messages even though you can't mark them as read. + +```javascript +// Get visible message previews in current group +Array.from(document.querySelectorAll('.m9d-c2')).map(e => ({ + text: (e.innerText || '').substring(0, 100), + rect: e.getBoundingClientRect() +})) +``` + +### Pitfalls +- Dashboard and messenger are different SPAs — Vue instance location differs (`#__ozon.__vue__` vs `#app.__vue__`) +- Sidebar group labels are `` inside `
`, not clickable buttons +- Unread count badges are `
` — read these to track remaining unread +- The settings button at position (474, 178) opens a chat-settings panel that blocks the message list +- Page.navigate to messenger URL returns minimal shell (~58 chars); only client-side routing via Vue $router.push() works + +Auto-surf Ozon.ru via CDP tunnel — randomly hops between product pages, extracts data, saves to JSONL. Runs continuously. + +**When to use:** Continuous background collection of Ozon product data for market research, price monitoring. + +**Key patterns:** +- CDP tunnel for browser connection +- Random page navigation (surf pattern) +- Extract: SKU, price, rating, seller, stock, delivery info +- Append to JSONL file +- Graceful shutdown on interrupt + +**Quick start:** +```bash +python3 scripts/cdp_ozon_collector.py --output products.jsonl +``` + +**Pitfalls:** +- CDP connection may drop — implement reconnection +- Respect rate limits — add delays between page loads +- JSONL append mode — don't rewrite entire file each iteration + +**See:** `references/cdp-ozon-collector.md` for full collection pipeline.