Python selenium 发送长文本卡顿问题

系统 1449 0

通过 Python \text{Python} Python 仿真一个 FireFox or Chrome \text{FireFox or Chrome} FireFox or Chrome 浏览器,然后通过 send_keys \text{send\_keys} send_keys 发送数据到 input \text{input} input 文本框,当数据字节数比较小时,完全不会发现任何异常,但是当发送长文本时,会出现卡顿或者阻塞的现象,导致数据的实时性下降了很多。

查看 send_keys \text{send\_keys} send_keys 源码:

            
              
                def
              
              
                send_keys
              
              
                (
              
              self
              
                ,
              
              
                *
              
              keys_to_send
              
                )
              
              
                :
              
              
                """
    Sends keys to current focused element.

    :Args:
     - keys_to_send: The keys to send.  Modifier keys constants can be found in the
       'Keys' class.
    """
              
              
    typing 
              
                =
              
               keys_to_typing
              
                (
              
              keys_to_send
              
                )
              
              
                if
              
               self
              
                .
              
              _driver
              
                .
              
              w3c
              
                :
              
              
                for
              
               key 
              
                in
              
               typing
              
                :
              
              
            self
              
                .
              
              key_down
              
                (
              
              key
              
                )
              
              
            self
              
                .
              
              key_up
              
                (
              
              key
              
                )
              
              
                else
              
              
                :
              
              
        self
              
                .
              
              _actions
              
                .
              
              append
              
                (
              
              
                lambda
              
              
                :
              
               self
              
                .
              
              _driver
              
                .
              
              execute
              
                (
              
              
            Command
              
                .
              
              SEND_KEYS_TO_ACTIVE_ELEMENT
              
                ,
              
              
                {
              
              
                'value'
              
              
                :
              
               typing
              
                }
              
              
                )
              
              
                )
              
              
                return
              
               self
    

              
                def
              
              
                keys_to_typing
              
              
                (
              
              value
              
                )
              
              
                :
              
              
                """Processes the values that will be typed in the element."""
              
              
    typing 
              
                =
              
              
                [
              
              
                ]
              
              
                for
              
               val 
              
                in
              
               value
              
                :
              
              
                if
              
              
                isinstance
              
              
                (
              
              val
              
                ,
              
               Keys
              
                )
              
              
                :
              
              
            typing
              
                .
              
              append
              
                (
              
              val
              
                )
              
              
                elif
              
              
                isinstance
              
              
                (
              
              val
              
                ,
              
              
                int
              
              
                )
              
              
                :
              
              
            val 
              
                =
              
              
                str
              
              
                (
              
              val
              
                )
              
              
                for
              
               i 
              
                in
              
              
                range
              
              
                (
              
              
                len
              
              
                (
              
              val
              
                )
              
              
                )
              
              
                :
              
              
                typing
              
                .
              
              append
              
                (
              
              val
              
                [
              
              i
              
                ]
              
              
                )
              
              
                else
              
              
                :
              
              
                for
              
               i 
              
                in
              
              
                range
              
              
                (
              
              
                len
              
              
                (
              
              val
              
                )
              
              
                )
              
              
                :
              
              
                typing
              
                .
              
              append
              
                (
              
              val
              
                [
              
              i
              
                ]
              
              
                )
              
              
                return
              
               typing

            
          

可以发现 keys_to_typing \text{keys\_to\_typing} keys_to_typing 函数将 value \text{value} value 逐个拆分成字符放到列表中,然后再做其他处理,并不是特别理解他为什么要这样去做(没有进一步去探索原因),但是可以肯定的是,当数据量大的时候,这会大大的提高 send_keys \text{send\_keys} send_keys 的时间,继而造成卡顿的状况。

解决方案是内嵌 js \text{js} js 进行赋值:

            
              js 
              
                =
              
              
                "element = document.getElementById('text');"
              
               \
	 
              
                "element.value = 'xxx';"
              
              
driver
              
                .
              
              execute_script
              
                (
              
              js
              
                )
              
            
          

这样便可以避免拆分字符所造成的卡顿问题,但是同样带来了一个新的问题——无法使用 selenimu.webdriver.common.keys \text{selenimu.webdriver.common.keys} selenimu.webdriver.common.keys 来触发事件。因为如上发送文本后并不会触发任何事件(例如 change \text{change} change 事件),而我们往往会用到这些事件来结束一次输入刷新数据,所以需要找到对应的触发方案。

解决这个问题的方法是使用 fireEvents or dispatchEvent \text{fireEvents or dispatchEvent} fireEvents or dispatchEvent ,前者是在较老或者低级的浏览器中可以使用,后者在 FireFox or Chrome \text{FireFox or Chrome} FireFox or Chrome 中使用。由于我使用的是 FireFox \text{FireFox} FireFox ,所以如下:

            
              js 
              
                =
              
              
                "element = document.getElementById('text');"
              
               \
	 
              
                "element.value = 'xxx';"
              
               \
	 
              
                "event = document.createEvent('HTMLEvents');"
              
               \
	 
              
                "event.initEvent('change', true, true);"
              
               \
	 
              
                "element.dispatchEvent(event);"
              
              
driver
              
                .
              
              execute_script
              
                (
              
              js
              
                )
              
            
          

完美解决发送长文本卡顿的问题,不过如果需要发送很多次数据的时候,上述 js \text{js} js 代码中有些部分没必要执行多次,但是由于是内嵌在 Python \text{Python} Python 中,所以么得法子……或者说,我不知道怎么优化,没有学过 js \text{js} js 也是第一次尝试嵌到 Python \text{Python} Python 中。

另外,有网友称也可以通过将数据复制到粘贴板然后直接粘贴到输入框,未测试。


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论