zoukankan      html  css  js  c++  java
  • scrapy中间件中使用selenium切换ip

    scrapy抓取一些需要js加载页面时一般要么是通过接口直接获取数据,要么是js加载,但是我通过selenium也可以获取动态页面

    但是有个问题,容易给反爬,因为在scrapy中间件mid中使用selenium的ip不会跟着你在中间件中切换的ip变化,还是使用本机的ip在访问网站,

    这里通过 确定网页url进行过滤,什么网页使用selenium,什么使用scrapy自带的抓取,

    为selenium单独设置一个获取ip的办法,当然也可以使用全局变量

    from selenium import webdriver
    from scrapy.http.response.html import HtmlResponse
    from selenium.webdriver.chrome.options import Options
    import json
    import requests
    
    
    class ip_mid(object):
        def __init__(self):
            self.ip = ''
            self.url = 'http://proxy.1again.cc:35050/api/v1/proxy/?type=2'
            self.ip_num = 0
    
    
        def process_request(self,request,spider):
            # if re.findall(r'根据需求的url过滤,简单的页面', request.url):
            print('正在使用ip')
            if self.ip_num ==0 or self.ip_num >=10:
                res = json.loads(requests.get(url=self.url).content.decode())
                if res:
                    ip = res['data']['proxy']
                    print(ip,'-'*20)
                    self.ip = ip
                    print(self.ip)
                    self.ip_num = 1
    
            if self.ip:
                request.meta['proxy'] = 'http://' + self.ip
                self.ip_num += 1
                print('ip地址>>>{} --- 使用次数{}'.format(self.ip, self.ip_num))
            else:
                self.ip_num += 3
                print('使用的是本机ip......')
    
    '''
    两个获取ip的设置,对ip池的访问返回是个问题,
    如果加上一个判定什么网页使用selenium + 获取ip,什么网页使用正常的获取ip正常的访问
    比如 if re.findall(r'根据需求的url过滤,必须使用selenium加载的js动态页面',request.url)
    '''
    class YanzhenIp_selenium_DownloaderMiddleware(object):
    
        def __init__(self):
    
            self.chrome_options = Options()
            self.chrome_options.add_argument('--headless')
            self.chrome_options.add_argument('--disable-gpu')
            # self.driver = webdriver.Chrome(chrome_options=chrome_options)
            self.chrome_options.add_experimental_option('excludeSwitches', ['enable-automation'])
    
            self.ip = ''
            self.url = 'http://proxy.1again.cc:35050/api/v1/proxy/?type=2'
            self.ip_num = 0
    
    
        def process_request(self, request, spider):
            # if re.findall(r'根据需求的url过滤,必须使用selenium加载的js动态页面', request.url):
            print('获取ip............')    # 为selenium获取ip
            if self.ip_num == 0 or self.ip_num >= 3:
                res = json.loads(requests.get(url=self.url).content.decode())
                if res:
                    ip = res['data']['proxy']
                    self.ip = ip
                    self.ip_num = 1
    
    
            print('调用selenium中.............')
    
            self.chrome_options.add_argument("--proxy-server=http://{}".format(self.ip))    # 加载ip
            print('插入ip{},并使用{}'.format(self.ip,self.ip_num), '-' * 20)
            self.driver = webdriver.Chrome(chrome_options=self.chrome_options)
    
            self.driver.get(request.url)
            html = self.driver.page_source
            url = self.driver.current_url
    
            response =  HtmlResponse(url=url,body=html,encoding='utf-8',request=request)
            return response
    
        def close_spider(self,spider):
            self.driver.close()
            print('关闭selenium')

    ua也可以这样搞

     随手一写,有待优化




    ga改进版本,有待优化

    class YanzhenIp_selenium_DownloaderMiddleware(object):
    
        def __init__(self):
    
            self.chrome_options = Options()
            self.chrome_options.add_argument('--headless')
            self.chrome_options.add_argument('--disable-gpu')
            # self.driver = webdriver.Chrome(chrome_options=chrome_options)
            self.chrome_options.add_experimental_option('excludeSwitches', ['enable-automation'])
    
            self.ip = ''
            self.url = 'http://proxy.1again.cc:35050/api/v1/proxy/?type=2'
            self.ip_num = 0
    
    
        def process_request(self, request, spider):
            # if re.findall('js加载页面的url',request.url):
            if self.ip_num == 0 or self.ip_num >= 10:
                res = json.loads(requests.get(url=self.url).content.decode())
                if res:
                    ip = res['data']['proxy']
                    self.ip = ip
                    self.ip_num = 1
    
            if re.findall('js加载页面的url', request.url):
                
                # TODO if self.ip ?? 做个判断有咩有ip 没有的时候怎么办
                print('调用selenium中.............')
                
                self.chrome_options.add_argument("--proxy-server=http://{}".format(self.ip))
                print('插入ip{},并使用{}'.format(self.ip,self.ip_num), '-' * 20)
                self.driver = webdriver.Chrome(chrome_options=self.chrome_options)
        
                self.driver.get(request.url)
                html = self.driver.page_source
                url = self.driver.current_url
        
                response =  HtmlResponse(url=url,body=html,encoding='utf-8',request=request)
                return response
            
            
            
            else:       # 抓取简单的页面,scrapy可以胜任
                if self.ip:
                    request.meta['proxy'] = 'http://' + self.ip
                    self.ip_num += 1
                    print('ip地址>>>{} --- 使用次数{}'.format(self.ip, self.ip_num))
                else:
                    self.ip_num += 3
                    print('使用的是本机ip......')
    
    
    
    
        def close_spider(self,spider):
            self.driver.close()
            print('关闭selenium')
  • 相关阅读:
    CF1290E Cartesian Tree
    【LeetCode】11. 盛最多水的容器
    【LeetCode】10. 正则表达式匹配
    【LeetCode】9. 回文数
    【LeetCode】8. 字符串转换整数 (atoi)
    【LeetCode】7. 整数反转
    【LeetCode】6. Z 字形变换
    【LeetCode】5. 最长回文子串
    【LeetCode】4. 寻找两个正序数组的中位数[待补充]
    【LeetCode】3. 无重复字符的最长子串
  • 原文地址:https://www.cnblogs.com/zengxm/p/10995046.html
Copyright © 2011-2022 走看看