本文最近一次更新于 5 年 零 8 个月 前,其中所包含的信息很可能已经有所发展或是发生改变。
前言
我为什么会想到要写一个下载器呢,实在是被百度云给逼的没招了,之前用 Axel 配合直链在百度云下载视频能达到满速,结果最近两天 Axel 忽然不能用了,于是我就想着要不干脆自己写一个吧,就开始四处查询资料,这就有了这篇博客。
我假设阅读这篇博客的你已经对以下知识有所了解:
- Python 的文件操作
- Python 的多线程
- Python 的线程池
- Python 的 requests 库
- HTTP 报文的首部信息
下载
获取文件采用的是 requests 库,该已经封装好了许多 http 请求,我们只需要发送 get 请求,然后将请求的内容写入文件即可:
|
|
随后看看文件夹,那张名为 wallpaper.png
的图片就是我们刚刚下载的。
但是这个功能太简单了,甚至简陋,我们需要多线程并发执行下载各自的部分,然后再汇总。
拆分
为了拆分,首先得知道数据块的大小,HTTP 报文首部提供了这样的信息:
- 用 head 方法去获取 http 首部信息,再从获取的信息提取出
Content-Length
字段(上文图片大小为 261258 bytes)
|
|
我们得到了图片的前 100001 个字节(Range 的范围是包括起始和终止的),打开 wallpaper.png
你应该能看到一幅“半残”的图。
这样我们里目标更近了一步,继续:
- 确认线程数(比如 8 个),261258//8 = 32657,前 7 个线程都取 32657 个 bytes,第八个取剩余的
|
|
- 每个线程获取到的内容按顺序写入文件(file.seek() 调节文件指针)
|
|
嘛,线程多了起来就扔到线程池让它来帮我们调度。
封装
功能复杂了,用对象来封装整理一下:
|
|
至此,核心功能都完成了,剩下的就是实际体验的优化了。
完整的代码已托管至 GitHub,地址见这里。
结语
很可惜,我写的这个下载器还是不能下载百度云直链,不过嘛,好多人都说结果不重要,都说重要的是过程,不是么?写这个下载器我也确实学到了许多,至于一开始我是出于什么样的目的?管他呢
Python 实现多线程下载器
https://blog.itswincer.com/posts/80689c8d/