aiohttp ClientSession.get()方法静默失败-Python3.7

时间:2019-02-07 00:45:39

标签: python asynchronous exception-handling python-asyncio aiohttp

我正在制作一个小型应用程序,试图通过Bing搜索公司网站URL的名称。它采用了一大堆公司名称,使用Bing Search API获取第一个URL,然后将这些URL保存回列表中。

我对aiohttp的{​​{1}}方法有疑问,具体地说,它无声地失败了,我不知道为什么。

这是我初始化脚本的方式。注意ClientSession.get()

worker.perform_mission()

async def _execute(workers,*, loop=None): if not loop: loop = asyncio.get_event_loop() [asyncio.ensure_future(i.perform_mission(verbose=True), loop=loop) for i in workers] def main(): filepth = 'c:\\SOME\\FILE\\PATH.xlsx' cache = pd.read_excel(filepth) # CHANGE THE NUMBER IN range(<here>) TO ADD MORE WORKERS. workers = (Worker(cache) for i in range(1)) loop = asyncio.get_event_loop() loop.run_until_complete(_execute(workers, loop=loop)) ...<MORE STUFF>... 方法执行以下操作(滚动到底部并查看worker.perform_mission()):

_split_up_request_like_they_do_in_the_docs()

最后我的输出是:

class Worker(object):
    def __init__(self, shared_cache):
        ...<MORE STUFF>...

    async def perform_mission(self, verbose=False):
        while not self.mission_complete:
            if not self.company_name:
                await self.find_company_name()
                if verbose:
                    print('Obtained Company Name')
            if self.company_name and not self.website:
                print('Company Name populated but no website found yet.')
                data = await self.call_bing() #<<<<< THIS IS SILENTLY FAILING.
                if self.website and ok_to_set_website(self.shared_cache, self):
                    await self.try_set_results(data)
                    self.mission_complete = True
                else:
                    print('{} worker failed at setting website.'.format(self.company_name))
                    pass
            else:
                print('{} worker failed at obtaining data from Bing.'.format(self.company_name))
                pass

    async def call_bing(self):
        async with aiohttp.ClientSession() as sesh:
            sesh.headers = self.headers
            sesh.params = self.params
            return await self._split_up_request_like_they_do_in_the_docs(sesh)

    async def _split_up_request_like_they_do_in_the_docs(self, session):
        print('_bing_request() successfully called.') #<<<THIS CATCHES
        async with session.get(self.search_url) as resp:
            print('Session.get() successfully called.') #<<<THIS DOES NOT.
            return await resp.json()

有人可以帮我弄清楚为什么Obtained Company Name Company Name populated but no website found yet. _bing_request() successfully called. Process finished with exit code 0 没有触发吗?...或者可以帮助我更好地问这个问题吗?

1 个答案:

答案 0 :(得分:2)

看看这部分:

async def _execute(workers,*, loop=None):
    # ...
    [asyncio.ensure_future(i.perform_mission(verbose=True), loop=loop) for i in workers]

您创建了一堆任务,但是您不等待这些任务完成。这意味着_execute本身将在创建任务之后立即完成,远远早于这些任务完成。而且由于您运行事件循环直到_execute完成,所以事件循环将在启动后不久停止。

要解决此问题,请使用asyncio.gather等待多个可等待对象完成:

async def _execute(workers,*, loop=None):
    # ...
    tasks = [asyncio.ensure_future(i.perform_mission(verbose=True), loop=loop) for i in workers]
    await asyncio.gather(*tasks)