【问题标题】:python async def how to return valuepython async def如何返回值
【发布时间】:2020-09-03 00:09:03
【问题描述】:

我正在尝试从 Python Async 返回 XHR url 列表。下面是我的代码。

import asyncio
from pyppeteer import launch

async def intercept_response(res):
    resourceType = res.request.resourceType
    xhr_list = []
    if resourceType in ['xhr']:
        print(res.request.url)
        xhr_list.append(res.request.url)
    return xhr_list

async def main():
    browser = await launch(headless=False)
    page = await browser.newPage()
    page.on('response', intercept_response)
    await page.setUserAgent('Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1')
    await page.goto('https://www.iesdouyin.com/share/user/70015326114', waitUntil = 'networkidle2')
    await browser.close()

if __name__ == '__main__':
    url = asyncio.run(main())
    print(url)

但是,当我运行代码时,res.request.url 被打印出来,但 xhr_list 没有返回,导致 url 为 None。我的代码有问题吗?

【问题讨论】:

  • url 将被分配您从main 返回的任何值。由于您没有从中返回任何内容,因此 url 设置为 None。

标签: python async-await return python-asyncio pyppeteer


【解决方案1】:

您的代码有两个问题。首先,intercept_response 尝试构建一个列表,但该列表始终是新创建的,并且始终最多包含一个元素。由于intercept_response 被多次调用,它应该附加到相同的列表中。

另外,您需要确保intercept_response 的返回值传播到main,并从那里实际返回。例如,您可以使用一个闭包(一个内部 def),它分配给在外部范围中定义的变量:

async def main():
    browser = await launch(headless=False)
    page = await browser.newPage()
    url = []
    async def intercept_response(res):
        if res.request.resourceType == 'xhr':
            print(res.request.url)
            url.append(res.request.url)
    page.on('response', intercept_response)
    await page.setUserAgent('Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1')
    await page.goto('https://www.iesdouyin.com/share/user/70015326114', waitUntil = 'networkidle2')
    await browser.close()
    return url

【讨论】:

  • 这段代码部分解决了我的问题。但是这个问题仍然存在:打印了三个 XHR url,但只有一个附加到 xhr_list。因此返回的 url 只有 1 个元素。我怀疑这与 Asynico await 方法有关?
  • 这是因为我应该使用 Gather 来获取返回值吗? @user4815162342
  • @jackliu 您的问题与 asyncio 无关,您的 intercept_response 总是会创建一个新列表。当多次调用时,它返回三个不同的列表,最后一个被使用。我现在已经编辑了代码,以便 intercept_response 的不同调用附加到同一个列表中。
  • @jackliu 没问题。如果问题现在已经解决,请记得accept回答。
猜你喜欢
  • 1970-01-01
  • 2017-11-04
  • 2023-01-17
  • 2021-01-12
  • 2019-03-01
  • 2017-03-27
  • 2021-09-07
  • 1970-01-01
相关资源
最近更新 更多