node爬虫类&&切换免费IP代理池

在初写爬虫的时候发现即使增加延时请求爬网站,有时候还是会有连接错误,然后打算设计一个可以自动切换IP代理的爬虫类免费ip代理。

const request = require("request");
const cheerio = require('cheerio');

class reqSpider {
    constructor(option) {
        this.proxy_list = [];
        this.reConnt = 0;
        this.opt = Object.assign({
            method: "GET",
            timeout: 120000, //2Mins
            rejectUnauthorized: false, //不检查证书
            reMax: 15 //只切换15次IP
        }, option);
    }
    run() {
        return new Promise((resolve, reject) => {
            let s = +new Date();
            request(this.opt, async (error, response, body) => {
                let e = +new Date();
                if (error || body.indexOf("502 Bad Gateway") > -1) { //根据业务情况来判断发现爬取会出现502报错
                    await this.set_proxy();
                    if (this.reConnt < this.opt.reMax) { //如果超过15次重复爬取,就不在重复,不然任务会一直卡死
                        this.reConnt++;
                        this.run();
                    } else {
                        reject(error);
                    }
                    return
                }
                this.reConnt = 0;
                resolve({
                    body,
                    timeCon: e - s
                });
            })
        })
    }
    /*
        @测试代理IP是否可用
    */
    test_proxy(ip) {
        return new Promise((resolve, reject) => {
            request.get({
                url: "http://www.baidu.com",
                proxy: "http://" + ip
            }, (err, res, body) => {
                if (err) {
                    resolve(false)
                };
                resolve(true);
            })
        })
    }
    /*
        @检查代理
    */
    async check_ip() {

        !this.proxy_list.length && (this.proxy_list = await this.get_proxy());

        let s = this.proxy_list.shift();
        let result = await this.test_proxy(s); //true / false 测试IP是否可以使用
        if (result || !this.proxy_list.length) {
            return s || null;
        } else {
            this.check_ip();
        }
    }
    /*
        设置代理
    */
    async set_proxy() {
        let proxy_ip = await this.check_ip();
        if (proxy_ip != undefined) {
            this.opt.proxy = proxy_ip;
        } else {
            await this.set_proxy();
        }
    }
    /*
        获取代理IP
    */
    get_proxy() {
        //使用了https://www.freeip.top/?page=1 免费代理
        return new Promise((resolve, reject) => {
            request.get({
                url: "https://www.freeip.top/?page=1" // 网址失效了你可以切换你自己的
            }, function (e, r, b) {
                if (e) {
                    return []
                };
                var $ = cheerio.load(b);
                let td = $(".ip-tables").find(".layui-table tbody tr");
                let ips = [];
                for (let i = 0; i < td.length; i++) {
                    let ip = $(td).eq(i).find("td").eq(0).text() + ":" + $(td).eq(i).find("td").eq(1).text();
                    ips.push(ip);
                }
                resolve(ips);
            })
        })
    }
}
贡献者: mankueng