python - Scrapy下载中间件返回response对象时不执行del操作
问题描述
我正在编写一个将 Scrapy 连接到 Selenium 的下载中间件:
# spider.py
import scrapy
class TestSpider(scrapy.Spider):
name = 'test'
# allowed_domains = ['xxx.com']
start_urls = ['http://httpbin.org/']
def parse(self, response):
print(response)
# Middleware.py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
from scrapy.http import HtmlResponse
class SeleniumMiddleware:
"""Docking Selenium"""
def __init__(self):
self.browser = webdriver.Chrome()
self.browser.maximize_window()
self.wait = WebDriverWait(self.browser, 10)
@classmethod
def from_crawler(cls, crawler):
return cls()
def process_request(self, request, spider):
try:
# Determine which links need to be accessed using the selenium program
if request.url in spider.start_urls:
self.browser.get(request.url)
# wait data load
self.wait.until(EC.presence_of_element_located((
By.ID, 'operations-tag-HTTP_Methods')))
page_text = self.browser.page_source # get data
# return Response
print('1')
return HtmlResponse(url=request.url, body=page_text, encoding='utf-8', request=request, status=200)
except TimeoutException:
# Timeout
print('2')
return HtmlResponse(url=request.url, status=500, request=request)
def process_exception(self, request, exception, spider):
print(f'Error: {exception}')
return None
def __del__(self):
print('Browser close~')
self.browser.quit()
在测试程序的时候,发现在返回响应对象时,程序没有进行del操作,导致打开的浏览器无法按预期关闭。
输出结果:
1
<200 http://httpbin.org/>
可以看出程序运行的时候没有触发异常,但是程序并没有使用del删除这个中间件。
当我注释返回响应对象的代码时,程序会执行del操作:
# return Response
print('1')
# return HtmlResponse(url=request.url, body=page_text, encoding='utf-8', request=request, status=200)
输出结果:
1
<200 http://httpbin.org/>
Browser close~
我想知道是什么导致了这个结果,返回响应对象时应该如何进行整理操作(关闭浏览器)?
希望你能帮助我,谢谢。
已经解决,请spider_closed
在创建中间件时使用方法并连接信号:
--skip--
@classmethod
def from_crawler(cls, crawler):
o = cls()
crawler.signals.connect(o.spider_closed, signals.spider_closed)
return o
--skip--
def spider_closed(self):
"""Close the browser"""
self.browser.quit()
解决方案
推荐阅读
- javascript - 如何通过 HTML 显示 javascript 函数的输出
- reactjs - 为样式化组件创建通用道具
- mysql - Galera Cluster 从 MySQL 集群复制数据
- ios - 如何使用中间模型格式化核心数据多对多谓词
- sql - 如何在 CTE 中限制 STUFF 函数以在重复单词之前删除字符
- unity3d - 如何在 Blazor 的 Unity 中打开为 WebGL 编译的游戏?
- r - R:基于不是一列而是两列的值的颜色标记
- java - 防止通知被自动隐藏
- python - 如果在 Django 模板中出现条件,如何使用 Django 模板?
- c - 为什么我得到 s=-1807786450?