2 回答

TA貢獻1836條經(jīng)驗 獲得超5個贊
如何避免[多次請求]?
你可以使用asyncio.Lock
:
saync def __init__(self, ...):
? ? ...
? ? self._page_lock = asyncio.Lock()
async def _get_page(self) -> HtmlElement:
? ? async with self._page_lock:
? ? ? ? if self._page is None:
? ? ? ? ? ? async with self._get_session().get(self._url) as page:
? ? ? ? ? ? ? ? self._page = lxml.html.document_fromstring(await page.text())
? ? return self._page

TA貢獻1934條經(jīng)驗 獲得超2個贊
Python 3.8 和 jupyter 筆記本的更新
import asyncio
import aiohttp
from lxml import html
class MyClass:
? ? def __init__(self):
? ? ? ? self._url = 'https://www.google.com'
? ? ? ? self._page = None
? ? ? ? self._futures = []
? ? ? ? self._working = False
? ? ? ? self._session = aiohttp.ClientSession()
? ? async def _close(self):
? ? ? ? if self._session:
? ? ? ? ? ? session = self._session
? ? ? ? ? ? self._session = None
? ? ? ? ? ? await session.close()
? ? def _get_session(self):
? ? ? ? return self._session
? ? async def _get_page(self):
? ? ? ? if self._page is None:
? ? ? ? ? ? if self._working:
? ? ? ? ? ? ? ? print('will await current page request')
? ? ? ? ? ? ? ? loop = asyncio.get_event_loop()
? ? ? ? ? ? ? ? future = loop.create_future()
? ? ? ? ? ? ? ? self._futures.append(future)
? ? ? ? ? ? ? ? return await future
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? self._working = True
? ? ? ? ? ? session = self._get_session()
? ? ? ? ? ? print('making url request')
? ? ? ? ? ? async with session.get(self._url) as page:
? ? ? ? ? ? ? ? print('status =', page.status)
? ? ? ? ? ? ? ? print('making page request')
? ? ? ? ? ? ? ? self._page = html.document_fromstring(await page.text())
? ? ? ? ? ? ? ? print('Got page text')
? ? ? ? ? ? ? ? for future in self._futures:
? ? ? ? ? ? ? ? ? ? print('setting result to awaiting request')
? ? ? ? ? ? ? ? ? ? future.set_result(self._page)
? ? ? ? ? ? ? ? self._futures = []
? ? ? ? ? ? ? ? self._working = False
? ? ? ? return self._page
async def main():
? ? futures = []
? ? m = MyClass()
? ? futures.append(asyncio.ensure_future(m._get_page()))
? ? futures.append(asyncio.ensure_future(m._get_page()))
? ? futures.append(asyncio.ensure_future(m._get_page()))
? ? results = await asyncio.gather(*futures)
? ? for result in results:
? ? ? ? print(result[0:80])
? ? await m._close()
if __name__ == '__main__':
? ? asyncio.run(main())
? ? #await main() # In jupyter notebook and iPython
請注意,在 Windows 10 上,我在終止時看到:
RuntimeError: Event loop is closed
添加回答
舉報