【python】多线程下载文件与实际大小极度不符的问题
本帖最后由 MyModHeaven 于 2022-5-3 13:22 编辑- 使用 `requests` 多线程下载文件,下载完成后与实际文件大小不符,差距好几倍甚至十倍
- 前天在网上学着多线程下载一个文件,500多M的一个压缩包,下下来2G多,第二次3G多,昨天搞了一天,无果
- 今天再尝试,8M的一个apk文件,下下来80多M
- 请懂得的老哥帮帮忙,谢谢
```py
import requests
from bs4 import BeautifulSoup
from threading import Thread
def req(url):
headersvalue = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36 Edg/100.0.1185.44',}
r = requests.get(url, headers=headersvalue)
soup = BeautifulSoup(r.text, 'lxml')
return soup
url = 'https://anonfiles.com/rap9r5c9y9/_1.2.9_apk'
dl_link = req(url).find('a', id='download-url')['href']
name = dl_link.split('/')[-1]
filesize = int(requests.head(dl_link).headers['Content-Length'])
def dl(s_pos, e_pos):
headersvalue = {'Accept-Ranges': f'bytes={s_pos}-{e_pos}'}
with requests.get(dl_link, headers=headersvalue, stream=True) as r, open('d:/'+name, 'ab+') as f:
f.seek(s_pos)
for chunk in r.iter_content(chunk_size=256):
f.write(chunk)
l = list(range(0, filesize, filesize//7))
sections = [, l] for i in range(len(l)-1)]
sections[-1][-1] = filesize
for s_pos, e_pos in sections:
Thread(target=dl, args=(s_pos, e_pos)).start()
```
https://static.52pojie.cn/static/image/hrline/1.gif
总结一下,问题就如那位热心的吾友说的:请求头写错了,是range,不是accept-ranges。我写的这个错误的参数名是从响应头上抄来的,应该是当时脑子昏了,后来从网上看见别人写的都是range,当时竟然没意识到这个错误。也非常感谢那位说用 os.system() 调用aria2的吾友,没这样用过,长见识了。
python的多线程。。。我推荐用aria2,ws连接,比自己写的好用得多 很明显,你的代码中,打开的每个线程都在各下各的。
意味着,如果下载的内容有10M,开10个线程,
下完了之后有100M,而且还无法运行。。
多线程是要把整个块分块后交给不同的线程下,而你这个每个线程都是各自完整下载。
感谢分享,学习了! 你的线程都去下载同一个文件,肯定会这样 你请求头写错了{:301_1008:}
是range不是Accept-Ranges 学习了学习了 把要下载的文件分成四块,用四个线程分别下载,再把文件拼起来就行了。可以使用seek()来设置文件的读写位置,计算好每一个文件块的大小,分别写入相应的位置就行了。
懒得折腾可以直接 os.system(command)调用aria2下载,我写自己用的爬虫就直接用aria下载,比自己搞定多线程下载舒服多了...
页:
[1]