recent.js
1 import { cli, Strategy } from '@jackwener/opencli/registry'; 2 import { clampInt } from '../_shared/common.js'; 3 4 cli({ 5 site: 'gov-policy', 6 name: 'recent', 7 description: '国务院最新政策文件', 8 domain: 'www.gov.cn', 9 strategy: Strategy.PUBLIC, 10 browser: true, 11 args: [ 12 { name: 'limit', type: 'int', default: 10, help: '返回结果数量 (max 20)' }, 13 ], 14 columns: ['rank', 'title', 'date', 'source', 'url'], 15 navigateBefore: false, 16 func: async (page, kwargs) => { 17 const limit = clampInt(kwargs.limit, 10, 1, 20); 18 await page.goto('https://www.gov.cn/zhengce/zuixin/index.htm'); 19 await page.wait(4); 20 const data = await page.evaluate(` 21 (async () => { 22 const normalize = v => (v || '').replace(/\\s+/g, ' ').trim(); 23 for (let i = 0; i < 20; i++) { 24 if (document.querySelector('.news_box li, .list li, .list_item, .news-list li')) break; 25 await new Promise(r => setTimeout(r, 500)); 26 } 27 const results = []; 28 for (const el of document.querySelectorAll('.news_box li, .list li, .list_item, .news-list li')) { 29 const titleEl = el.querySelector('a'); 30 const title = normalize(titleEl?.textContent); 31 if (!title || title.length < 4) continue; 32 33 let url = titleEl?.getAttribute('href') || ''; 34 if (url && !url.startsWith('http')) url = 'https://www.gov.cn' + url; 35 36 const date = (el.textContent || '').match(/(\\d{4}[-./]\\d{1,2}[-./]\\d{1,2})/)?.[1] || ''; 37 const source = normalize(el.querySelector('.source, .from')?.textContent); 38 39 results.push({ rank: results.length + 1, title, date, source, url }); 40 if (results.length >= ${limit}) break; 41 } 42 return results; 43 })() 44 `); 45 return Array.isArray(data) ? data : []; 46 }, 47 });