Python 刮擦飞溅点击按钮不';行不通 我想做什么

Python 刮擦飞溅点击按钮不';行不通 我想做什么,python,scrapy,splash-js-render,Python,Scrapy,Splash Js Render,在avito.ru(俄罗斯房地产网站)上,这个人的手机会一直隐藏,直到你点击它。我想用Scrapy+Splash来收集手机 示例URL: 单击按钮后,将显示弹出窗口并显示手机 我正在将Splash API与以下Lua脚本一起使用: function main(splash) splash:go(splash.args.url) splash:wait(10) splash:runjs("document.getElementsByClassName('item-pho

在avito.ru(俄罗斯房地产网站)上,这个人的手机会一直隐藏,直到你点击它。我想用Scrapy+Splash来收集手机

示例URL:

单击按钮后,将显示弹出窗口并显示手机

我正在将Splash API与以下Lua脚本一起使用:

function main(splash)
    splash:go(splash.args.url)
    splash:wait(10)
    splash:runjs("document.getElementsByClassName('item-phone-button')[0].click()")
    splash:wait(10)
    return splash:png()
end
问题 未单击按钮,也未显示电话号码。这是一项微不足道的任务,我无法解释为什么它不起作用

如果我们将
item phone按钮
替换为
js show stat
,则单击可在同一页面上的另一个字段中正常工作。所以Javascript在一般情况下是有效的,而蓝色的“显示电话”按钮在某种程度上一定很特别

我试过的 为了解决这个问题,我创建了一个带有最少示例脚本的repo和一个用于Splash的docker compose文件:

Javascript代码是有效的,您可以使用Chrome和Firefox中的Javascript控制台进行验证

document.getElementsByClassName('item-phone-button')[0].click()
我在Splash版本3.0、3.1、3.2中试用过,结果是一样的

更新 我也试过:

  • @Lore的建议,包括
    simulateClick()
    方法(参见分支)

  • 此处描述的mouseDown/mouseUp事件:(参见分支)


我不知道您的实现是如何工作的,但我建议将
main
重命名为
parse
,这是爬行器在启动时调用的默认函数

如果这不是问题所在,那么首先要做的就是使用Javascript和css选择器控制是否选择了该类的正确元素。可能它存在另一个具有
item phone button
class属性的项目,而您单击的位置不正确

如果以上都是正确的,那么我建议两个对我有效的选项:

  • 使用and(我看到您已经使用了后者)。如果不起作用,请尝试双击,在代码中替换:

    local button = splash:select('item phone-button') 
    button:mouse_click()
    button:mouse_click()
    
  • 使用,执行javascript代码直到终止,然后重新启动LUA。您的代码也将变得更简单:

    function main(splash)
        splash:go(splash.args.url)
        splash:wait_for_resume("document.getElementsByClassName([[
                      function main(splash) {
                           document.getElementsByClassName('item-phone-button');[0].click()
                           splash.resume();
                      }               
        ]])
        return splash:png()
    end
    
    编辑:似乎最好使用
    dispatchEvent
    而不是
    click()
    如:


    以下脚本适合我:

    function main(splash, args)
      splash.private_mode_enabled = false
      assert(splash:go(args.url))
      btn = splash:select_all('.item-phone-button')[2]
      btn:mouse_click()
      btn.style.border = "5px solid black"
      assert(splash:wait(0.5))
      return {
        num = #splash:select_all('.item-phone-button'),
        html = splash:html(),
        png = splash:png(),
        har = splash:har(),
      }
    end
    
    原始解决方案存在两个问题:

  • “item phone button”类有两个元素,感兴趣的按钮是第二个。我已经通过设置
    btn.style.border=“5px纯黑”
    检查了匹配的元素
  • 此网站要求禁用私有模式,可能是因为它使用本地存储。检查其他常见的建议

  • 谢谢你的回答,这很有道理,我投赞成票。不幸的是,这些建议中没有一个对我有效。我怀疑Splash的Webkit版本与此特定站点之间存在兼容性问题。谢谢。看看这里FTR,splash:mouse_click比任何基于JS的click函数(通过MouseEvent等)都要好,因为它会向浏览器窗口发送一个真实的鼠标单击事件。实际上,只需将
    splash.private_mode_enabled=false
    添加到原始脚本即可。谢谢你,迈克!
    function main(splash, args)
      splash.private_mode_enabled = false
      assert(splash:go(args.url))
      btn = splash:select_all('.item-phone-button')[2]
      btn:mouse_click()
      btn.style.border = "5px solid black"
      assert(splash:wait(0.5))
      return {
        num = #splash:select_all('.item-phone-button'),
        html = splash:html(),
        png = splash:png(),
        har = splash:har(),
      }
    end