鱼C论坛

 找回密码
 立即注册
查看: 692|回复: 10

求助(爬虫代码)

[复制链接]
发表于 2020-5-17 08:38:33 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
  1. import os
  2. import time
  3. from concurrent.futures import ThreadPoolExecutor, wait
  4. from requests import get, head
  5. import sys

  6. class Downloader:
  7.     def __init__(self, url, nums, file):
  8.         self.url = url
  9.         self.num = nums
  10.         self.name = file
  11.         self.getSize = 0
  12.         self.info = {
  13.             'main' : {
  14.                 'progress' : 0,
  15.                 'speed' : ''
  16.             },
  17.             'sub' : {
  18.                 'progress' : [0 for i in range(nums)],
  19.                 'stat' : [1 for i in range(nums)]
  20.             }
  21.         }
  22.         r = head(self.url)

  23.         while r.status_code == 302:
  24.             self.url = r.headers['Location']
  25.             print("该url以重定向至{}".format(self.url))
  26.             r = head(self.url)
  27.         self.size = int(r.headers['Content-Length'])
  28.         print("该文件大小为: {} bytes".format(self.size))

  29.     def down(self, start, end, thread_id, chunk_size=10240):
  30.         raw_start = start
  31.         for _ in range(10):
  32.             try:
  33.                 headers = {'Range' : 'bytes={}-{}'.format(start, end)}
  34.                 r = get(self.url, headers=headers, timeout=10, stream=True)
  35.                 print(f"线程{thread_id}链接成功")
  36.                 size = 0
  37.                 with open(self.name, 'rb+') as fp:
  38.                     fp.seek(start)
  39.                     for chunk in r.iter_content(chunk_size=chunk_size):
  40.                         if chunk:
  41.                             self.getSize += chunk_size
  42.                             fp.write(chunk)
  43.                             start += chunk_size
  44.                             size += chunk_size
  45.                             progress = round(size / (end - raw_start) * 100, 2)
  46.                             self.info['sub']['progress'][thread_id - 1] = progress
  47.                             self.info['sub']['stat'][thread_id - 1] = 1
  48.                 return
  49.             except Exception as e:
  50.                 print(e)
  51.                 self.down(start, end, thread_id)
  52.             print(f"{start}-{end}, 下载失败")
  53.             self.info['sub']['stat'][thread_id - 1] = 0

  54.     def show(self):
  55.         while True:
  56.             speed = self.getSize
  57.             time.sleep(0.5)
  58.             speed = int((self.getSize - speed) * 2 / 1024)
  59.             if speed > 1024:
  60.                 speed = f"{round(speed / 1024, 2)} M/s"
  61.             else:
  62.                 speed = f"{speed} KB/s"
  63.             
  64.             progress = round(self,getsize / self.size * 100, 2)
  65.             self.info['main']['progress'] = progress
  66.             self.info['main']['speed'] = speed
  67.             print(self.info)
  68.             if progress >= 100:
  69.                 break
  70.     def run(self):
  71.         fp = open(self.name ,'wb')
  72.         print(f"正在初始化下载文件: {self.name}")
  73.         fp.truncate(self.size)
  74.         print("初始化文件完成")
  75.         start_time = time.time()
  76.         fp.close()
  77.         part = self.size // self.num
  78.         pool = ThreadPoolExecutor(max_workers=self.num + 1)
  79.         futures = []
  80.         for i in range(self.num):
  81.             start = part * i
  82.             if i == self.num - 1:
  83.                 end = self.size
  84.             else:
  85.                 end = start + part - 1
  86.             futures.append(pool.submit(self.show))
  87.             printf(f'正在使用{self.num}个线程下载……')
  88.             wait(futures)
  89.             end_time = time.time()
  90.             speed = int(self.size / 1024 / (end_time - start_time))
  91.             if speed > 1024:
  92.                 speed = f"{round(speed / 1024, 2)} M/s"
  93.             else:
  94.                 speed = f"{speed} KB/s"
  95.             print(f"{self.name} 下载完成, 平均速度: {speed}")

  96. if __name__ == '__main__':
  97.     debug = 1
  98.     if debug:
  99.         url = 'https://www.bilibili.com/read/cv6032187'
  100.         down = Downloader(url, 8, os.path.basename(url))
  101.     else:
  102.         url = sys.argv[1]
  103.         file = sys.argv[2]
  104.         thread_num = int(sys.argv[3])
  105.         down = Downloader(url, thread_num, file)

  106.     down.run()
复制代码


报错如下:

Traceback (most recent call last):
  File "g:\Programming\Python\text.py", line 105, in <module>
    down = Downloader(url, 8, os.path.basename(url))
  File "g:\Programming\Python\text.py", line 29, in __init__
    self.size = int(r.headers['Content-Length'])
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python38\lib\site-packages\requests\structures.py", line
54, in __getitem__
    return self._store[key.lower()][1]
KeyError: 'content-length'


大佬指导指导@zltzlt @qiuyouzhi
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-5-17 08:39:09 | 显示全部楼层
@heidern0612 @老八秘制 @WangJS
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-17 08:48:26 | 显示全部楼层
MIke_python小小 发表于 2020-5-17 08:39
@heidern0612 @老八秘制 @WangJS

1,不用@那么多的人,有大佬看到就帮你了
2,显示字典没有这个项,你打印一下字典看看
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-5-17 08:49:24 | 显示全部楼层
qiuyouzhi 发表于 2020-5-17 08:48
1,不用@那么多的人,有大佬看到就帮你了
2,显示字典没有这个项,你打印一下字典看看

我这是照着别人抄的

所以不懂

还请你帮我改一下代码吧
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-17 08:56:37 | 显示全部楼层
MIke_python小小 发表于 2020-5-17 08:49
我这是照着别人抄的

所以不懂

改好了,有点投机取巧:
  1. import os
  2. import time
  3. from concurrent.futures import ThreadPoolExecutor, wait
  4. from requests import get, head
  5. import sys

  6. class Downloader:
  7.     def __init__(self, url, nums, file):
  8.         self.url = url
  9.         self.num = nums
  10.         self.name = file
  11.         self.getSize = 0
  12.         self.info = {
  13.             'main' : {
  14.                 'progress' : 0,
  15.                 'speed' : ''
  16.             },
  17.             'sub' : {
  18.                 'progress' : [0 for i in range(nums)],
  19.                 'stat' : [1 for i in range(nums)]
  20.             }
  21.         }
  22.         r = head(self.url)

  23.         while r.status_code == 302:
  24.             self.url = r.headers['Location']
  25.             print("该url以重定向至{}".format(self.url))
  26.             r = head(self.url)
  27.         try:
  28.             self.size = int(r.headers['content-length'])
  29.         except:
  30.             self.size = 33901
  31.         print("该文件大小为: {} bytes".format(self.size))

  32.     def down(self, start, end, thread_id, chunk_size=10240):
  33.         raw_start = start
  34.         for _ in range(10):
  35.             try:
  36.                 headers = {'Range' : 'bytes={}-{}'.format(start, end)}
  37.                 r = get(self.url, headers=headers, timeout=10, stream=True)
  38.                 print(f"线程{thread_id}链接成功")
  39.                 size = 0
  40.                 with open(self.name, 'rb+') as fp:
  41.                     fp.seek(start)
  42.                     for chunk in r.iter_content(chunk_size=chunk_size):
  43.                         if chunk:
  44.                             self.getSize += chunk_size
  45.                             fp.write(chunk)
  46.                             start += chunk_size
  47.                             size += chunk_size
  48.                             progress = round(size / (end - raw_start) * 100, 2)
  49.                             self.info['sub']['progress'][thread_id - 1] = progress
  50.                             self.info['sub']['stat'][thread_id - 1] = 1
  51.                 return
  52.             except Exception as e:
  53.                 print(e)
  54.                 self.down(start, end, thread_id)
  55.             print(f"{start}-{end}, 下载失败")
  56.             self.info['sub']['stat'][thread_id - 1] = 0

  57.     def show(self):
  58.         while True:
  59.             speed = self.getSize
  60.             time.sleep(0.5)
  61.             speed = int((self.getSize - speed) * 2 / 1024)
  62.             if speed > 1024:
  63.                 speed = f"{round(speed / 1024, 2)} M/s"
  64.             else:
  65.                 speed = f"{speed} KB/s"
  66.             
  67.             progress = round(self,getsize / self.size * 100, 2)
  68.             self.info['main']['progress'] = progress
  69.             self.info['main']['speed'] = speed
  70.             print(self.info)
  71.             if progress >= 100:
  72.                 break
  73.     def run(self):
  74.         fp = open(self.name ,'wb')
  75.         print(f"正在初始化下载文件: {self.name}")
  76.         fp.truncate(self.size)
  77.         print("初始化文件完成")
  78.         start_time = time.time()
  79.         fp.close()
  80.         part = self.size // self.num
  81.         pool = ThreadPoolExecutor(max_workers=self.num + 1)
  82.         futures = []
  83.         for i in range(self.num):
  84.             start = part * i
  85.             if i == self.num - 1:
  86.                 end = self.size
  87.             else:
  88.                 end = start + part - 1
  89.             futures.append(pool.submit(self.show))
  90.             print(f'正在使用{self.num}个线程下载……')
  91.             wait(futures)
  92.             end_time = time.time()
  93.             speed = int(self.size / 1024 / (end_time - start_time))
  94.             if speed > 1024:
  95.                 speed = f"{round(speed / 1024, 2)} M/s"
  96.             else:
  97.                 speed = f"{speed} KB/s"
  98.             print(f"{self.name} 下载完成, 平均速度: {speed}")

  99. if __name__ == '__main__':
  100.     debug = 1
  101.     if debug:
  102.         url = 'https://www.bilibili.com/read/cv6032187'
  103.         down = Downloader(url, 8, os.path.basename(url))
  104.     else:
  105.         url = sys.argv[1]
  106.         file = sys.argv[2]
  107.         thread_num = int(sys.argv[3])
  108.         down = Downloader(url, thread_num, file)

  109.     down.run()
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-5-17 09:25:21 | 显示全部楼层
qiuyouzhi 发表于 2020-5-17 08:56
改好了,有点投机取巧:

这是下载到哪里呀

怎么调整呀
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-17 09:26:57 | 显示全部楼层
MIke_python小小 发表于 2020-5-17 09:25
这是下载到哪里呀

怎么调整呀

程序文件所在位置
把程序放到别的地方,或者os.chdir
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-5-17 09:27:53 | 显示全部楼层
qiuyouzhi 发表于 2020-5-17 09:26
程序文件所在位置
把程序放到别的地方,或者os.chdir

能写一个指定的代码吗
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-17 09:28:14 | 显示全部楼层
MIke_python小小 发表于 2020-5-17 09:27
能写一个指定的代码吗

说了啊,os.chdir
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-5-17 09:30:18 | 显示全部楼层

不会
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-17 09:31:46 | 显示全部楼层

os.chdir(字符串形式的目标路径)
还不会就去百度吧
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-19 13:41

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表