我有一个简单的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
答案 0 :(得分:0)
除了尝试在普通迭代器上进行异步迭代(已解决)的问题之外,还有一个更深层的问题,即您没有使用异步http库。
例如,您无法await
requests.get
的结果,因为requests.get()
不会返回asyncio的未来,而是返回Response
。删除await
可以使错误消失,但是最终会产生普通的同步代码。为了加快并行运行多个下载的速度,您需要:
从requests
切换到异步http库,例如出色的aiohttp
使用asyncio.gather
等待并行运行的下载,例如here
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()