我正在 aiohttp 中编写网络爬虫并遇到 cookie 问题。我尝试抓取的服务器需要身份验证,并且为了获取可供经过身份验证的用户使用的页面,我需要在密钥本身中设置一个带有括号的 cookie。这是一个问题,因为aiohttp.ClientSession.cookie_jar.update_cookies要么忽略任何非法 cookie:
session = ClientSession()
cookie = SimpleCookie("a[b]=1234;")
session.cookie_jar.update_cookies(cookie)
print([f for f in session.cookie_jar]) # empty list, cookie not set
Run Code Online (Sandbox Code Playgroud)
或提出CookieError:
session = ClientSession()
cookie = SimpleCookie()
cookie["a[b]"] = "1234" # http.cookies.CookieError: Illegal key 'a[b]'
session.cookie_jar.update_cookies(cookie)
print([f for f in session.cookie_jar])
session = ClientSession()
session.cookie_jar.update_cookies([("a[b]", "1234")]) # http.cookies.CookieError: Illegal key 'a[b]'
print([f for f in session.cookie_jar])
Run Code Online (Sandbox Code Playgroud)
可以通过访问http.cookies.Morsel受保护的成员来强制设置cookie _key,即
session = ClientSession()
session.cookie_jar.update_cookies([("__tmp", "1234")])
for cookie in session.cookie_jar:
if …Run Code Online (Sandbox Code Playgroud) 使用 aiohttp 进行客户端请求和 websocket 连接我试图找到一个合适的 pytest 实现。
对于客户端请求,我使用aioresponses https://pypi.python.org/pypi/aioresponses/0.1.2
为了模拟 websocket 连接,我不知道该怎么做。有人有什么建议吗?
谢谢 !
我想记录aiohttp ClientSession发送的所有 HTTP 请求。该文档提供了可用记录器的列表。所以我尝试了以下方法:
import asyncio
import logging
import aiohttp
logging.basicConfig()
logging.getLogger().setLevel(logging.DEBUG)
http_logger = logging.getLogger("aiohttp.client")
http_logger.setLevel(logging.DEBUG)
http_logger.propagate = True
async def make_request():
async with aiohttp.ClientSession() as session:
async with session.get('https://httpbin.org/get') as resp:
return await resp.text()
loop = asyncio.get_event_loop()
response_text = loop.run_until_complete(make_request())
print(response_text)
Run Code Online (Sandbox Code Playgroud)
但这只产生了以下输出:
DEBUG:asyncio:Using selector: EpollSelector
// response text print here
Run Code Online (Sandbox Code Playgroud)
我尝试了文档中该列表中的所有记录器,然后搜索问题。这个类似:在aiohttp 2中指定日志请求格式
答案描述了如何为 aiohttp 服务器设置日志记录。有趣的是,他们必须显式注册记录器:
app = web.Application(loop=loop)
app.router.add_get('/', handle)
app.router.add_get('/{name}', handle)
loop.run_until_complete(
loop.create_server(
app.make_handler(access_log=mylogger, #<--------------- HERE
access_log_format='%r %s %b'), '0.0.0.0', 8080))
Run Code Online (Sandbox Code Playgroud)
这对于客户来说也是必要的吗?我可以合理地注入记录器的唯一方法可能是会话。但ClientSession 的 …
我想显示请求的所有 HTTP 标头(我添加的和自动生成的)。我尝试使用跟踪(https://aiohttp.readthedocs.io/en/stable/tracing_reference.html#aiohttp-client-tracing-reference):
#!/usr/bin/env python3
import aiohttp
import asyncio
async def on_request_start(session, trace_config_ctx, params):
print("Starting %s request for %s. I will send: %s" % (params.method, params.url, params.headers))
async def on_request_end(session, trace_config_ctx, params):
print("Ending %s request for %s. I sent: %s" % (params.method, params.url, params.headers))
async def fetch(session, url):
async with session.get(url) as response:
return response
async def main():
trace_config = aiohttp.TraceConfig()
trace_config.on_request_start.append(on_request_start)
trace_config.on_request_end.append(on_request_end)
async with aiohttp.ClientSession(trace_configs=[trace_config]) as session:
r = await fetch(session, 'http://stackoverflow.com')
print(r)
loop = asyncio.get_event_loop()
loop.run_until_complete(main()) …Run Code Online (Sandbox Code Playgroud) 我有一些代码可以使用asyncio和向远程站点发出请求aiohttp。
import aiohttp, asyncio
async def f():
session = aiohttp.ClientSession()
async with session.get('https://httpbin.org/get') as response:
pass
asyncio.run(f())
Run Code Online (Sandbox Code Playgroud)
当我运行它时,它会产生
Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x7f56796b3d68>
Unclosed connector
connections: ['[(<aiohttp.client_proto.ResponseHandler object at 0x7f56793836a8>, 0.0)]']
connector: <aiohttp.connector.TCPConnector object at 0x7f56796b3f98>
Run Code Online (Sandbox Code Playgroud)
现在,不推荐我提出请求的方式(出于各种原因),这就是我收到这些消息的原因。但是,他们肯定不会阻止我,所以我只想再也见不到他们。
我合理地认为它们是正常的警告,并尝试通过-Wignore命令行选项禁用它们,以及将以下代码放在脚本的开头
import warnings
warnings.filterwarnings('ignore')
Run Code Online (Sandbox Code Playgroud)
但消息不断出现。怎么会?我怎样才能压制他们?
我想使用 aiohttp 进行多帖子。而且,我需要用文件发布。但是,我的代码不起作用这是我的代码
import aiohttp
file = open('file/path', 'rb')
async with aiohttp.request('post', url, files=file) as response:
return await response.text()
Run Code Online (Sandbox Code Playgroud)
和request.FILES is None
这是引用通告
def post(self, url: StrOrURL,
*, data: Any=None, **kwargs: Any) -> '_RequestContextManager':
"""Perform HTTP POST request."""
return _RequestContextManager(
self._request(hdrs.METH_POST, url,
data=data,
> **kwargs))
E TypeError: _request() got an unexpected keyword argument 'files'
Run Code Online (Sandbox Code Playgroud)
拜托....这可能...?我需要解决方案...请...T^T
这是所需的输出
request.FILES['key'] == file
关键是html形式
def post(self, url: StrOrURL,
*, data: Any=None, **kwargs: Any) -> '_RequestContextManager':
"""Perform HTTP POST request."""
return _RequestContextManager(
self._request(hdrs.METH_POST, url, …Run Code Online (Sandbox Code Playgroud) 当我尝试通过 HTTPS 代理发出请求时 -
async with session.get(
url
headers={"k": v},
proxy='https://my-proxy.com:1234',
) as response:
resp_json = await response.json()
Run Code Online (Sandbox Code Playgroud)
我的请求失败,但出现以下异常:
raise ValueError("Only http proxies are supported")
Run Code Online (Sandbox Code Playgroud)
这对应于源代码。
然而,文档说支持 HTTPS 代理。
这是文档中的疏忽还是我做错了?
我不明白为什么resp.json()需要等待。据我了解,async/await 在处理 I/O 时很有用。但是,当我在下面的示例中调用 resp.json() 时,Web 请求是否尚未使用上面行中的 session.get() 进行处理?
async with session.get('https://api.github.com/events') as resp:
print(await resp.json())
Run Code Online (Sandbox Code Playgroud) 我正在使用 AIOHTTP 开发 API 服务,尝试集成一些异步 ORM,第一个候选者是 Tortoise-ORM。在 Django 项目中,我有很多链接模型,其__str__方法如下:
from tortoise.models import Model
from tortoise import fields
class Department(Model):
id = fields.IntField(pk=True)
title = fields.TextField()
upper = fields.ForeignKeyField('models.Department', related_name='children')
def __str__(self):
if self.upper is not None:
return f'{self.id} Department {self.title} of {self.upper.title}'
else:
return f'{self.id} Department {self.title}, head'
class Employee(Model):
id = fields.IntField(pk=True)
name = fields.TextField()
dep = fields.ForeignKeyField('models.Department', related_name='employees')
def __str__(self):
return f'{self.id}. Employee {self.name} of {self.dep.title}'
Run Code Online (Sandbox Code Playgroud)
以便每个对象在描述中显示其相关模型。但在 Tortoise 中我得到一个错误:
AttributeError:“QuerySet”对象没有属性“title”
我想不可能在__str__方法中等待查询。那么,是否有可能使用相关模型的字段来使用 Tortoise-ORM 创建对象表示?
我正在尝试使用 Discord.py 将附件上传到 Ballchasing 的 API。以下是相关的 API 部分:
https://discordpy.readthedocs.io/en/latest/api.html#discord.Attachment.read
https://ballchasing.com/doc/api#upload-upload-post
文档中的示例建议使用请求,但我一遍又一遍地读到,这对于 Discord 机器人来说不是最佳实践,因为您希望异步代码以避免任何可能阻止脚本执行的情况。
这是我所拥有的:
@commands.Cog.listener()
async def on_message(self, message):
headers = {'Authorization':self.upload_key_bc}
for attachment in message.attachments:
file = io.BytesIO(await attachment.read())
action = {'file': ('replay.replay', file.getvalue())}
async with aiohttp.ClientSession() as session:
async with session.post(self.api_upload_bc, headers=headers, data=action) as response:
print(response.status)
print(await response.text())
Run Code Online (Sandbox Code Playgroud)
我收到这样的回复:
failed to get multipart form: request Content-Type isn't multipart/form-data
Run Code Online (Sandbox Code Playgroud)
我尝试将 Content-Type 标头强制为 multipath/form-data,但出现了不同的错误:
failed to get multipart form: no multipart boundary param in Content-Type
Run Code Online (Sandbox Code Playgroud)
我认为我发送数据的方式有问题。我缺少什么?
aiohttp ×10
python ×8
python-3.x ×2
cookies ×1
discord.py ×1
http-proxy ×1
https ×1
logging ×1
orm ×1
proxy ×1
pytest ×1
python-3.6 ×1
tortoise-orm ×1