我正在尝试使用Python Pyppeteer获得XHR。这是我的代码。
import asyncio
from pyppeteer import launch
import json
async def intercept_response(res):
resourceType = res.request.resourceType
if resourceType in ['xhr']:
resp = await res.text()
try:
r = json.loads(resp)
print(res.request.url)
except:
pass
return res.request.url
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')
await page.waitForSelector('li.item goWork')
await browser.close()
if __name__ == '__main__':
url = asyncio.run(main())
print('IS THIE WAHT YOU WANT:', url)
但是当我运行它时,浏览器永远不会关闭,并且在30秒之后,它给了我一个TimeoutError。代码应该返回xhr响应的url,但不是。
您遇到此问题的原因是,此版本的pyppeteer
使用的事件发射器不支持async
事件订阅者。正在开发中的库的下一个版本(在撰写本文时)将允许这样做。
def intercept_response(res):
async def intercept_response(res):
resourceType = res.request.resourceType
if resourceType in ['xhr']:
resp = await res.text()
try:
r = json.loads(resp)
print(res.request.url)
except:
pass
return res.request.url
asyncio.get_event_loop().run_until_complete(intercept_response(res))
第二,您的代码并非全部用于“返回xhr响应的网址”。您的函数main
隐式返回None
。仅仅因为您指定了事件处理程序并不意味着该参数的返回值是从您最初附加该处理程序的函数中神奇地返回的。尽管如此,这是完成我认为您要尝试执行的操作的一种方法:
async def main():
browser = await launch(headless=False)
page = await browser.newPage()
resp_fut, interceptor = make_interceptor()
page.on('response', interceptor)
await page.goto('https://www.iesdouyin.com/share/user/70015326114')
await page.waitForSelector('li.item goWork')
resp = await resp_fut
await browser.close()
return resp
不过,这种解决方案不是最好的,如果未设置将来的结果,它将无限期地挂起。您可能需要查看asyncio.wait_for
,或者更好,只需使用内置的asyncio.wait_for
方法(;