Files

7.9 KiB
Raw Permalink Blame History

name, description
name description
atomk-bulk-claim Automatically log into AtomK, claim products from Product Pool, generate Temu/AliExpress data, and download CSV with 800x800 images using Node.js Playwright.

AtomK Product Claim & Temu Data Generation

Automates logging into the AtomK system (atomlisting.com), claiming products from the Product Pool (产品池), generating Temu listing data via AI, and exporting CSV with 800x800 images.

Critical Environment Facts

  • DrissionPage is NOT installed — do NOT use it
  • Use Node.js Playwright at /home/ubuntu/.hermes/hermes-agent/node_modules/playwright
  • Use atomlisting.com domainbt109atomk.sh3.ikuai7.com login silently fails
  • Login credentials: admincao / Tt123456!
  • sharp npm package required for image resizing (npm install sharp)
  • Set NODE_PATH=/home/ubuntu/.hermes/hermes-agent/node_modules when running scripts
  • Use ignoreHTTPSErrors: true for atomlisting.com

Execution Steps

1. Setup

killall -9 chrome chromium chrome-headless-shell 2>/dev/null
cd /home/ubuntu/.hermes/hermes-agent && NODE_PATH=/home/ubuntu/.hermes/hermes-agent/node_modules node script.js

2. Login

Navigate to https://atomlisting.com/login (NO www, HTTPS only). Fill inputs[0] with username, inputs[1] with password, then await inputs[1].press('Enter') — do NOT click the login button. The form has method="get" and clicking the button triggers a GET redirect to login? instead of the JavaScript-powered POST /api/v1/auth/login. Pressing Enter on the password field triggers the correct JS handler.

3. Claim Products

  1. Navigate to https://atomlisting.com/products (use waitUntil: 'domcontentloaded')
  2. Select category: await page.selectOption('select', { label: '家居百货' })
  3. Click refresh button: text=刷新
  4. Find claim buttons: page.$$('text=认领并编辑')
  5. For each button:
    • Extract product ID using regex /^[A-Z0-9]{6,8}$/ from card text
    • Click button, wait for URL to contain /editor/
    • Extract editor ID from URL
    • Navigate back to products, re-select category

2a. Searching for Existing Products (Product Lookup)

AtomK has two separate product views:

Page URL Contains
Product Pool (产品池) https://atomlisting.com/products Unclaimed products available for claiming
My Products (我的产品) https://atomlisting.com/my-products Products already claimed by current account

Search strategy:

  • Use product name prefix (e.g. 88NeoHab, 11Chughalf) rather than the full SKU (88NeoHab-PO-211-16060374487670113). The full SKU often returns no results because AtomK indexes by product code, not the full platform SKU.
  • If a product is not found in My Products, check the Product Pool — it may not have been claimed yet.
  • The search input may not be visible immediately on page load; wait for the SPA to render.
// Search in Product Pool
await page.goto('https://atomlisting.com/products');
await page.waitForTimeout(3000);
const searchInput = page.locator('input[placeholder*="搜索"]').first();
await searchInput.fill('88NeoHab');  // prefix, not full SKU
await searchInput.press('Enter');
await page.waitForTimeout(5000);

4. Generate Platform Data (Temu / AliExpress / etc.)

For each claimed product:

  1. Navigate to https://atomlisting.com/editor/{id}
  2. Click platform tab button first — available platforms: button:has-text("Temu"), button:has-text("速卖通"), button:has-text("亚马逊"), button:has-text("TikTok Shop"), button:has-text("SHEIN"), button:has-text("Ozon"), button:has-text("沃尔玛")
  3. Click button:has-text("AI 生成") — the button text becomes AI 生成 速卖通 上架信息 after platform selection
  4. Wait for generation (poll button text until no longer contains "生成中")
  5. Extract generated data:
    • Title: input[placeholder*="标题"] or input[placeholder*="产品标题"]
    • Description: textarea[placeholder*="描述"] or textarea[placeholder*="产品描述"]
    • Price: input[type="number"]
    • Tags: input[placeholder*="关键词"] or input[placeholder*="标签"]
    • Image URLs: img[src*="cos"] (both cos.ap-hongkong and cos.ap-nanjing sources, exclude logo/icon)
    • Dimensions: inputs with placeholders for 重量/长/宽/高

AliExpress CSV format (similar to Temu but different category defaults):

Product name,Category path,Price,Quantity,Product description,Package weight,Package length,Package width,Package height,Keywords,Image URLs,Product code

Use "Luggage & Bags" as category for 箱包 products.

5. Download & Resize Images

const sharp = require('sharp');
const { execSync } = require('child_process');

// Download
execSync(`curl -sL -o "${tempFile}" "${url}"`, { timeout: 30000 });

// Resize to 800x800
const resized = await sharp(tempFile)
  .resize(800, 800, { fit: 'contain', background: { r: 255, g: 255, b: 255, alpha: 1 } })
  .jpeg({ quality: 90 })
  .toBuffer();

6. Generate CSV

Temu standard format:

Product name,Category path,Price,Quantity,Product description,Package weight,Package length,Package width,Package height,Keywords,Image URLs,SKU,Product code

CSV fields must be escaped: if value contains ,, ", or \n, wrap in " and double any ".

Critical Pitfalls

  • Login form GET trap: The login form has method="get" — clicking the "登 录" button submits a GET request to login? and stays on the login page. Always press Enter on the password field to trigger the JS POST /api/v1/auth/login handler instead.
  • Available categories in Product Pool: "全部分类", "汽摩配", "玩具母婴", "箱包" (bags-luggage), "服饰配饰", "美妆个护", "服饰", "美容健康", "默认分类", "文具电子", "家居百货", "运动户外". Use page.selectOption('select', { label: '箱包' }) for bags/luggage.
  • Platform tabs in Editor: After claiming, the editor supports multiple platforms. Click the platform tab FIRST (e.g., 速卖通, Temu, 亚马逊, TikTok Shop, SHEIN, Ozon, 沃尔玛), THEN click AI generate. The AI generate button text changes to reflect the selected platform (e.g., "AI 生成 速卖通 上架信息").
  • Image sources include both regions: Generated product images may come from both cos.ap-hongkong.myqcloud.com (user uploads) AND cos.ap-nanjing.myqcloud.com (1688 source images). Filter with img[src*="cos"] instead of just hongkong.
  • Product ID parsing: Don't use line position (lines[0]). Use regex /^[A-Z0-9]{6,8}$/ to find the 6-8 char alphanumeric product code. First line can be "暂无图片" or image count.
  • Editor ID validation: Must be numeric (/^\d+$/). Some claimed products lead to non-editor pages.
  • Stale element references: After clicking a claim button, the page navigates. Re-find elements after each navigation back to products.
  • AI generation timeout: Each product takes 1-3 minutes. Use generous polling (50 iterations × 3 seconds = 150 seconds max).
  • Background processes: For 20+ products, use terminal(background=true, notify_on_complete=true) with timeout > 600s.
  • Playwright waitUntil: Use domcontentloaded not networkidle for heavy pages — faster and more reliable.
  • Suppress alerts: Use page.addInitScript(() => { window.alert = function() {}; window.confirm = function() { return true; }; }) to prevent blocking dialogs.
  • sharp module path: Must set NODE_PATH environment variable or require will fail with "Cannot find module 'sharp'".
  • HTTPS certificate errors: atomlisting.com has a cert mismatch. Set ignoreHTTPSErrors: true at BOTH chromium.launch() AND browser.newContext() levels.
  • Download blocking: Cannot use page.goto() for image URLs that trigger downloads. Use curl via execSync instead.

Archive Output

cd /tmp && tar -czf temu_batch_20.tar.gz temu_batch_listing_final.csv temu_batch_images_800x800/