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')

 

posted @ 2019-06-09 21:55  花名k  阅读(1265)  评论(0编辑  收藏  举报