赞
踩
要实现一个爬虫系统,那么代理是一个绕不开的话题。如果经费充裕,当然优先考虑收费代理。因为众所周知,免费代理的稳定性和可用性都无法得到有效的保障。所以笔者在这里分享一个免费代理IP的搜集和校验的Demo,并基于此可以有效的支撑分布式爬取网易云音乐的数据。
代理IP爬虫&校验源码:ProxyIpSpider
网易云音乐爬虫源码:CloudMusicSpider【附带数据API】
网易云音乐爬虫实现逻辑:博客
欢迎Start、Issue
爬取三一代理、西刺代理和无忧代理三个网站上的所有免费代理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校验,所以不建议在爬取信息的同时进行有效性校验。
挂代理访问待爬取的目标网站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()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。