我正在尝试自学Python的异步功能.为此,我构建了一个异步Web scraper.我想限制我一次打开的连接总数,以成为服务器上的好公民.我知道信号量是一个很好的解决方案,并且asyncio库内置了一个信号量类.我的问题是,当你在组合和语法yield from中使用async函数时,Python会抱怨.以下是我正在使用的确切语法...yieldawait
import asyncio
import aiohttp
sema = asyncio.BoundedSemaphore(5)
async def get_page_text(url):
with (yield from sema):
try:
resp = await aiohttp.request('GET', url)
if resp.status == 200:
ret_val = await resp.text()
except:
raise ValueError
finally:
await resp.release()
return ret_val
Run Code Online (Sandbox Code Playgroud)
提出这个例外:
File "<ipython-input-3-9b9bdb963407>", line 14
with (yield from sema):
^
SyntaxError: 'yield from' inside async function
Run Code Online (Sandbox Code Playgroud)
我能想到的一些可能的解决方案......
@asyncio.coroutine装饰器我是Python的异步功能的新手,所以我可能会遗漏一些明显的东西.
第一次尝试asyncio并且aiohttp。我有以下urls从MySQL数据库获取GET请求的代码。获取响应并将其推送到MySQL数据库。
if __name__ == "__main__":
database_name = 'db_name'
company_name = 'company_name'
my_db = Db(database=database_name) # wrapper class for mysql.connector
urls_dict = my_db.get_rest_api_urls_for_specific_company(company_name=company_name)
update_id = my_db.get_updateid()
my_db.get_connection(dictionary=True)
for url in urls_dict:
url_id = url['id']
url = url['url']
table_name = my_db.make_sql_table_name_by_url(url)
insert_query = my_db.get_sql_for_insert(table_name)
r = requests.get(url=url).json() # make the request
args = [json.dumps(r), update_id, url_id]
my_db.db_execute_one(insert_query, args, close_conn=False)
my_db.close_conn()
Run Code Online (Sandbox Code Playgroud)
这工作正常,但要加快速度我该如何运行它asynchronously?