zoukankan      html  css  js  c++  java
  • 随机切换IP和UA

      在爬虫爬取过程中,网站会根据我们的IP和UA去确认到底是浏览器操作还是爬虫在操作,所以,为了让爬虫不被网站禁止,随机切换Ip 和UA是很重要的,因为这个类在各个爬虫中经常要用到,所以可以自已维护一份随机切换IP和UA的代码,

      可以在爬虫工程目录中加入tools这个目录,这个目录中存放着这个爬虫所用到的一些工具,

        目录结构如下:

      

      get_ip.py 代码如下:

      

    import requests
    import pymysql
    
    
    class GetIp(object):
        """从数据库中取出可用的IP给爬虫使用"""
        conn = pymysql.connect(host="127.0.0.1", user="root", password="root", db="outback")
        cursor = conn.cursor()
    
        def get_random_ip(self):
            select_sql = "select ip,port,type from ip_proxy ORDER  by rand() limit 1"
    
            result = self.cursor.execute(select_sql)
            for ip_info in self.cursor.fetchall():
                ip = ip_info[0]
                port = ip_info[1]
                type = ip_info[2].lower()
                judge_result = self.judge_ip(type, ip, port, )
                if judge_result:
                    # 这里不能关闭连接,因为每一个请求都会云获取一个IP,如果关了,就只能获取一个
                    # self.cursor.close()
                    # self.conn.close()
    
                    return "{0}://{1}:{2}".format(type, ip, port)
                else:
                    self.get_random_ip()
    
        def judge_ip(self, type, ip, port):
        """验证IP是否可用,如果可以用,则返回,不可用,则删除数据库中的该IP""" baidu
    = "https://www.baidu.com" proxy_url = "{0}://{1}:{2}".format(type, ip, port) try: proxy_dict = {type:proxy_url,} response = requests.get(baidu, proxies=proxy_dict) except Exception as e: print("invalid in or port ") self.delete_ip(ip) return False else: code = response.status_code if code >= 200 and code < 300: print("effective ip,the ip is",proxy_url) return True else: print("invalid iP ") self.delete_ip(ip) return False def delete_ip(self, ip): delete_sql = """delete FROM ip_proxy where ip='{0}'""".format(ip) try: self.cursor.execute(delete_sql) self.conn.commit() except Exception as e: print(e) if __name__ == "__main__": get_ip = GetIp() ip = get_ip.get_random_ip() print(ip)

    之后在middlewares.py 中进行设置,

    middlewares.py代码如下:

    from taobao.tools.get_ip import GetIp
    
    class RandomProxyMiddleware(object):
        #动态设置ip代理
        def process_request(self, request, spider):
            get_ip = GetIP()
            request.meta["proxy"] = get_ip.get_random_ip()

    这样就可以使scrapy 动态的随机更换IP

    二 随机更换UA,

      自己可以在settings中维护一个ua池,然后随机切换,但是这样有个不好的地方是,自已维护UA池很麻烦,还在定期查看这些UA是否可用,网上有个开源的库 fake-useragent

    这个库动态的管理着很多UA,可以使用。

    用法如下:

    from scrapy import signals
    from fake_useragent import UserAgent
    
    class RandomUserAgentMiddleware(object):
        """使用爬虫使用随机的Ip 和 UA"""
    
        def __init__(self, crawler):
            self.ua = UserAgent()
            self.ua_type = crawler.settings.get("USER_AGENT_TYPE", "random")
            super(RandomIpAndUserAgentMiddleware, self).__init__()
    
        @classmethod
        def from_crawler(cls, crawler):
            return cls(crawler)
    
        def process_request(self, request, spider):
            def get_ua():
                return getattr(self.ua, self.ua_type)
    
            request.headers.setdefault('User-Agent', get_ua())

    其实上边两个类可写成一个类,这个在settings中只设置一个类就行了,代码如下:

    from scrapy import signals
    from fake_useragent import UserAgent
    from taobao.tools.get_ip import GetIp
    
        def process_request(self, request, spider):
            def get_ua():
                return getattr(self.ua, self.ua_type)
            request.headers.setdefault('User-Agent', get_ua())
            get_ip = GetIP()
            request.meta["proxy"] = get_ip.get_random_ip()

    上面代码中有几个非常重要的,也是很容易出错的地了,

    一、老师,前辈们经常会说,文件打开记得关闭,数据库连接后记得断开连接,但是在GetIp这个类中不能断开数据库(我在这里也卡了),因为scrapy是随机取IP,也就意味着scrapy对每次请求(也可能是每几次请求)就会去数据库中取IP,所以如果在GetIp这个类中就断开连接后,也就是只能取一次,下次就不能取了,所以GetIp这个类中不能断开连接,可以使用scrapy 信号,当爬虫关闭的时候断开连接。所以GetIp类不连接数据而没有断开连接是没有错的。

    二,西刺的IP很慢,所以还是珍惜自已的IP,友好爬取,

    GitHub https://github.com/573320328/tools

  • 相关阅读:
    日本最大的汽车品牌:丰田【仅供自己参考】
    读书笔记1
    读书笔记1
    计算机网络笔记1
    ZY凉凉经
    HK凉凉经
    访问一个网站,发生了什么?
    正向代理VS反向代理
    mac下打开hosts文件
    国际手机区号
  • 原文地址:https://www.cnblogs.com/liuqianli/p/8325688.html
Copyright © 2011-2022 走看看