知其然,知其所以然
爬虫工程 2026-10-12

连接复用:Session 与每次新建连接,一次请求差多少毫秒

在本机测试服务器上实测 requests 的连接复用:300 次 HTTP 小请求,每次 requests.get 0.50 ms、同一个 Session 0.33 ms;HTTPS 下是 1.51 ms 对 0.35 ms(4.34 倍);服务器那边记下的连接数是 300 对 1;stream=True 没读完响应、服务器回 Connection: close 时 Session 也复用不了。

爬虫 requests Session 连接复用 keep-alive TLS Python 真实验证 动画演示
MongoDB 2026-10-12

dbpath 目录:每个文件分别是干什么的

实测 mongod 的 dbpath 目录:WiredTiger、turtle、_mdb_catalog.wt、sizeStorer.wt、storage.bson、mongod.lock 各是什么;每个集合、每个索引一个 .wt 文件,文件名里的 ident 用 collStats 与 $listCatalog 对应;journal 是 100 MiB 的稀疏预分配文件;drop 集合后对应文件消失。

MongoDB dbpath WiredTiger 文件 journal 真实验证 动画演示
爬虫工程 2026-10-12

连接池大小:pool_maxsize 不够时并发线程会发生什么

在本机测试服务器上实测 requests 的连接池:默认 pool_maxsize=10 并不限制并发,30 个并发请求会开出 30 条连接并丢弃 20 条(WARNING: Connection pool is full);第二波再开 20 条;pool_block=True 才能把并发限制在 10;pool_connections 是缓存的主机池个数。

爬虫 requests 连接池 HTTPAdapter pool_maxsize pool_block Python 真实验证 动画演示
MongoDB 2026-10-12

压缩:snappy、zstd、zlib 下同一份数据占多少磁盘

实测 WiredTiger 的块压缩:同样 100,000 个日志样文档,none、snappy、zstd、zlib 的 storageSize 是 BSON 总大小的 104%、46%、31%、35%;插入耗时差别不大,冷缓存扫描 zstd 与 zlib 约是 snappy 的两倍;随机数据几乎不可压缩;集合默认 snappy,索引用前缀压缩。

MongoDB 压缩 snappy zstd zlib WiredTiger 真实验证 动画演示
爬虫工程 2026-10-12

keep-alive 空闲超时:服务端先关掉连接,客户端怎么发现

在本机测试服务器上实测 keep-alive 空闲超时:服务器空闲 1 秒后关闭连接,客户端隔 1.5 秒再请求会悄悄新建连接(套接字已是 CLOSE_WAIT),没有报错;urllib3 靠 wait_for_read 在取连接时检测;服务器收到请求后才断开则会抛 RemoteDisconnected,需要 Retry;Keep-Alive: timeout 提示客户端不读。

爬虫 requests keep-alive 空闲超时 urllib3 RemoteDisconnected Python 真实验证 动画演示
MongoDB 2026-10-12

删了数据磁盘为什么不还:compact 前后对比

实测删数据后磁盘为什么不还:删掉 90% 的文档后 dataSize 立刻下降,磁盘文件反而略增,空间变成“可复用空闲”留在文件里;再插入会复用它;compact 把 36 MB 空闲空间还给操作系统(文件 45.5 MB → 9.2 MB);compact 期间读写照常;drop 集合则立即删掉文件。

MongoDB 磁盘空间 compact delete WiredTiger 真实验证 动画演示
爬虫工程 2026-10-12

超时的几种含义:requests 的 timeout 为什么不是总时长

实测 requests 的 timeout:连接超时耗时恰好等于设定值;读超时限制的是两次数据到达之间的间隔,每 0.5 秒滴灌 1 个字节的 3 秒响应用 timeout=1.0 照样成功;读响应体阶段超时抛的是 ConnectionError 而不是 ReadTimeout;总时长要自己用 stream=True 加截止时间;不传 timeout 就一直阻塞。

爬虫 requests 超时 timeout ConnectTimeout ReadTimeout Python 真实验证 动画演示
爬虫工程 2026-10-12

重定向:301、302、307、308 对 POST 的影响与跳转上限

实测 requests 的重定向:POST 遇到 301/302/303 变成 GET 并丢掉请求体,307/308 保持 POST 和请求体;默认最多跳 30 次(第 31 跳抛 TooManyRedirects,服务器收到 31 个请求);跳到另一个主机时 Authorization 和 Cookie 被去掉,但自定义的 X-Token 头会原样带过去。

爬虫 requests 重定向 301 302 307 308 Authorization Python 真实验证 动画演示
爬虫工程 2026-10-12

响应压缩:gzip、br、zstd 与自动解压

实测爬虫里的响应压缩:requests 默认的 Accept-Encoding 取决于本机是否装了 brotli(gzip, deflate, zstd 变成 gzip, deflate, br, zstd);同一页面 gzip 7.3%、zstd 4.9%、br 3.2%;随机数据压缩无收益;服务器硬发 br 而客户端没装库时 r.content 是未解压的乱码;65250 字节的 gzip 解压成 64 MiB。

爬虫 requests gzip brotli zstd Content-Encoding 压缩炸弹 Python 真实验证 动画演示
爬虫工程 2026-10-12

流式读取:chunked 响应与提前中止下载

实测 requests 的流式读取:chunked 响应没有 Content-Length,stream=True 下 iter_content 按块到达的时刻产出(chunk_size=4096 也不会等凑满);iter_lines 能拼回跨块的行;只看响应头时 HEAD 0.6 ms 且连接可复用,stream 加 close 1.2 ms 但连接被丢弃;响应被截断会抛 ChunkedEncodingError。

爬虫 requests 流式读取 chunked iter_content stream Python 真实验证 动画演示
爬虫工程 2026-10-12

Cookie 的域与路径匹配:CookieJar 什么时候带上、什么时候不带

在本机用多个主机名实测 requests 的 Cookie 匹配:没写 Domain 的 cookie 会发给子域名;Domain=example.test 覆盖子域但不覆盖 notexample.test;Path 按目录边界匹配且区分大小写;cookie 不区分端口;Domain=co.uk 被接受并发给 other.co.uk(http.cookiejar 没有公共后缀列表);手写 Cookie 头会取代 jar。

爬虫 requests Cookie CookieJar Domain Path http.cookiejar 公共后缀 Python 真实验证 动画演示
爬虫工程 2026-10-12

HTTP 代理的 CONNECT 隧道:代理到底看到了什么

用自己写的本地代理实测 HTTP 代理的可见范围:HTTP 地址经代理时代理看到完整 URL、查询串和 Cookie;HTTPS 地址只有 CONNECT 主机:端口和明文 SNI,路径与头看不到;407 时 HTTP 地址返回 407 而 HTTPS 抛 ProxyError;NO_PROXY 只管环境变量里的代理,proxies= 参数不受它影响。

爬虫 requests 代理 HTTP代理 CONNECT HTTPS NO_PROXY Proxy-Authorization Python 真实验证 动画演示
京ICP备2026067502号-1京公网安备11010502063487号