{"id":"goofish-search-list","name":"goofish-search-list","summary":"中国最大の中古品市場であるGoofish(闲鱼/xianyu、goofish.com)から中古品検索結果をスクレーピング。","body":"# Goofish (闲鱼) — Search Results List\n\n> keyword + optional filters → list of 30 second-hand item cards per page (id, title, price, image, location, want-count)\n\n## Language\n\nAll process output to user (progress updates, process notifications) follows the user's language.\n\n## Objective\n\nExtract second-hand item listing cards from Goofish keyword search results, supporting sort options, price range filters, and publish-date filters, with page-by-page pagination.\n\n## Prerequisites\n\n- Browser with an active Goofish session (logged-in account recommended for full results)\n- Target page is already open or will be opened: `https://www.goofish.com/search?q={keyword}`\n\n## Pre-execution Checks\n\n### 1. Tool Readiness\n\nIf browser-act has been confirmed available in the current session → skip this step.\n\nInvoke `browser-act` via Skill tool to load usage. If installation or configuration issues arise, follow its guidance to resolve then retry.\n\n### 2. Login Verification\n\nIf login status for Goofish has been confirmed in the current session → skip this step.\n\nOtherwise: open `https://www.goofish.com/` and observe the page:\n- User avatar or account entry exists → logged in, continue\n- Login/register prompt → not logged in; inform user that login may be required for full results; assist login if needed\n\n## Capability Components\n\n> This Skill's operational boundary = what the user can manually do in their browser. It only reads data already displayed to the user on the page. JS code is encapsulated in Python files under the `scripts/` directory, invoked via `eval \"$(python scripts/xxx.py {params})\"`. `$(...)` is bash syntax; it is recommended to use the bash tool for execution.\n\n### Network Capture: trigger search and load results\n\nSearch requests use a dynamic `sign` token computed client-side — they cannot be reconstructed directly. Navigate to the search URL to trigger the API automatically.\n\n1. `navigate https://www.goofish.com/search?q={keyword}`\n2. `wait stable`\n3. Proceed to DOM extraction below\n\nError handling: If the page shows a CAPTCHA slider (\"Please slide to verify\") instead of search results, the session has been rate-limited. Wait 5–10 minutes before retrying, or switch to a fresh browser session.\n\n### DOM: search result item cards (data extraction)\n\nAfter navigating and waiting stable, extract all 30 item cards on the current page:\n\n`eval \"$(python scripts/extract-search-items.py)\"`\n\nOutput example:\n```json\n{\n  \"items\": [\n    {\n      \"item_id\": \"1054668718340\",        // unique item ID\n      \"category_id\": \"126862528\",        // category ID\n      \"item_url\": \"https://www.goofish.com/item?id=1054668718340&categoryId=126862528\",\n      \"title\": \"美版iPhone 14 国行256G 纯原 原版原漆\",  // full title text\n      \"image_url\": \"https://img.alicdn.com/bao/uploaded/...\",  // thumbnail URL\n      \"price\": \"1810\",                   // numeric string, CNY, no ¥ sign\n      \"service_tag\": \"Apple/苹果256GB无任何维修\",  // condition/attribute tag or recency label, null if absent\n      \"price_desc\": \"2人想要\",           // want-count or price-drop info, null if absent\n      \"location\": \"广东\"                 // seller's location province/city\n    }\n  ],\n  \"count\": 30\n}\n```\n\n### DOM: apply sort and filter options (operation)\n\nApply sort order, publish-date filter, or price range before extracting. Call before running `extract-search-items.py`. After calling, `wait stable` before extracting.\n\n`eval \"$(python scripts/apply-search-filters.py --sort {sort} --publish-days {days} --price-min {min} --price-max {max})\"`\n\nParameters:\n- `--sort`: Sort option — `\"\"` default (综合), `\"reduce\"` price-drop (新降价), `\"create\"` newest (新发布), `\"price-asc\"` price low-to-high, `\"price-desc\"` price high-to-low. Default: `\"\"`\n- `--publish-days`: Filter by publish date — `\"\"` all, `\"1\"` within 1 day, `\"3\"` within 3 days, `\"7\"` within 7 days, `\"14\"` within 14 days. Default: `\"\"`\n- `--price-min`: Minimum price (CNY integer string, e.g., `\"500\"`). Requires `--price-max`. Default: `\"\"`\n- `--price-max`: Maximum price (CNY integer string, e.g., `\"3000\"`). Requires `--price-min`. Default: `\"\"`\n\nOutput example:\n```json\n{\n  \"ok\": true,\n  \"applied\": {\n    \"sort\": \"reduce:desc\",\n    \"searchFilter\": \"publishDays:7;priceRange:500,3000;\"\n  }\n}\n```\n\n### DOM: navigate to a specific page (operation)\n\n`eval \"$(python scripts/goto-page.py {page_number})\"`\n\nParameters:\n- `page_number`: Target page number (integer, 1-based)\n\nOutput example:\n```json\n{ \"ok\": true, \"clicked_page\": 2 }\n```\n\nAfter clicking, `wait stable` then re-run `extract-search-items.py` to get the new page's items.\n\n## Enum Parameters\n\n[AI] sort options: `\"\"` (综合/default), `\"reduce\"` (新降价), `\"create\"` (新发布/最新), `\"price-asc\"` (价格从低到高), `\"price-desc\"` (价格从高到低)\n\n[AI] publish-days filter: `\"\"` (all), `\"1\"`, `\"3\"`, `\"7\"`, `\"14\"`\n\n## Pagination\n\n**DOM Pagination**: Click the target page number button using `goto-page.py {page}`, then `wait stable`, then re-run `extract-search-items.py`. Page numbers appear in the pagination bar at the bottom of the search results.\n\nTermination: When `goto-page.py` returns `error: Page N not found` — no more pages available, or the target page exceeds the pagination range displayed (typically up to 25 pages / 750 items).\n\n## Success Criteria\n\n`result count >= 1` and `item_id non-null rate = 100%` and `price non-null rate >= 80%`\n\n## Known Limitations\n\n- 30 items per page (fixed by the site)\n- Maximum ~750 items accessible via pagination (25 pages × 30)\n- Seller username and user ID are not available in search cards — only seller location\n- Session rate limiting: accessing item detail pages rapidly after heavy search usage may trigger a CAPTCHA slider; mitigate by adding 1–2 second delays between page navigations\n- The `sign` token in search API requests is computed client-side; direct API replay without browser context is not supported — always trigger via page navigation\n\n## Execution Efficiency\n\n- **Batch orchestration**: Write a bash script to loop through keywords serially within a single session; do not parallelize within one browser (prone to triggering anti-scraping). Add 1–2 second delays between page navigations. To increase throughput, open multiple stealth browser sessions and distribute keywords across them\n- **Test before batch execution**: After writing a batch script, first test with 1–2 keywords/pages to verify the script runs correctly; only then run the full batch\n- **Reduce redundant pre-operations**: Navigate once per keyword, apply all filters at once before extracting, rather than navigating multiple times\n- **Error resumption**: Save results keyword-by-keyword and page-by-page during batch processing; on failure, resume from the last saved position\n\n## Experience Notes\n\nPath: `{working-directory}/browser-act-skill-forge-memories/xianyu-scraper-goofish-search-list.memory.md`\n\n**Before execution**: If the file exists, read it first — it records unexpected situations encountered during past executions (e.g., a strategy has become ineffective); adjust strategy order accordingly.\n\n**After execution**: If an unexpected situation is encountered (strategy became ineffective, page redesigned, anti-scraping upgraded, better path discovered), append a line:\n`{YYYY-MM-DD}: {what happened} → {conclusion}`\n\nNormal execution does not write to the file. Do not record what keywords were used or how many results were returned — those are task outputs, not experience.","author":"@browser-act","ownerProfile":null,"authorContacts":null,"sourceUrl":"https://github.com/browser-act/skills/tree/main/solutions/ecommerce/goofish-search-list","license":"MIT","category":"research","lang":"en","tokens":1801,"stars":0,"calls30d":1,"claimed":false,"visibility":"public","origin":"crawler","version":"0.1.0","createdAt":"2026-08-22","updatedAt":"2026-08-22","files":[{"path":"scripts/apply-search-filters.py","size":4798,"sha256":"25e2bdd7ce15fd6c1f3545c08667673c6614fa15add693e8438b6b9275fed50c"},{"path":"scripts/extract-search-items.py","size":2339,"sha256":"115688e05366fe03d295b94828e5cecc432040a45b91c5263323cf4feae34210"},{"path":"scripts/goto-page.py","size":1233,"sha256":"952b2e4c8e55a78f94695dac63a21646eafc82769037c5b6bf4bfa883814022e"}],"requires":{"mcp":[],"tools":[]},"safety":{"flags":[{"code":"net.endpoints","kind":"exfiltration","excerpt":"img.alicdn.com, www.goofish.com","message":"bundled scripts reach 2 external host(s)","severity":"warn"}],"scannedAt":"2026-08-22","hasScripts":true,"networkEndpoints":["img.alicdn.com","www.goofish.com"]}}