【发布时间】:2021-01-16 00:39:48
【问题描述】:
概述
我编写了一个脚本,该脚本可以进入页面,抓取表单输入,然后发回同一页面(就像用户会做的那样;需要这样做才能获取隐藏的输入/令牌/等。) .
我的脚本目前使用requests.Session,我正在尝试迁移到异步并改用aiohttp.ClientSession。
这个登录功能的requests版本有效,但是aiohttp版本发送却返回一个无效的登录响应。
aiohttp 对我传递给s.post(...) 的数据字典有什么特殊作用吗?我看到 aiohttp 是 slightly opinionated when it comes to cookies 而 requests 不是。这是否也扩展到表单数据编码?
相关代码片段
请求版本
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 请求失败的原因是什么?
【问题讨论】:
标签: python beautifulsoup python-requests python-asyncio aiohttp