RuntimeWarning:从未等待协程 'NewsExtraction.get_article_data_elements'

RuntimeWarning: coroutine 'NewsExtraction.get_article_data_elements' was never awaited

我一直拒绝在我的代码中使用 asyncio,但使用它可能有助于解决我遇到的一些性能问题。

这是我的场景:

90% 的时间此流程是完美的,但有时 NewsExtraction Class 中的 12 个函数之一无法提取 HTML 提供的数据。看来我的代码是“踩到自己”,导致数据元素无法解析。当我重新运行代码时,所有元素都被正确解析。

NewsExtraction Class 有这个函数 get_article_data_elements,它是从 Extraction Class.

中调用的

函数 get_article_data_elements 调用这些项目:

published_date = self._extract_article_published_date()
modified_date = self._extract_article_modified_date()
title = self._extract_article_title()
description = self._extract_article_description()
keywords = self._extract_article_key_words()
tags = self._extract_article_tags()
authors = self._extract_article_author()
top_image = self._extract_top_image()
language = self._extract_article_language()
categories = self._extract_article_category()
text = self._extract_textual_content()
url = self._extract_article_url()

这些数据元素中的每一个都用于填充一个 Python 字典,最终传递回最终用户。

我一直在尝试将 asyncio 代码添加到 NewsExtraction Class,但我一直收到此错误消息:

RuntimeWarning: coroutine 'NewsExtraction.get_article_data_elements' was never awaited

过去 3 天我一直在努力解决这个问题。我在 Stack Overflow 上看了几十个关于这个错误的问题 RuntimeWarning: coroutine never awaited。我也看过许多关于使用 asyncio 的文章,但我不知道如何将 asyncio 与我的 NewsExtraction Class 一起使用,它是从 Extraction Class.

有人可以提供一些建议来解决我的问题吗?

class NewsExtraction(object):
    """
    This class is used to extract common data elements from a news article
    on xyz
    """

    def __init__(self, url, soup):
        self._url = url
        self._raw_soup = soup


    truncated...


    async def _extract_article_published_date(self):
      """
      This function is designed to extract the publish date for the article being parsed.

      :return: date article was originally published
      :rtype: string
      """
      json_date_published = JSONExtraction(self._url, self._raw_soup).extract_article_published_date()
      if json_date_published is not None:
         if len(json_date_published) != 0:
            return json_date_published
         else:
             return None
      elif json_date_published is None:
           if self._raw_soup.find(name='div', attrs={'class': regex.compile("--publishDate")}):
              date_published = self._raw_soup.find(name='div', attrs={'class': regex.compile("--publishDate")})
              if len(date_published) != 0:
                 return date_published.text
              else:
                logger.info('The HTML tag to extract the publish date for the following article was not found.')
                logger.info(f'Article URL -- {self._url}')
                return None


    truncated...


    async def get_article_data_elements(self):
      """
      This function is designed to extract all the common data elements from a
      news article on xyz.

      :return: dictionary of data elements related to the article
      :rtype: dict
        """
      article_data_elements = {}
      
      # I have tried this:
      published_date = self._extract_article_published_date().__await__()

      # and this
      published_date = self.task(self._extract_article_published_date())
      await published_date

      truncated...
      

我也试过用:

if __name__ == "__main__":
    asyncio.run(NewsExtraction.get_article_data_elements())
    # asyncio.run(self.get_article_data_elements())

在我的新闻提取代码中使用 asyncio 真是让我头撞墙。

如果这个问题不对,我很乐意将其删除并继续阅读如何正确使用 asyncio

有人可以提供一些建议来解决我的问题吗?

提前感谢您提供有关使用 asyncio

的任何指导

您正在将 _extract_article_published_dateget_article_data_elements 定义为协同程序,并且必须在您的代码中 await 编辑此协同程序才能以异步方式获取它们的执行结果。

你可以这样做,创建类型 NewsExtraction 的实例,并在前面使用关键字 await 调用此方法,此 await 将执行传递给循环中的其他任务,直到他等待的任务完成执行。请注意,此任务执行不涉及任何线程或进程,只有在不使用 cpu-time(await-ing I/O 操作或休眠)时才会通过执行。

if __name__ == '__main__':
    extractor = NewsExtraction(...)
    # this creates the event loop and runs the coroutine
    asyncio.run(extractor.get_article_data_elements())

在您的 _extract_article_published_date 中,您还必须 await 通过网络执行请求的协程,如果您使用某些库进行抓取,请确保使用 async/await 在幕后使用 asyncio.

获得真正的表演
async def get_article_data_elements(self):
      article_data_elements = {}
      
     # note here that the instance is self
      published_date = await self._extract_article_published_date()

      truncated...

您必须深入研究 asyncio documentation 才能更好地了解 Python 3.7+ 的这些功能。