【日常】爬虫技巧进阶:textarea的value修改与提交问题(以智谱清言为例)

序言

记录一个近期困扰了一些时间的问题。

我很喜欢在爬虫中遇到问题,因为这意味着在这个看似简单的事情里还是有很多值得去探索的新东西。其实本身爬虫也是随着前后端技术的不断更新在进步的。


文章目录

  • 序言
  • Preliminary
  • 1 问题缘起
    • 1.1 Selenium长文本输入阻塞
    • 1.2 ChromeDriver无法输入非BMP字符(如Emoji字符)
  • 2 Javascript修改textarea文本内容不生效
  • 3 笨方法
  • 4 正解
  • 附录:智谱清言(ChatGLM)Selenium测试脚本
  • 后记


Preliminary

本文假定你已经拥有基于ChromeDriver的Selenium脚本开发经验以及基础的前端知识。

1 问题缘起

1.1 Selenium长文本输入阻塞

长文本输入阻塞的问题是Selenium老大难问题,其原因是Selenium的send_keys()函数在输入字符串时,会将字符串分解为每个字符进行处理,具体可见源码(keys_to_typing函数for循环里最后一个else分支):

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

这显然是挺笨重的操作,因为我们正常将长文本复制到中,因此将send_keys(...)中的换行符\n替换成
即可避免。

题外话,源码为什么要这样写一定会有它的道理。仔细想想也不难理解,keys_to_typing函数的参数value并不总是字符串,也可能是键盘的某个键位,比如常用的我们通过send_keys(Key.CONTROL, 'v')实现向输入框中粘贴文本,因此需要分解成各个字符处理。


图1 智谱清言官网
【日常】爬虫技巧进阶:textarea的value修改与提交问题(以智谱清言为例)_第1张图片


本文以智谱清言(ChatGLM)官网的