Как scrapy-splash справляется с бесконечной прокруткой?

Я хочу сделать обратный инжиниринг содержимого, созданного прокруткой вниз на веб-странице. Проблема в URL https://www.crowdfunder.com/user/following_page/80159?user_id=80159&limit=0&per_page=20&screwrand=933, screwrand не похоже на какой-либо шаблон, поэтому обратные URL-адреса не работают. Я рассматриваю автоматический рендеринг с использованием Splash. Как использовать Splash для прокрутки, как в браузерах? Большое спасибо! Вот коды для двух запросов:

request1 = scrapy_splash.SplashRequest('https://www.crowdfunder.com/user/following/{}'.format(user_id),
                                                        self.parse_follow_relationship,
                                                        args={'wait':2},
                                                        meta={'user_id':user_id, 'action':'following'},
                                                        endpoint='http://192.168.99.100:8050/render.html')
yield request1

request2 = scrapy_splash.SplashRequest('https://www.crowdfunder.com/user/following_user/80159?user_id=80159&limit=0&per_page=20&screwrand=76',
                                                    self.parse_tmp,
                                                    meta={'user_id':user_id, 'action':'following'},
                                                    endpoint='http://192.168.99.100:8050/render.html')
yield request2

запрос AJAX отображается в консоли браузера

3 ответа

Для прокрутки страницы вы можете написать собственный скрипт рендеринга (см. http://splash.readthedocs.io/en/stable/scripting-tutorial.html), что-то вроде этого:

function main(splash)
    local num_scrolls = 10
    local scroll_delay = 1.0

    local scroll_to = splash:jsfunc("window.scrollTo")
    local get_body_height = splash:jsfunc(
        "function() {return document.body.scrollHeight;}"
    )
    assert(splash:go(splash.args.url))
    splash:wait(splash.args.wait)

    for _ = 1, num_scrolls do
        scroll_to(0, get_body_height())
        splash:wait(scroll_delay)
    end        
    return splash:html()
end

Чтобы отобразить этот скрипт, используйте конечную точку execute для конечной точки render.html:

script = """<Lua script> """
scrapy_splash.SplashRequest(url, self.parse,
                            endpoint='execute', 
                            args={'wait':2, 'lua_source': script}, ...)

Спасибо Михаил, я попробовал ваш скрипт прокрутки, и он сработал, но я также заметил, что ваш скрипт прокручивает слишком много раз, некоторые js не имеют слишком много времени для рендеринга и пропускаются, поэтому я делаю небольшое изменение следующим образом:

function main(splash)
        local num_scrolls = 10
        local scroll_delay = 1

        local scroll_to = splash:jsfunc("window.scrollTo")
        local get_body_height = splash:jsfunc(
            "function() {return document.body.scrollHeight;}"
        )
        assert(splash:go(splash.args.url))
        splash:wait(splash.args.wait)

        for _ = 1, num_scrolls do
            local height = get_body_height()
            for i = 1, 10 do
                scroll_to(0, height * i/10)
                splash:wait(scroll_delay/10)
            end
        end        
        return splash:html()
end

Я не думаю, что жестко запрограммированное количество прокруток является хорошей идеей для страниц с бесконечной прокруткой, поэтому я изменил вышеупомянутый код следующим образом:

      function main(splash, args)
    
    current_scroll = 0  
  
    scroll_to = splash:jsfunc("window.scrollTo")
    get_body_height = splash:jsfunc(
        "function() {return document.body.scrollHeight;}"
    )
    assert(splash:go(splash.args.url))
    splash:wait(3)
  
    height = get_body_height()

    while current_scroll < height do
        scroll_to(0, get_body_height())
        splash:wait(5)
            current_scroll = height
            height = get_body_height()
    end 
    splash:set_viewport_full()
    return splash:html()
end
Другие вопросы по тегам