Другим решением будет реализация обработчика загрузки или промежуточного программного обеспечения обработчика загрузки. (см. scrapy docs для получения дополнительной информации о промежуточном программном обеспечении загрузчика) Ниже приведен пример класса, использующего селен с веб-драйвером phantomjs без головы:
1) Определение класса в скрипте middlewares.py
.
from selenium import webdriver
from scrapy.http import HtmlResponse
class JsDownload(object):
@check_spider_middleware
def process_request(self, request, spider):
driver = webdriver.PhantomJS(executable_path='D:\phantomjs.exe')
driver.get(request.url)
return HtmlResponse(request.url, encoding='utf-8', body=driver.page_source.encode('utf-8'))
2) Добавить JsDownload()
класс к переменной DOWNLOADER_MIDDLEWARE
в settings.py
:
DOWNLOADER_MIDDLEWARES = {'MyProj.middleware.MiddleWareModule.MiddleWareClass': 500}
3) Интеграция HTMLResponse
в your_spider.py
. Расшифровка тела ответа даст вам желаемый результат.
class Spider(CrawlSpider):
# define unique name of spider
name = "spider"
start_urls = ["https://www.url.de"]
def parse(self, response):
# initialize items
item = CrawlerItem()
# store data as items
item["js_enabled"] = response.body.decode("utf-8")
Дополнительный аддон:
Мне нужна была возможность сообщать различным паукам, какое промежуточное программное обеспечение использовать, поэтому я реализовал эту оболочку:
def check_spider_middleware(method):
@functools.wraps(method)
def wrapper(self, request, spider):
msg = '%%s %s middleware step' % (self.__class__.__name__,)
if self.__class__ in spider.middleware:
spider.log(msg % 'executing', level=log.DEBUG)
return method(self, request, spider)
else:
spider.log(msg % 'skipping', level=log.DEBUG)
return None
return wrapper
для работы оболочки все пауки должны иметь как минимум:
middleware = set([])
для включения промежуточного программного обеспечения:
middleware = set([MyProj.middleware.ModuleName.ClassName])
Преимущество:
Основным преимуществом реализации этого способа, а не пауком, является то, что вы в конечном итоге делаете только один запрос. Например, в решении A T: обработчик загрузки обрабатывает запрос, а затем передает ответ пауку. Затем паук делает новый запрос в функции parse_page - это два запроса на один и тот же контент.