zoukankan      html  css  js  c++  java
  • 超强程序员用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 utils
    import settings
    import time
    class 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()
  • 相关阅读:
    Go基础系列:流程控制结构
    Go基础系列:数据类型转换(strconv包)
    Go基础系列:简单数据类型
    Go基础系列:常量和变量
    Go基础系列:map类型
    Go基础系列:Go slice详解
    go基础系列:数组
    Go基础系列:import导包和初始化阶段
    Go基础系列:构建go程序
    go基础系列:结构struct
  • 原文地址:https://www.cnblogs.com/jiguangdongtaiip/p/13560569.html
Copyright © 2011-2022 走看看