TypeError:“ list_iterator”对象不可异步迭代

时间:2018-09-09 15:25:51

标签: python-3.x web-scraping python-asyncio

我有一个简单的python3 webscraper,它正在同步工作。我想使其异步,所以我对其做了一些修改。但是,即使将程序转换为使用iter()将其转换为可迭代列表之后,该程序也不会迭代未压缩列表def y_labels(y): start_note_values = T.alloc(np.array(0, dtype=np.int8), BATCH_SIZE * NUM_TIMESTEPS, 1, OUTPUT_LAYER) correct_choices = y[:, :, :-1, :].reshape((BATCH_SIZE * NUM_TIMESTEPS, NUM_NOTES - 1, OUTPUT_LAYER)) features = T.concatenate([start_note_values, correct_choices], axis=1) return features.reshape((BATCH_SIZE, NUM_TIMESTEPS, NUM_NOTES, OUTPUT_LAYER)).transpose((0, 2, 1, 3)).reshape((BATCH_SIZE * NUM_NOTES, NUM_TIMESTEPS, OUTPUT_LAYER)) get_labels_shape = lambda shape: [BATCH_SIZE * NUM_NOTES, NUM_TIMESTEPS, OUTPUT_LAYER] previous_notes = Sequential([ Lambda(y_labels, output_shape=get_labels_shape, batch_input_shape=(BATCH_SIZE, NUM_TIMESTEPS, NUM_NOTES, OUTPUT_LAYER), name='y_labels') ]) 。说X = (440, 128, 300)

因为我的代码很大,而且我仍在学习异步编程,所以这里将“错误”放在主要部分。

我的目的是异步获取链接以加快过程。有办法解决吗?


代码:

[(,), (,), (,), ...]

错误:

TypeError: 'list_iterator' object is not async iterable

2 个答案:

答案 0 :(得分:0)

除了尝试在普通迭代器上进行异步迭代(已解决)的问题之外,还有一个更深层的问题,即您没有使用异步http库。

例如,您无法await requests.get的结果,因为requests.get()不会返回asyncio的未来,而是返回Response。删除await可以使错误消失,但是最终会产生普通的同步代码。为了加快并行运行多个下载的速度,您需要:

aiostream可能为此目的过大了-它专门处理异步迭代器。 (异步迭代器是类似迭代器的对象,其__next__被称为__anext__,是一个协程。典型的用例是数据库API,它为结果行提供异步迭代器。它们通过{进行迭代{1}},但async for通过异步迭代器提供了广泛的运算符,涵盖了创建,转换,选择,聚合等等。

答案 1 :(得分:-2)

是的,您这里需要一个异步迭代器。修复后,它会按顺序异步下载网址。

asking the project maintainer on gihub之后,我了解了它的实际工作原理。

xs = stream.iterate(myList)
ys = stream.starmap(xs, download, ordered=True, task_limit=20)
zs = stream.starmap(ys, process, ordered=True, task_limit=20)
await ys

它如何工作?

  • 首先,我们在myList上创建一个异步的可迭代对象。

  • 然后我们将其传递给download,它异步获取结果。

  • 然后,我们将从download返回的下载内容传递给process函数,以对其进行处理 我们想。就我而言,是《 Beautiful Soup 4》。

请注意,starmap接受格式为[(,), (,), (,), . . .]的解压缩值。您可以在这些元组中压缩更多的值。我需要两个,所以我将它们设置为这种格式。


工作代码:

import asyncio
from aiostream import stream, pipe
from aiohttp import ClientSession
from bs4 import BeautifulSoup as bs

myList = []

def get_myList():
    #Append values to myList in the format [(,), (,), (,), ...]
    pass

async def download(link, title):
    # Download a page
    async with ClientSession() as session:
        async with session.get(url) as response:
            response = await response.read()
            return (response, title)

def process(response, title):
    # Do some processing with bs4
    pass

async def main():
    get_myList()

    xs = stream.iterate(myList)
    ys = stream.starmap(xs, download, ordered=True, task_limit=20)
    zs = stream.starmap(ys, process, ordered=True, task_limit=20)
    await ys

if __name__=="__main__":
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())
    loop.close()