免费代理IP爬虫 & IP有效性校验

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/YHYR_YCY/article/details/83476381

要实现一个爬虫系统,那么代理是一个绕不开的话题。如果经费充裕,当然优先考虑收费代理。因为众所周知,免费代理的稳定性和可用性都无法得到有效的保障。所以笔者在这里分享一个免费代理IP的搜集和校验的Demo,并基于此可以有效的支撑分布式爬取网易云音乐的数据。
代理IP爬虫&校验源码:ProxyIpSpider
网易云音乐爬虫源码:CloudMusicSpider【附带数据API】
网易云音乐爬虫实现逻辑:博客
欢迎Start、Issue

代理IP爬取

爬取三一代理、西刺代理和无忧代理三个网站上的所有免费代理IP信息,并持久化到mysql中,数据表结构如下所示:

CREATE TABLE `proxy_ip_info` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `proxy_ip` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5085 DEFAULT CHARSET=utf8mb4;

IP有效性校验

注:由于免费IP大概率无法使用,或者存活时间较短;且IP爬取的速率远高于IP校验,所以不建议在爬取信息的同时进行有效性校验

校验思路

挂代理访问待爬取的目标网站URL即可

实现方式

通过并发 + 定时轮询,实现高效且持续的校验

# -*- coding: utf-8 -*-
"""
代理Ip有效性校验
相对于爬取, IP的有效性校验比比较耗时的;
又因为Scrapy本身不支持并发, 所以在爬取IP的同时校验有效性会导致最终效率过于低下
可通过后台单独运行此脚本, 并基于进程池来提升校验效率
此处默认的进程数为10;校验等待超时时长为10s;
@Author YH YR
@Time 2018/10/24 17:19
"""
import random
import time

import multiprocessing
import requests

from ProxyIpSpider.utils.mysqlUtil import MysqlUtil
from ProxyIpSpider.utils.user_agents import agents
from ProxyIpSpider.settings import *

mysql = MysqlUtil(host, user_name, pass_word, db_name, port)


class IPValidityCheck:
    @staticmethod
    def run(processes_num=10):
        """
        轮询代理IP表, 通过线程池提升IP筛选效率
        在一轮筛选过后,暂停5分钟后继续筛选
        :param processes_num:
        :return:
        """
        query_sql = 'select id, proxy_ip from proxy_ip_info'
        while True:
            results = mysql.query(query_sql, num='all')
            if len(results) == 0:
                print('IP table is empty')
                return
            pool = multiprocessing.Pool(processes=processes_num)
            for i in results:
                auto_increase_id = i[0]
                ip = i[1]
                pool.apply_async(proxy_ip_check, args=(ip, auto_increase_id))
            pool.close()
            pool.join()
            print('Cycle check per minutes')
            time.sleep(60)


def proxy_ip_check(check_ip, auto_increase_id, check_timeout=10):
    """
    代理IP有效性检验
    判断依据: 访问带爬取的目标地址, 根据请求返回结果初步判断有效性
    :param check_ip: 待检查IP
    :param auto_increase_id: 该数据在MySQL中对应的自增长Id
    :param check_timeout: 请求超时时长; 如果在该时间内请求无响应, 则认为此Ip无效
    :return:
    """
    delete_sql = 'delete from proxy_ip_info where id = {0}'.format(auto_increase_id)
    proxies = {'http': check_ip}
    agent = random.choice(agents)
    header = {'Referer': 'https://music.163.com/', 'User-Agent': agent}
    try:
        proxy_response = requests.get(request_check_url, proxies=proxies, headers=header, timeout=check_timeout)
        if proxy_response.status_code == 200:
            print('Valid IP: {0}'.format(check_ip))
        else:
            print('Invalid IP: {0}'.format(check_ip))
            mysql.modify(delete_sql.format(auto_increase_id))
    except:
        print('Invalid IP: {0}'.format(check_ip))
        mysql.modify(delete_sql.format(auto_increase_id))


if __name__ == '__main__':
    IPValidityCheck.run()

猜你喜欢

转载自blog.csdn.net/YHYR_YCY/article/details/83476381