search.js
1 /** 2 * 什么值得买搜索好价 — browser cookie, DOM scraping. 3 * 4 * Fix: The old adapter used `search.smzdm.com/ajax/` which returns 404. 5 * New approach: navigate to `search.smzdm.com/?c=home&s=<keyword>&v=b` 6 * and scrape the rendered DOM directly. 7 */ 8 import { cli, Strategy } from '@jackwener/opencli/registry'; 9 cli({ 10 site: 'smzdm', 11 name: 'search', 12 description: '什么值得买搜索好价', 13 domain: 'www.smzdm.com', 14 strategy: Strategy.COOKIE, 15 args: [ 16 { name: 'query', required: true, positional: true, help: 'Search keyword' }, 17 { name: 'limit', type: 'int', default: 20, help: 'Number of results' }, 18 ], 19 columns: ['rank', 'title', 'price', 'mall', 'comments', 'url'], 20 func: async (page, kwargs) => { 21 const q = encodeURIComponent(kwargs.query); 22 const limit = kwargs.limit || 20; 23 // Navigate directly to search results page 24 await page.goto(`https://search.smzdm.com/?c=home&s=${q}&v=b`); 25 const data = await page.evaluate(` 26 (() => { 27 const limit = ${limit}; 28 const items = document.querySelectorAll('li.feed-row-wide'); 29 const results = []; 30 items.forEach((li) => { 31 if (results.length >= limit) return; 32 const titleEl = li.querySelector('h5.feed-block-title > a') 33 || li.querySelector('h5 > a'); 34 if (!titleEl) return; 35 const title = (titleEl.getAttribute('title') || titleEl.textContent || '').trim(); 36 const url = titleEl.getAttribute('href') || titleEl.href || ''; 37 const priceEl = li.querySelector('.z-highlight'); 38 const price = priceEl ? priceEl.textContent.trim() : ''; 39 let mall = ''; 40 const mallEl = li.querySelector('.z-feed-foot-r .feed-block-extras span') 41 || li.querySelector('.z-feed-foot-r span'); 42 if (mallEl) mall = mallEl.textContent.trim(); 43 const commentEl = li.querySelector('.feed-btn-comment'); 44 const comments = commentEl ? parseInt(commentEl.textContent.trim()) || 0 : 0; 45 results.push({ rank: results.length + 1, title, price, mall, comments, url }); 46 }); 47 return results; 48 })() 49 `); 50 if (!Array.isArray(data)) 51 return []; 52 return data; 53 }, 54 });