在上一个项目(《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 of requests.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中设置。

首先,我们先看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赋值给sessioncookies属性:

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()

诸如此类的差异很难在一一列出,如果你有其他想法,在下面评论区留言吧!