zoukankan      html  css  js  c++  java
  • 程序员解决爬虫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()
    
     
  • 相关阅读:
    xls与csv文件的区别
    青音,经典爱情语录
    win7用户账户自动登录方法汇总
    How to using Procedure found Lead Blocker
    FTS(3) BSD 库函数手册 遍历文件夹(二)
    FTS(3) BSD 库函数手册 遍历文件夹(一)
    DisplayMetrics类 获取手机显示屏的基本信息 包括尺寸、密度、字体缩放等信息
    About App Distribution 关于应用发布
    FTS(3) 遍历文件夹实例
    OpenCV 2.1.0 with Visual Studio 2008
  • 原文地址:https://www.cnblogs.com/jiguangdongtaiip/p/13619123.html
Copyright © 2011-2022 走看看