博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
二十七 Python分布式爬虫打造搜索引擎Scrapy精讲—通过自定义中间件全局随机更换代理IP...
阅读量:4573 次
发布时间:2019-06-08

本文共 7564 字,大约阅读时间需要 25 分钟。

设置代理ip只需要,自定义一个中间件,重写process_request方法,

request.meta['proxy'] = "http://185.82.203.146:1080"   设置代理IP

中间件,注意将中间件注册到配置文件里去

from adc.daili_ip.sh_yong_ip.sh_yong_ip import sui_ji_hq_ipfrom fake_useragent import UserAgent    #导入浏览器用户代理模块class RequestsUserAgentmiddware(object):                                    #自定义浏览器代理中间件    #中间件随机更换Requests请求头信息的User-Agent浏览器用户代理    def __init__(self,crawler):        super(RequestsUserAgentmiddware, self).__init__()                   #获取上一级父类基类的,__init__方法里的对象封装值        self.ua = UserAgent()                                               #实例化浏览器用户代理模块类        self.ua_type = crawler.settings.get('RANDOM_UA_TYPE','random')      #获取settings.py配置文件里的RANDOM_UA_TYPE配置的浏览器类型,如果没有,默认random,随机获取各种浏览器类型    @classmethod                                                            #函数上面用上装饰符@classmethod,函数里有一个必写形式参数cls用来接收当前类名称    def from_crawler(cls, crawler):                                         #重载from_crawler方法        return cls(crawler)                                                 #将crawler爬虫返回给类    def process_request(self, request, spider):                             #重载process_request方法        def get_ua():                                                       #自定义函数,返回浏览器代理对象里指定类型的浏览器信息            return getattr(self.ua, self.ua_type)        sssf = get_ua()        print('启用用户代理浏览器信息:{0}'.format(sssf))        request.headers.setdefault('User-Agent', get_ua())                  #将浏览器代理信息添加到Requests请求class MyproxiesSpiderMiddleware(object):    #中间件随机更换IP    def process_request(self, request, spider):                             #重写process_request方法        #到数据库随机获取一个IP        xieyi = request._get_url()                                          #_get_url可以获取到请求URL,来判断是什么协议请求如https        print(xieyi)        dai_ip = sui_ji_hq_ip('http')                                       #到数据库随机获取一个代理IP        request.meta['proxy'] = "http://{0}".format(dai_ip)                 #字符串格式化设置代理IP        #request.meta['proxy'] = "http://185.82.203.146:1080"   设置代理IP

 

 

随机数据库获取IP

#!/usr/bin/env python# -*- coding:utf8 -*-import timeimport requestsfrom adc.daili_ip.mysq import shujuku as ORMdef suiji_ip(rst):    """    调用此函数随机到数据库获取代理IP返回IP,如果IP不可用会自动删除返回False    """    atime = time.localtime(time.time()-240)          #设置获取多少时间以内检测过的IP(单位秒)    sudu = '00:00:03'                               #设置获取访问速度小于等于多少的IP,单位(时分秒)默认3秒    dqatime = "{0}-{1}-{2} {3}:{4}:{5}".format(        atime.tm_year,        atime.tm_mon,        atime.tm_mday,        atime.tm_hour,        atime.tm_min,        atime.tm_sec    )  # 将格式化时间日期,单独取出来拼接成一个完整日期    try:        mysq = ORM.session()        shuju = mysq.query(            ORM.daili_ip.ip,            ORM.daili_ip.port,            ORM.daili_ip.xtype,            ORM.daili_ip.seshi_ri_qi,            ORM.daili_ip.connectTimeMs        ).from_statement(            "SELECT ip,port,xtype,seshi_ri_qi,connectTimeMs FROM daili_ip WHERE xtype='{0}' AND ce_shi='{1}' AND seshi_ri_qi>='{2}' AND connectTimeMs<='{3}' ORDER BY RAND() LIMIT 1".format(rst, '1', dqatime, sudu)        ).all()        mysq.close()        if shuju:            print('获取到IP')        else:            print('获取IP失败,请检查获取条件')    except Exception as e:        print('查询代理IP数据出错')        return True    ip = shuju[0][0]    duan_kou = shuju[0][1]    print('启用代理IP,数据库获取到IP:{0}'.format(shuju))    http_url = '{0}://image.baidu.com/'.format(rst)    proxy_url = '{0}://{1}:{2}'.format(rst, ip, duan_kou)    headers = {        'Referer': http_url,        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:54.0) Gecko/20100101 Firefox/54.0',    }    print('启用代理IP,测试网址:{0}'.format(http_url))    print('启用代理IP,测试头:{0}'.format(proxy_url))    try:        proxy_dict = {            'http': proxy_url        }        response = requests.get(http_url, proxies=proxy_dict, headers=headers)    except Exception as e:        print('启用代理IP,测速连接失败{0}'.format(e))        print('启用代理IP,测速连接失败,当前IP不可用,删除当前ip!')        fanhui = mysq.query(ORM.daili_ip).filter(ORM.daili_ip.ip == ip).delete()  # 删除不可以数据        mysq.commit()        mysq.close()        if fanhui == 1:            print("成功删除当前IP")        else:            print('删除当前IP失败')        return False    else:        code = response.status_code  # 获取状态吗        sudu = str(response.elapsed)  # 获取响应时间        if code >= 200 and code < 300:            atime = time.localtime()            dqatime = "{0}-{1}-{2} {3}:{4}:{5}".format(                atime.tm_year,                atime.tm_mon,                atime.tm_mday,                atime.tm_hour,                atime.tm_min,                atime.tm_sec            )  # 将格式化时间日期,单独取出来拼接成一个完整日期            print('启用代理IP,测试代理ip--{0}{1}--状态可用--状态码--{2}'.format(ip, duan_kou, code))            print('启用代理IP,当前IP可以,正在向数据库标记')            fanhui = mysq.query(ORM.daili_ip).filter(ORM.daili_ip.ip == ip).update({                "ce_shi": "1",                "seshi_ri_qi": dqatime,                "connectTimeMs": sudu            })            mysq.commit()            mysq.close()            if fanhui == 1:                print('向数据库成功标记可用IP!')            else:                print('向数据库标记可用IP失败!!!')            print('向爬虫返回IP:{0}:{1}'.format(ip, duan_kou))            return ip + ':' + duan_kou        else:            print('启用代理IP,测试代理ip--{0}{1}--状态不可用--状态码--{2}'.format(ip, duan_kou, code))            print('返回状态码不可以,正在向数据库删除当前IP')            fanhui = mysq.query(ORM.daili_ip).filter(ORM.daili_ip.ip == ip).delete()  # 删除不可以数据            mysq.commit()            mysq.close()            if fanhui == 1:                print('删除当前IP成功')            else:                print('删除当前IP失败')            return Falsedef sui_ji_hq_ip(rst):    """    正式使用:调用此函数,接收一个参数协议,如http    循环到数据库获取IP,IP如果不可用删除后继续获取,直到ip可以后返回ip    值循环获取测试30分钟内有效的IP    """    n = True    h = None    while n:        youxiao_ip = suiji_ip(rst)        if youxiao_ip:            h = youxiao_ip            n = False    return h# print(sui_ji_hq_ip('http'))

 

 

数据库模块文件

import sqlalchemyfrom sqlalchemy.ext.declarative import declarative_basefrom sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index,text,DATETIME,TIMEfrom sqlalchemy.orm import sessionmaker, relationshipfrom sqlalchemy import create_engineimport requestsimport jsonimport timeimport datetime#配置数据库引擎信息ENGINE = create_engine("mysql+pymysql://root:279819@127.0.0.1:3306/cshi?charset=utf8", max_overflow=500, echo=True)Base = declarative_base()       #创建一个SQLORM基类class daili_ip(Base):            #ip池设计表    __tablename__ = 'daili_ip'    id = Column(Integer, primary_key=True, autoincrement=True)    ip = Column(String(300), unique=True)       #IP    port = Column(String(300))                  #端口    city = Column(String(300))                  #城市    isp = Column(String(300))                   #运营商    connectTimeMs = Column(TIME())              #速度    anonymity = Column(String(300))             #匿名方式    country = Column(String(300))               #国家    xtype = Column(String(300))                 #协议    zhuang_tai_ma = Column(String(300))         #状态码    ruku_riqi = Column(DATETIME())             #入库日期    ce_shi = Column(String(300))                #测试状态    seshi_ri_qi = Column(DATETIME())           #测试日期    shi_xiao_riqi = Column(DATETIME())         # 失效日期def init_db():    Base.metadata.create_all(ENGINE)        #向数据库创建指定表def drop_db():    Base.metadata.drop_all(ENGINE)          #向数据库删除指定表def session():    cls = sessionmaker(bind=ENGINE)         #创建sessionmaker类,操作表    return cls()# drop_db()         #删除表# init_db()

 

转载于:https://www.cnblogs.com/meng-wei-zhi/p/8182753.html

你可能感兴趣的文章
1003: 相邻数对问题
查看>>
【踩坑】List 的陷阱
查看>>
【开源】封装HTML5的localstorage
查看>>
通过ABAP代码判断当前系统类型,BYD还是S4 OP还是S4 Cloud
查看>>
买相机
查看>>
使用MDK将STM32的标准库编译成lib使用
查看>>
读《构建之法》1,2,3章后感
查看>>
luogu 1593 因子和
查看>>
将扁平化的JSON属性转换为嵌套的JSON
查看>>
[中英对照]Introduction to DPDK: Architecture and Principles | DPDK概论: 体系结构与实现原理...
查看>>
读黑客与画家啦
查看>>
JSONCPP使用
查看>>
MAC OSX 10.10 下启用自带的Apache的rewrite模块
查看>>
Jenkins持续集成iOS项目
查看>>
对卷积的定义和意义的通俗解释
查看>>
GlusterFS缺陷
查看>>
(づ ̄3 ̄)づ╭❤~
查看>>
java程序设计第二次作业
查看>>
idea使用generatorconfig生成
查看>>
$.ajax()方法详解
查看>>