JavaScript爬虫使用API提取代理模板

发布于:2025-07-03 ⋅ 阅读:(16) ⋅ 点赞:(0)

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项目中,为大家的爬虫提供可靠的代理支持。、


网站公告

今日签到

点亮在社区的每一天
去签到