scrapy中间件中使用selenium切换ip
Posted zengxm
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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‘)
以上是关于scrapy中间件中使用selenium切换ip的主要内容,如果未能解决你的问题,请参考以下文章