在上一个项目(《Bilibili GetReceivedGiftStream》)中,登陆部分使用单线程的 Requests ,爬取数据部分采用异步的 Aiohttp ,今日有时间删掉这两个,改成既能同步又能异步的 Httpx ,在此记录一下需要修改的部分。
主要是 Requests 与 Httpx 的 Cookies 部分。
Client 与 Session
在官方文档中写道,Client
可代替Session
:
If you are coming from Requests,
httpx.Client()
is what you can use instead ofrequests.Session()
.
但同时他们也有一些区别(详见官方文档 兼容性 一节)
We prefer enforcing a stricter API here because it provides clearer expectations around cookie persistence, particularly when redirects occur.
这使得一些参数仅可在 Client
中设置,而不可基于每个请求单独设置,例如:
# 这样是允许的
client = httpx.Client(cookies=...)
client.post(...)
# 这样是禁止的
client = httpx.Client()
client.post(..., cookies=...)
同理,像verify
等参数仅可在Client
中设置。
Cookie 和 Cookie.jar
首先,我们先看http.cookiejar
都有哪些特征:
import http.cookiejar as cookielib
cookies = cookielib.LWPCookieJar("bzcookies.txt")
print(cookies)
print(type(cookies))
输出:
<LWPCookieJar[]>
<class 'http.cookiejar.LWPCookieJar'>
可以看到,此时cookiejar中内容为空,我们需要通过load
方法加载 Cookie 的值:
cookies.load()
print(cookies)
print(type(cookies))
输出中包含 Cookie 值内容。此时,我们可以用cookies.save()
来将 Cookies 值保存到文件bzcookies.txt
中。
当使用 Requests 时,新建session
后,将LWPCookieJar
赋值给session
的cookies
属性:
cookies = cookielib.LWPCookieJar("bzcookies.txt")
session = requests.Session()
print(session.cookies)
print(type(session.cookies))
session.cookies = cookies
print(session.cookies)
print(type(session.cookies))
输出:
<RequestsCookieJar[]>
<class 'requests.cookies.RequestsCookieJar'>
<LWPCookieJar[]>
<class 'http.cookiejar.LWPCookieJar'>
可见,赋值直接改变了session.cookies
的类型,使其从RequestsCookieJar
变为LWPCookieJar
。
但在 httpx 中不同:
cookies = cookielib.LWPCookieJar("bzcookies.txt")
client = httpx.Client()
print(client.cookies)
print(type(client.cookies))
client.cookies = cookies
print(client.cookies)
print(type(client.cookies))
输出:
<Cookies[]>
<class 'httpx.Cookies'>
<Cookies[]>
<class 'httpx.Cookies'>
赋值并未改变client.cookies
的类型,那传递的值保存在哪里了呢?
print(client.cookies.jar)
print(type(client.cookies.jar))
输出:
<LWPCookieJar[]>
<class 'http.cookiejar.LWPCookieJar'>
httpx.Cookies
将 CookieJar 保存在client.cookies.jar
中。
同理,要使用load()
或save()
,需写为:
client.cookies.jar.load()
client.cookies.jar.save()
诸如此类的差异很难在一一列出,如果你有其他想法,在下面评论区留言吧!
GitHub IssuesGitHub Discussions