如何从python调用selenium execute_async_脚本中的回调函数

如何从python调用selenium execute_async_脚本中的回调函数,python,selenium,scrapy,Python,Selenium,Scrapy,我正在抓取一个网站,网页中有音频播放,我想知道音频何时会结束播放,所以我将事件侦听器添加到音频webElement中,以监视要触发的“oneded”事件,我想从driver.execute\u async\u脚本中的callback()函数中得到注意 但我总是犯错误 TypeError:不可序列化JSON。 我的问题是: 1.参数[arguments.length-1]是否指self.audio\u play\u end 2.为什么错误输出与“MissionContentItemHelper.a

我正在抓取一个网站,网页中有音频播放,我想知道音频何时会结束播放,所以我将事件侦听器添加到音频webElement中,以监视要触发的“oneded”事件,我想从driver.execute\u async\u脚本中的callback()函数中得到注意

但我总是犯错误

TypeError:不可序列化JSON。

我的问题是:

1.参数[arguments.length-1]是否指self.audio\u play\u end

2.为什么错误输出与“MissionContentItemHelper.audio_play_end不可JSON序列化”有关?我看不到MissionContentItemHelper.audio\u play\u end和JSON之间的任何线索

3.调用audio\u play\u end的方式正确吗

class MissionContentItemHelper: 
    def sleep(self):
        audio = self.browser.find_element_by_css_selector('#audio')
        self.browser.execute_async_script("""
            var audio = arguments[0];
            callback = arguments[arguments.length - 1];
            audio.addEventListener("ended", function(_event) {
                callback();
            }
        """, audio, self.audio_play_end)

    @staticmethod
    def audio_play_end():
        print('the audio finished playing...')

execute\u async\u script
的名字让很多人感到困惑。它不会从测试代码异步执行脚本,它只允许您执行从浏览器主线程异步运行的脚本,如AJAX调用和JavaScript
setTimeout

这些JavaScript函数和类似的函数本身几乎立即返回,但它们使用异步操作完成时执行的(JavaScript)函数参数。
execute\u async\u script
的作用与
execute\u script
完全相同,但它不是在函数本身返回时返回(几乎立即返回),而是提供自己的回调JavaScript函数(它将其作为最后一个参数传递,这就是为什么需要
参数[arguments.length-1]
),可以在传递到
execute\u async\u script
的JavaScript代码中使用,以将其作为回调传递给异步函数
execute\u async\u script
仅在调用此回调时返回,而不是立即返回

例如,在以下代码中,对
execute\u async\u script
的调用的行为类似于2秒的延迟:

browser.执行异步脚本(“setTimeout(参数[0],2000)”)

请注意,因为我没有向脚本传递任何附加参数,所以
arguments[0]
实际上是最后一个参数

在您的情况下,您不必传递
self.audio\u play\u end
,但必须在JavaScript代码段内调用
audio.play()
,才能启动音频<代码>执行异步脚本应仅在音频播放完成后返回