Python asyncio 问题

2020-05-10 22:11:49 +08:00
 fangwenxue
    def crawl(self, tasks: list, task_handler=None, callback=None, semaphore_count=100):
        if not task_handler:
            task_handler = self.page_handler

        main_loop = asyncio.new_event_loop()
        asyncio.set_event_loop(main_loop)
        semaphore = asyncio.Semaphore(semaphore_count)
        n = len(tasks)

        asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())

        new_tasks = []

        async def _run():
            async with semaphore:
                async with ClientSession() as session:
                    for i, task in enumerate(tasks):
                        future = asyncio.ensure_future(task_handler(task, i=i + 1, n=n, session=session))
                        if callback:
                            future.add_done_callback(callback)
                        new_tasks.append(future)
                    return await asyncio.gather(*new_tasks)

        try:
            result = main_loop.run_until_complete(_run())
            return [x for j in result for x in j]
        except Exception as e:
            logging.exception(e)
        finally:
            if not main_loop.is_closed():
                main_loop.close()
            return []
            
    async def page_handler(self, task, session, **kwargs):
       	''' 省略部分代码 '''
        result = self.crawl(book_item_url_list, self.item_handler)
        return result

855 次点击
所在节点    问与答
1 条回复
sikong31
2020-05-11 11:11:52 +08:00
1 唯一的 ClientSession,就自己定义一个 AppSession 类,返回一个类属性就是了
2 再调用就相当于阻塞了,你可以参考下 asyncio 动态添加任务
4 如果不是等最后一起处理,列表是没办法顺序返回的,因为哪个请求先返回并不是你这边控制的,只有结果全部返回了才是顺序的

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/670346

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX