Scrapy与Selenium注意事项笔记
Selenium
参数部分
- 通常情况下涉及到
selenium
的项目都推荐添加以下模板。from selenium import webdriver from selenium.webdriver.chrome.options import Options chrome_options = Options() # 不加载图片 prefs = {"profile.managed_default_content_settings.images":2} chrome_options.add_experimental_option("prefs",prefs) # 无头模式 关闭gpu chrome_options.add_argument("--headless") chrome_options.add_argument("--disable-gpu") # 针对Linux环境下的chrome driver参数 chrome_options.add_argument('--no-sandbox') chrome_options.add_argument('--disable-dev-shm-usage') # 设置ua chrome_options.add_argument('User-Agent="Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36"')
加载时间过长解决办法
- 手动停止加载
spider.browser.get(request.url) time.sleep(2) spider.browser.execute_script("window.stop();")
- 不要使用这个,无论如何这个将导致driver挂掉。:
from selenium.common.exceptions import TimeoutException try: browser.get(addr) except TimeoutException as e: print("加载页面太慢,停止加载,继续下一步操作") browser.execute_script('window.stop()')
与scrapy整合使用模板
- 在
spider
的__init__
中声明def __init__(self): self.browser = webdriver.Chrome(self.WEBDRIVER_PATH,chrome_options=chrome_options) self.browser.implicitly_wait(5) super().__init__()
- 在中间件中拦截
class SeleniumInterceptMiddleware(object): #通过chrome请求动态网页 def process_request(self, request, spider): #这里的XXXX即为我们的爬虫名,对不同的爬虫进行动态的修改 spider.browser.get(request.url) time.sleep(2) spider.browser.execute_script("window.stop();") print('访问:{}'.format(request.url)) #这里直接retrun HtmlResponse的原因是我们已经通过模拟浏览器的方式访问过一遍网站了 不需要再次进入downloader下载一次所以直接return就好了 return HtmlResponse(url=spider.browser.current_url,body=spider.browser.page_source,encoding='utf-8')
Scrapy使用注意事项
中间件使用
- 如果一个中间件执行完
process_request
后想交给下一个中间件继续执行process_request
那么这个这个这个中间件要返回None
def process_request(self, request, spider): # Called for each request that goes through the downloader # middleware. # 每个交给下载器的request对象都会经过该方法,并期望返回response # Must either: # 如果该方法返回的是None,则继续执行其他下载中间件的process_request方法送往下载器,直到合适的下载器函数被调用,该request被执行,返回response # - return None: continue processing this request # 如果该方法返回的是response,则终止当前流程,也终止继续调用其他process_request方法,将该response通过引擎返回给爬虫 # - or return a Response object # 如果该方法返回的是request,则终止当前流程,也终止继续调用其他process_request方法,将request返回给调度器,大多数情况是更换新的request请求 # - or return a Request object # 抛出IgnoreRequest异常, 该异常就会交个process_exception方法进行处理; 如果没有任何一个方法处理该异常 # 那么该请求就直接被忽略了, 也不会记录错误日志. # - or raise IgnoreRequest: process_exception() methods of # installed downloader middleware will be called return None ———————————————— 版权声明:本文为CSDN博主「今夜睡火星」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/Hepburn_li/java/article/details/81478885
Pipline 使用
- 有个Pipline执行完
process_item
想传给下一个Pipline继续执行。则要返回item
class BilibiliPipeline(object): def process_item(self, item, spider): return item
Reference
- https://blog.csdn.net/Hepburn_li/java/article/details/81478885