JavaScript爬虫有两大优势:直接执行页面JS(Puppeteer/Playwright)和解析SPA(单页应用)如 React/Vue这就是我为何钟爱于JavaScript爬虫的原因。最近有几个同行说,使用API代理IP配合JavaScript经常报错,修改请求头或者访问频率也未能解决问题,因此,请求我们出手修改代码,一看代码简直惨不忍睹,能运行起来算他运气好,索性我自己写个通用模版给他参考。
以下是一个JavaScript爬虫模板,用于提取并验证代理IP,配合API使用。该模板包含代理获取、验证和API集成功能:
const axios = require('axios');
const cheerio = require('cheerio');
// 配置对象
const config = {
// 代理源网站(支持多个)
proxySources: [
'https://free-proxy-list.net/',
'https://www.sslproxies.org/'
],
// 验证代理的测试URL(推荐使用高稳定性API)
testUrl: 'https://httpbin.org/ip',
// 请求超时时间(毫秒)
timeout: 5000,
// 每次验证的最大并发数
maxConcurrency: 20
};
/**
* 从HTML页面提取代理列表
* @param {string} html - 页面HTML内容
* @returns {Array} 代理列表 [ {ip, port, protocol} ]
*/
function parseProxiesFromHtml(html) {
const $ = cheerio.load(html);
const proxies = [];
// 示例:解析free-proxy-list的表格
$('#proxylisttable tbody tr').each((i, row) => {
const cols = $(row).find('td');
const ip = $(cols[0]).text().trim();
const port = $(cols[1]).text().trim();
const protocol = $(cols[6]).text().includes('yes') ? 'https' : 'http';
if (ip && port) {
proxies.push({ ip, port, protocol });
}
});
return proxies;
}
/**
* 验证代理可用性
* @param {Object} proxy - 代理对象 {ip, port, protocol}
* @returns {Promise<Object|boolean>} 可用时返回代理信息,不可用时返回false
*/
async function validateProxy(proxy) {
const { ip, port, protocol } = proxy;
const proxyUrl = `${protocol}://${ip}:${port}`;
try {
const response = await axios.get(config.testUrl, {
proxy: {
host: ip,
port: parseInt(port)
},
timeout: config.timeout
});
// 验证响应数据是否有效
if (response.data && response.data.origin) {
return {
...proxy,
speed: response.headers['request-duration'] || 'unknown',
country: 'unknown'
};
}
} catch (e) {
// 代理验证失败
}
return false;
}
/**
* 批量验证代理(并发控制)
* @param {Array} proxies - 代理列表
* @returns {Promise<Array>} 可用代理列表
*/
async function batchValidate(proxies) {
const workingProxies = [];
const promises = [];
for (const proxy of proxies) {
const promise = validateProxy(proxy).then(result => {
if (result) workingProxies.push(result);
});
promises.push(promise);
// 控制并发数量
if (promises.length >= config.maxConcurrency) {
await Promise.all(promises);
promises.length = 0; // 清空数组
}
}
// 等待剩余请求完成
await Promise.all(promises);
return workingProxies;
}
/**
* 主函数:获取并验证代理
*/
async function getProxies() {
const allProxies = [];
// 从所有源获取代理
for (const source of config.proxySources) {
try {
const response = await axios.get(source, {
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36'
},
timeout: config.timeout
});
const proxies = parseProxiesFromHtml(response.data);
allProxies.push(...proxies);
console.log(`[+] ${source} 获取 ${proxies.length} 个代理`);
} catch (e) {
console.error(`[-] ${source} 获取失败: ${e.message}`);
}
}
console.log(`[总计] 获取 ${allProxies.length} 个代理,开始验证...`);
// 验证代理
const workingProxies = await batchValidate(allProxies);
console.log(`[有效] 验证通过 ${workingProxies.length} 个代理`);
return workingProxies;
}
/**
* 示例:API端点返回代理列表
* 使用示例:GET /api/proxies?limit=10
*/
const express = require('express');
const app = express();
app.get('/api/proxies', async (req, res) => {
const limit = parseInt(req.query.limit) || 20;
try {
const proxies = await getProxies();
res.json({
success: true,
count: proxies.slice(0, limit).length,
proxies: proxies.slice(0, limit)
});
} catch (e) {
res.status(500).json({
success: false,
error: e.message
});
}
});
// 启动服务器
const PORT = 3000;
app.listen(PORT, () => {
console.log(`代理API服务运行在 http://localhost:${PORT}/api/proxies`);
});
// 单独运行获取代理
// getProxies().then(proxies => {
// console.log('可用代理列表:', proxies);
// });
使用说明:
1、安装依赖:
npm install axios cheerio express
2、功能特点:
- 多代理源支持(可自由扩展)
- 智能代理验证系统
- 并发控制优化性能
- API接口服务
- 自动协议检测(HTTP/HTTPS)
- 请求超时处理
3、API端点:
GET /api/proxies?limit=10
4、配置选项:
proxySources
:代理源列表testUrl
:代理验证地址timeout
:请求超时时间maxConcurrency
:最大并发验证数
5、扩展建议:
- 添加代理持久化(数据库存储)
- 增加定时刷新机制
- 添加代理评分系统
- 集成更多代理源(如西刺代理、站大爷等)
- 添加用户认证API
使用示例:
// 直接调用获取代理
getProxies().then(workingProxies => {
console.log('可用代理:', workingProxies);
// 在axios中使用代理示例
axios.get('https://target-website.com', {
proxy: {
host: workingProxies[0].ip,
port: workingProxies[0].port
}
});
});
部分代理网站有反爬机制,建议:随机化请求头、添加请求延迟、使用代理池递归获取同时也要尊重目标网站爬取规则,避免高频请求。
上面的模板拿来可直接运行,也可集成到现有Node.js项目中,为大家的爬虫提供可靠的代理支持。、