#!/usr/bin/env node /** * 搜索技术博客 * 用法: node search-tech.js <关键词> [juejin|cnblogs|all] */ const https = require('https'); const fs = require('fs'); const path = require('path'); // 保存结果 function saveResult(platform, data) { const timestamp = new Date().toISOString().replace(/[:.]/g, '-'); const filename = `${platform}_search_${timestamp}.json`; const filepath = path.join(__dirname, '../data', filename); if (!fs.existsSync(path.dirname(filepath))) { fs.mkdirSync(path.dirname(filepath), { recursive: true }); } fs.writeFileSync(filepath, JSON.stringify(data, null, 2), 'utf-8'); console.log(`💾 结果已保存: ${filepath}`); } // HTTP 请求 function httpGet(url, headers = {}) { return new Promise((resolve, reject) => { https.get(url, { headers }, (res) => { let data = ''; res.on('data', chunk => data += chunk); res.on('end', () => resolve(data)); }).on('error', reject); }); } // 搜索掘金 async function searchJuejin(keyword) { console.log(`\n📱 搜索掘金: "${keyword}"`); console.log('-'.repeat(60)); try { const url = `https://juejin.cn/search?query=${encodeURIComponent(keyword)}&type=0`; const html = await httpGet(url, { 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36', 'Referer': 'https://juejin.cn/', }); const items = []; const regex = /href="https:\/\/juejin\.cn\/post\/(\d+)"[^>]*>([^<]+)<\/a>/gi; let match; while ((match = regex.exec(html)) !== null && items.length < 10) { const title = match[2].trim(); if (title.length > 5 && !items.find(i => i.title === title)) { items.push({ rank: items.length + 1, title: title.substring(0, 80), url: `https://juejin.cn/post/${match[1]}`, }); } } if (items.length > 0) { items.forEach(i => console.log(`${i.rank}. ${i.title}`)); saveResult('juejin', { keyword, items }); console.log(`✅ 找到 ${items.length} 条结果`); } else { console.log('⚠️ 未找到结果'); } return items; } catch (e) { console.error('❌ 掘金搜索失败:', e.message); return []; } } // 搜索博客园 async function searchCnblogs(keyword) { console.log(`\n💻 搜索博客园: "${keyword}"`); console.log('-'.repeat(60)); try { const url = `https://zzk.cnblogs.com/s?w=${encodeURIComponent(keyword)}`; const html = await httpGet(url, { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', }); const items = []; // 匹配搜索结果 const titleRegex = /]*class="searchItemTitle"[^>]*href="([^"]+)"[^>]*>([\s\S]*?)<\/a>/gi; let match; while ((match = titleRegex.exec(html)) !== null && items.length < 10) { const url = match[1]; const title = match[2].replace(/<[^>]+>/g, '').trim(); if (title.length > 5 && !items.find(i => i.title === title)) { items.push({ rank: items.length + 1, title: title.substring(0, 80), url: url.startsWith('http') ? url : `https:${url}`, }); } } if (items.length > 0) { items.forEach(i => console.log(`${i.rank}. ${i.title}`)); saveResult('cnblogs', { keyword, items }); console.log(`✅ 找到 ${items.length} 条结果`); } else { console.log('⚠️ 未找到结果'); } return items; } catch (e) { console.error('❌ 博客园搜索失败:', e.message); return []; } } // 主函数 async function main() { const keyword = process.argv[2]; const platform = process.argv[3] || 'all'; if (!keyword) { console.log('用法: node search-tech.js <关键词> [juejin|cnblogs|all]'); process.exit(1); } console.log('='.repeat(60)); console.log(`🔍 技术博客搜索: "${keyword}"`); console.log('='.repeat(60)); if (platform === 'all' || platform === 'juejin') { await searchJuejin(keyword); } if (platform === 'all' || platform === 'cnblogs') { await searchCnblogs(keyword); } console.log('\n' + '='.repeat(60)); console.log('搜索完成'); console.log('='.repeat(60)); } main().catch(console.error);