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