【问题标题】:how does scrapy-splash handle infinite scrolling?scrapy-splash 如何处理无限滚动?
【发布时间】:2016-10-30 02:56:35
【问题描述】:

我想对在网页中向下滚动生成的内容进行逆向工程。问题出在网址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 request shown in browser console

【问题讨论】:

    标签: scrapy scrapy-splash splash-js-render


    【解决方案1】:

    要滚动页面,您可以编写自定义渲染脚本(请参阅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
    

    要渲染此脚本,请使用“执行”端点而不是 render.html 端点:

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

    【讨论】:

    • 能否请您指导在哪里编写此脚本。我的意思是我很困惑如何在 python 文件中编写这个 javascript 函数
    • 如果此脚本到达末尾,然后一些 javascript 将新内容附加到页面,脚本是否会一次又一次地滚动,直到不再添加内容?
    【解决方案2】:

    感谢 Mikhail,我尝试了你的滚动脚本,它成功了,但我也注意到你的脚本滚动一次太多,一些 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
    

    【讨论】:

      【解决方案3】:

      我不认为硬编码设置滚动次数对于无限滚动页面是一个好主意,所以我将上述代码修改为:

      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
      

      【讨论】:

      • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-13
      相关资源
      最近更新 更多