Почему LUA не может получить этот элемент html в моем файле python, когда рассматриваемый код js отлично работает в chrome разработчику? - PullRequest
1 голос
/ 24 апреля 2020

Я пытаюсь сканировать веб-страницу с помощью ScrapyRT, используя Spla sh для выполнения кнопки JavaScript, которая ведет к следующей странице.

Вот тестовая страница, которую я пытаюсь сканировать: https://www.walgreens.com/search/results.jsp?Ntt=toilet%20paper

Он может выполнить начальный штраф за сканирование до того, как LUA введен в уравнение, хотя иногда кажется, что он срабатывает на бит LUA перед запуском первого часть - я предполагаю, что я просто не могу ждать достаточно долго.

Вот ошибка, которую я получаю в Docker:

"error": {"error": 400, "type": "ScriptError", "description": "Error happened while executing LUA script", "info": {"source": "[string \"function main(splash, args)...\"]", 
"line_number": 7, "error": "JS error: \"TypeError: null is not an object (evaluating 'document.getElementById('#omni-next-click').click')\"", "type": "LUA_ERROR", "message": "Lua error: [string \"function main(splash, args)...\"]:7: JS error: \"TypeError: null is not an object (evaluating 'document.getElementById('#omni-next-click').click')\""}}}

Похоже, это говорит мне document.getElementById ('# omni-next-click') имеет значение null, но я запустил его в Chrome Developer, и он отлично работал, чтобы перенести меня на следующую страницу. Я на 99% уверен, что URL передается в сценарий LUA, потому что я возвратил его в выходной файл функции разбора перед передачей его LUA, просто чтобы убедиться.

На странице Spla sh в браузере он не выдает никаких ошибок, хотя возвращает только HTML исходного URL, поэтому я подозреваю, что это связано.

Мой код:

import scrapy
import scrapyrt
import json
import ScrapyProject
from scrapy_splash import SplashRequest

SCRAPY_SETTINGS_MODULE = ScrapyProject.settings

script = '''function main(splash, args)
  assert(splash:go(splash.args.url))
  splash:wait(5)
  assert(splash:runjs("document.getElementById('#omni-next-click').click()"))
  splash:wait(5)
  return {html = splash:html()}
end
'''

class WalgreensSpider(scrapy.Spider):
    name = 'Walgreens'

    def modify_realtime_request(self, request):
        return SplashRequest(request.url, self.parse,
                endpoint='render.html',
                args={'wait': 0.5}
            )

    def parse(self, response):
        JSON_SELECTOR = '/html/body/script[last()-2]/text()'
        if response.xpath(JSON_SELECTOR).extract_first():
            (unrelated code...)
                yield{
                    'name': itemName
                }
        NEXT_PAGE_SELECTOR = '#omni-next-click'
        next_page_btn = response.css(NEXT_PAGE_SELECTOR).extract_first()
        if next_page_btn:
            yield SplashRequest(response.request.url, self.parse,
                endpoint='execute',
                args={'lua_source': script})
...