[英]aiohttp.ClientSession shared between functions
我正在嘗試在 2 個函數之間共享會話。 登錄后,我必須能夠訪問只有在我通過身份驗證后才能訪問的其他頁面。
import asyncio
import aiohttp
import time
class Http:
async def __aenter__(self):
self._session = aiohttp.ClientSession()
return self
async def __aexit__(self, *err):
await self._session.close()
self._session = None
async def do_post(self, url,data, headers):
async with self._session.post(url, data=data, headers=headers) as resp:
resp.raise_for_status()
return await resp.read()
async def do_get(self, url, headers):
async with self._session.get(url , headers=headers) as resp:
resp.raise_for_status()
return await resp.read()
async def Login():
url = "https:/userlogin"
data={
'email': 'mailm@mail.it',
'pswd': '12345'
}
headers={
'Content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Accept': 'application/json, text/javascript, */*; q=0.01',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:107.0) Gecko/20100101 Firefox/107.0',
}
async with Http() as http:
try:
data = await asyncio.gather(
http.do_post(url, data=data, headers=headers))
return data
except Exception as e:
print("Exception Login: ", e)
async def do_something():
url="https://url_test.it?IsWork=0"
headers={
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:107.0) Gecko/20100101 Firefox/107.0',
'Content-type': 'application/x-www-form-urlencoded; charset=UTF-8'
}
async with Http() as http:
try:
data = await http.do_get(url, headers=headers)
return data
except Exception as e:
print("Exception Login: ", e)
results=asyncio.run(Login())
print (results)
time.sleep(10)
results=asyncio.run(do_something())
print (results)
成功登錄后,當我嘗試訪問do_something()
函數時,我從函數返回中收到會話超時消息。 如何在兩個函數之間使用相同的 Session aiohttp?
更新
顯然按照這篇文章中的建議使用請求會話: python-requests keep session between function可以在函數的返回值中傳遞相同的會話。
是否可以用 aiohttp.ClientSession() 做同樣的事情?
s = requests.session()
# we're now going to use the session in 3 different function calls
login_to_site(s)
page1 = scrape_page(s, 'page1')
page2 = scrape_page(s, 'page2')
# once this function ends we either need to pass the session up to the
# calling function or it will be gone forever
def login_to_site(s):
s.post('http://www.example.com/login')
def scrape_page(s, name):
page = s.get('http://www.example.com/secret_page/{}'.format(name))
return page
是的,您可以在aiohttp
中創建一個ClientSession
並將其傳遞給其他函數,如下所示:
import asyncio
import aiohttp
async def login_to_site(s):
await s.post('http://www.example.com/login')
async def scrape_page(s, name):
page = await s.get('http://www.example.com/secret_page/{}'.format(name))
return page
async def main():
name = "some_name"
async with aiohttp.ClientSession() as session:
await login_to_site(session)
result = await scrape_page(session, name)
if __name__ == "__main__":
asyncio.run(main())
會話在with
塊之后關閉。
要運行異步內容,您需要在異步函數中,因此您必須首先將 aiohttp 部分包裝在異步函數中,然后使用 asyncio 運行它。
運行異步函數。 你需要先用()
調用它們,它返回一個協程然后await
它們。
如果想在其他函數中傳遞和使用session,需要將它們轉為協程。
之后您的代碼應按預期運行。
我想利用 aiohttp 的潛力,因此利用 async\wait。 在我的程序中,有些調用需要異步調用,等待結果再繼續。
現在這應該是使用 aiohttp.ClientSession 的相同代碼:
from aiohttp import ClientSession
import asyncio
async def main():
session = ClientSession()
headers={ "Some" : "Header"}
data = {"username": "foo",
"password": "bar",
"csrf_token": csrf}
async with session.post(URL_Login, data=data, headers=headers) as Login:
print(await Login.text())
async with session.get(URL_Scrape) as Scrape:
html = await Scrape.text()
asyncio.run(main())
URL_Scrape html 頁面仍然是登錄頁面(json 結果邀請您登錄該網站,在登錄請求失敗后將我重定向到登錄頁面)。 這肯定是你在說什么:會話在 with 塊之后關閉。
如何在多個函數之間保持同一個會話處於活動狀態? 是否應該使用 cookie?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.