aiohttp处理/编码表单数据的方式是否与请求不同



概述

我已经写了一个脚本,它进入一个页面,抓取表单输入,然后发布回同一页面(就像用户一样;需要这样做才能获得隐藏的输入/令牌等)

我的脚本当前使用requests.Session,我正在尝试迁移到async并使用aiohttp.ClientSession

该登录函数的requests版本有效,但aiohttp版本发送但返回无效的登录响应。

aiohttp对我传递给s.post(...)的数据字典有什么特殊的作用吗?我看到aiohttp在cookie方面有点固执己见,而请求则不然。这是否也扩展到表单数据编码?

相关代码段

请求版本

import requests
from bs4 import BeautifulSoup
URL = '...'
def login(s: requests.Session, username: str, password: str) -> requests.Response:
response = s.get(URL)
soup = BeautifulSoup(response.text, 'html.parser')
inputs = soup.select('form input')
data = {
el['name']: el['value']
for el in inputs
if el.get('name') and el.get('value')
}
data.update({
'Username': username,
'Password': password
})
return s.post(URL, data=data)
if __name__ == '__main__':
with requests.session() as s:
response = login(s, <username>, <password>)

aiohttp版本

import asyncio
import aiohttp
from bs4 import BeautifulSoup
URL = '...'
async def login(s: aiohttp.ClientSession, username: str, password: str) -> aiohttp.ClientResponse:
async with s.get(URL) as response:
soup = BeautifulSoup(await response.text(), 'html.parser')
inputs = soup.select('form input')
data = {
el['name']: el['value']
for el in inputs
if el.get('name') and el.get('value')
}
data.update({
'Username': username,
'Password': password,
})
return await s.post(URL, data=data)
async def main():
jar = aiohttp.CookieJar(quote_cookie=False)
async with aiohttp.ClientSession(cookie_jar=jar) as s:
response = await login(s, <username>, <password>)
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(main())

我尝试过的东西

在这两种情况下,我都在发送data变量之前打印出了它,它们是相同的(除了页面生成的随机令牌等),我尝试更改内容类型的标题,我已经启动了一个快速Flask服务器,我已经向其发送了这两个请求,request.data看起来是相同的。

版本

在Ubuntu 20 上运行

Python:3.8.5

皮普冻结输出

aiodns==2.0.0
aiohttp==3.7.3
async-timeout==3.0.1
attrs==20.3.0
beautifulsoup4==4.9.3
brotlipy==0.7.0
cchardet==2.1.7
certifi==2020.12.5
cffi==1.14.4
chardet==3.0.4
click==7.1.2
Flask==1.1.2
idna==2.10
itsdangerous==1.1.0
Jinja2==2.11.2
MarkupSafe==1.1.1
multidict==5.1.0
numpy==1.19.5
pandas==1.2.0
pycares==3.1.1
pycparser==2.20
python-dateutil==2.8.1
python-dotenv==0.15.0
pytz==2020.5
requests==2.25.1
six==1.15.0
soupsieve==2.1
typing-extensions==3.7.4.3
ua-parser==0.10.0
urllib3==1.26.2
Werkzeug==1.0.1
yarl==1.6.3

主要问题

aiohttp处理/编码表单数据的方式是否与请求不同?如果没有,那么aiohttp请求失败的原因是什么?

尝试设置allow_redirects=False并手动执行。

async def login(s: aiohttp.ClientSession, username: str, password: str) -> aiohttp.ClientResponse:
async with s.get(URL) as response:
soup = BeautifulSoup(await response.text(), 'html.parser')
inputs = soup.select('form input')
data = {
el['name']: el['value']
for el in inputs
if el.get('name') and el.get('value')
}
data.update({
'Username': username,
'Password': password,
})
resp = await s.post(URL, data=data, allow_redirects=False)
return await s.get(resp.headers.get('Location'))

相关内容

最新更新