python程序员解决爬虫IP被封的优秀资料和神器

代理池是爬虫、采集、爆破、刷单等必不可少的配备。读了一个github的py代理池的源码,简单易用免维护,也无需过多配置,该程序从网站爬取代理列表,存入SQLite数据库。定时执行爬取->存入->检查->爬取的循环以保证采集到代理IP的可用性。

开两个线程,一个用做服务器对外提供代理IP,另一个用于维护代理池里IP的可用性。

线程1

def _api(self):
 ProxyServer(API_CONFIG['PORT'])
class ProxyServer:
 def __init__(self, port):
 self.port = int(port) self.run() .... def run(self):
 http_server = HTTPServer(('localhost', self.port), self.ProxyPoolHandler)
 logger.info('listened on localhost:%s' % API_CONFIG['PORT'])
 http_server.serve_forever()

二、本地搭建HTTP服务,使用URL参数作为筛选条件从数据库中筛出符合条件的代理并以json格式返回。

def get_proxy(self, params):
 where_dict = {'port': 'port', 'type': 'type', 'protocol': 'protocol', 'area': 'area'}
 conds = { 'field': ['ip', 'port'],
 'order': ['updatetime desc', 'lastusedtime', 'score desc', 'speed'],
 'limit': 1,
 'where': [],
 } if params:
 for (k, v) in params.items():
 try:
 if k == 'num':
 conds['limit'] = v[0]
 elif k == 'area':
 conds['where'].append((where_dict[k], 'like', '%%%s%%' % v[0]))
 else:
 conds['where'].append((where_dict[k], '=', v[0]))
 except: continue
 data = self.sqlite.select(self.table_name, conds)
 tmp = [{'ip': n[0], 'port': n[1], 'lastusedtime': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')} for
 n in data]
 self.sqlite.update(self.table_name, tmp) data = ['%s:%s' % n for n in data]
 return json.dumps(data)

因为每个加入代理池的ip都设置了过期时间,所以检查代理ip是否有效这个操作,也并非真的去检验ip本身,而是检查它的过期时间。

线程2

def _monitor(self):
 while True:
 self._update(PROXYPOOL_CONFIG['UPDATE_TIME'])
 self._delete(PROXYPOOL_CONFIG['DELETE_TIME'])
 self._crawl(PROXYPOOL_CONFIG['CRAWL_TIME'])
 time.sleep(1800)
我们需要清除掉过期时间<当前时间的ip。
# -*- coding: utf-8 -*-
# @File : delele_ip.py# @Author: AaronJny# @Date : 18-12-14 上午11:15
# @Desc : 过期ip清理器import utilsimport settingsimport timeclass ExpireIpCleaner:def __init__(self):
 self.logger = utils.get_logger(getattr(self.__class__, '__name__'))
 self.server = utils.get_redis_client()
 def clean(self):
 """
 清理代理池中的过期ip
 :return:
 """
 self.logger.info('开始清理过期ip')
 # 计算清理前代理池的大小 total_before = int(self.server.zcard(settings.IP_POOL_KEY))
 # 清理 self.server.zremrangebyscore(settings.IP_POOL_KEY, 0, int(time.time()))
 # 计算清理后代理池的大小 total_after = int(self.server.zcard(settings.IP_POOL_KEY))
 self.logger.info('完毕!清理前可用ip {},清理后可用ip {}'.format(total_before, total_after))
 def main(self):
 """
 周期性的清理过期ip
 :return:
 """
 while True:
 self.clean()
 self.logger.info('*' * 40)
 time.sleep(settings.CLEAN_INTERVAL)if __name__ == '__main__':
 ExpireIpCleaner().main()

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值