清华文泉学堂协程下载

yjsx86 21天前 62

协程下载, 增加下载速度, 试试看
github上那个试用了一下 会出现not found 还是not load 来着导致下载失败
这个会把下载失败的重回队列, 最终会下载成功的(测试的时候有两张图总是下载失败, 程序重试了上百次后成功了!)
有反映会下载“正在加载”的图片, 修改了下代码, 把服务器返回错误图片的地址重回队列, 并且增加了下载时间间隔的设置,如何最优自己调试吧
  1. import requests
  2. import jwt
  3. import json
  4. import time
  5. import aiohttp
  6. import asyncio
  7. import os
  8. import logging

  9. logging.basicConfig(format="%(asctime)s [%(levelname)s]: %(message)s", level=logging.INFO)

  10. class Wqxuetang():

  11.     def __init__(self, bookid, max_threads=4, interval=1):
  12.         self.bookid = bookid
  13.         self.max_threads = max_threads
  14.         self.interval = interval
  15.         self.work_queue = asyncio.Queue()
  16.         self.jwt_secret = "g0NnWdSE8qEjdMD8a1aq12qEYphwErKctvfd3IktWHWiOBpVsgkecur38aBRPn2w"
  17.         self.session = requests.session()
  18.         self.jwtkey = self.get_jwt_key()
  19.         self.timeoutlist = []
  20.         (self.bookname, self.totalpages) = self.bookinfo()
  21.         self.totalpages = int(self.totalpages)
  22.         self.creat_and_enter_book_dir()


  23.     def creat_and_enter_book_dir(self):
  24.         curpath = os.getcwd()
  25.         newpath = curpath + os.path.sep + self.bookname
  26.         os.mkdir(newpath)
  27.         os.chdir(newpath)
  28.             

  29.     def bookinfo(self):
  30.         url = f"https://lib-nuanxin.wqxuetang.com/v1/read/initread?bid={self.bookid}"
  31.         r = self.session.get(url)
  32.         info = json.loads(r.text)
  33.         data = info['data']
  34.         return data['name'], data['canreadpages']

  35.     def get_jwt_key(self):
  36.         url = "https://lib-nuanxin.wqxuetang.com/v1/read/k?bid=%s" % self.bookid
  37.         r = self.session.get(url, timeout=5)
  38.         j = json.loads(r.text)
  39.         return j['data']


  40.     def get_jwt_token(self, page):
  41.         cur_time = time.time()
  42.         jwttoken = jwt.encode({
  43.             "p": page,
  44.             "t": int(cur_time)*1000,
  45.             "b": str(self.bookid),
  46.             "w": 1000,
  47.             "k": json.dumps(self.jwtkey),
  48.             "iat": int(cur_time)
  49.         }, self.jwt_secret, algorithm='HS256').decode('ascii')
  50.         return jwttoken

  51.     async def download_img(self, page, task_id):
  52.         token = self.get_jwt_token(page)
  53.         url = f"https://lib-nuanxin.wqxuetang.com/page/img/{self.bookid}/{page}?k={token}"
  54.         headers = {
  55.             'referer': f'https://lib-nuanxin.wqxuetang.com/read/pdf/{self.bookid}',
  56.             'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'
  57.         }
  58.         try:
  59.             async with aiohttp.ClientSession() as session:
  60.                 async with session.get(url, headers=headers, timeout=5) as response:
  61.                     r = await response.read()
  62.         except Exception:
  63.             logging.warning(f"线程 {task_id} -> 第 {page} 张下载失败, 重回队列!!!")
  64.             self.work_queue.put_nowait(page)
  65.         else:
  66.             if len(r) == 10400:
  67.                 logging.warning(f"线程 {task_id} -> 第 {page} 张图片大小异常, 重回队列!!!")
  68.                 self.work_queue.put_nowait(page)
  69.             else:
  70.                 with open(f"{self.bookname+str(page)}.png", "wb") as f:
  71.                     f.write(r)
  72.                 logging.info(f"线程 {task_id} -> 第 {page} 张下载完成")


  73.     async def handle_tasks(self, task_id):
  74.         while not self.work_queue.empty():
  75.             page = await self.work_queue.get()
  76.             await self.download_img(page, task_id)
  77.             await asyncio.sleep(self.interval)
  78.         logging.info(f"线程 {task_id} 结束工作!~")

  79.     def main(self):
  80.         [self.work_queue.put_nowait(page) for page in range(1, self.totalpages + 1)]
  81.         loop = asyncio.get_event_loop()
  82.         tasks = [self.handle_tasks(task_id) for task_id in range(self.max_threads)]
  83.         loop.run_until_complete(asyncio.wait(tasks))
  84.         loop.close()

  85. if __name__ == "__main__":
  86.     bookid = 3208566
  87.     # 默认书名为下载文件夹名
  88.     # 参数1:书号, 参数2:线程数, 参数3:下载时间间隔
  89.     w = Wqxuetang(bookid, 3, 1)
  90.     w.main()
最新回复 (12)
  • haierwx21410 21天前
    引用 2
    顶一顶,请问楼主,这个下载下来是图片么?还是pdf啊
  • 楼主 yjsx86 21天前
    引用 3
    haierwx21410 发表于 2020-2-2 22:10
    顶一顶,请问楼主,这个下载下来是图片么?还是pdf啊
    下载下来的图片 , 需要pdf的话自己合成吧
  • jxpal 21天前
    引用 4
    顶一下,顺便mark
  • 东南西北 21天前
    引用 5
    马克一下
  • 杜甫 21天前
    引用 6
    每年618买的书堆成山了都
  • vopcloud 21天前
    引用 7
    1. import requests
    2. import jwt
    3. import json
    4. import time
    5. import aiohttp
    6. import asyncio
    7. import os
    8. import logging
    9. import sys

    10. logging.basicConfig(level=logging.INFO)

    11. class Wqxuetang():

    12.     def __init__(self, bookid, max_threads=4):
    13.         self.bookid = bookid
    14.         self.max_threads = max_threads
    15.         self.work_queue = asyncio.Queue()
    16.         self.jwt_secret = "g0NnWdSE8qEjdMD8a1aq12qEYphwErKctvfd3IktWHWiOBpVsgkecur38aBRPn2w"
    17.         self.session = requests.session()
    18.         self.jwtkey = self.get_jwt_key()
    19.         self.timeoutlist = []
    20.         (self.bookname, self.totalpages) = self.bookinfo()
    21.         self.totalpages = int(self.totalpages)
    22.         self.creat_and_enter_book_dir()


    23.     def creat_and_enter_book_dir(self):
    24.         curpath = os.getcwd()
    25.         newpath = curpath + os.path.sep + self.bookname
    26.         os.mkdir(newpath)
    27.         os.chdir(newpath)


    28.     def bookinfo(self):
    29.         url = f"https://lib-nuanxin.wqxuetang.com/v1/read/initread?bid={self.bookid}"
    30.         r = self.session.get(url)
    31.         info = json.loads(r.text)
    32.         data = info['data']
    33.         return data['name'], data['canreadpages']

    34.     def get_jwt_key(self):
    35.         url = "https://lib-nuanxin.wqxuetang.com/v1/read/k?bid=%s" % self.bookid
    36.         r = self.session.get(url, timeout=5)
    37.         j = json.loads(r.text)
    38.         return j['data']


    39.     def get_jwt_token(self, page):
    40.         cur_time = time.time()
    41.         jwttoken = jwt.encode({
    42.             "p": page,
    43.             "t": int(cur_time)*1000,
    44.             "b": str(self.bookid),
    45.             "w": 1000,
    46.             "k": json.dumps(self.jwtkey),
    47.             "iat": int(cur_time)
    48.         }, self.jwt_secret, algorithm='HS256').decode('ascii')
    49.         return jwttoken

    50.     async def download_img(self, page, task_id):
    51.         token = self.get_jwt_token(page)
    52.         url = f"https://lib-nuanxin.wqxuetang.com/page/img/{self.bookid}/{page}?k={token}"
    53.         headers = {
    54.             'referer': f'https://lib-nuanxin.wqxuetang.com/read/pdf/{self.bookid}',
    55.             'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'
    56.         }
    57.         try:
    58.             async with aiohttp.ClientSession() as session:
    59.                 async with session.get(url, headers=headers, timeout=5) as response:
    60.                     r = await response.read()
    61.         except Exception:
    62.             logging.warning(f"线程 {task_id} -> 第 {page} 张下载失败, 重回队列!!!")
    63.             self.work_queue.put_nowait(page)
    64.         else:
    65.             if sys.getsizeof(r)==10433:
    66.                 self.work_queue.put_nowait(page)
    67.                 logging.warning(f"线程 {task_id} -> 第 {page} 张加载失败, 重回队列!!!")
    68.             else:
    69.                 with open(f"{self.bookname+str(page)}.png", "wb") as f:
    70.                     f.write(r)
    71.                 logging.info(f"线程 {task_id} -> 第 {page} 张下载完成")


    72.     async def handle_tasks(self, task_id):
    73.         while not self.work_queue.empty():
    74.             page = await self.work_queue.get()
    75.             await self.download_img(page, task_id)
    76.         logging.info(f"线程 {task_id} 结束工作!~")

    77.     def main(self):
    78.         [self.work_queue.put_nowait(page) for page in range(1, self.totalpages + 1)]
    79.         loop = asyncio.get_event_loop()
    80.         tasks = [self.handle_tasks(task_id) for task_id in range(self.max_threads)]
    81.         loop.run_until_complete(asyncio.wait(tasks))
    82.         loop.close()

    83. if __name__ == "__main__":
    84.     bookid = int(sys.argv[1])
    85.     # 参数1:书号, 参数2:线程数
    86.     # 默认书名为下载文件夹名
    87.     w = Wqxuetang(bookid, 4)
    88.     w.main()
    楼主,我发现好像有些下载下来的图片有问题,图片都显示加载中,但是这些下载异常的图片大小都一样,就简单粗暴加了个判断,不知楼主有没有啥好方法?
  • 楼主 yjsx86 21天前
    引用 8
    vopcloud 发表于 2020-2-2 22:46
    楼主,我发现好像有些下载下来的图片有问题,图片都显示加载中,但是这些下载异常的图片大小都一样,就简 ...
    给个bookid我试试
  • vopcloud 21天前
    引用 9
    yjsx86 发表于 2020-2-2 22:51
    给个bookid我试试
    3208566
  • 夏生啊 21天前
    引用 10
    mark一下,今天看了搞了一会,自己的token感觉有问题,出来的都是加载中
  • qingseyouran 21天前
    引用 11
    好像有加载限制,0.5秒左右下一张图,不然到后面就是显示在加载中,即使单线程也是这样的,我在程序中加个延时,将就着下几本吧
  • 楼主 yjsx86 21天前
    引用 12
    vopcloud 发表于 2020-2-2 23:37
    3208566
    是有这个情况, 似乎是连接次数到达某个量, 而时间少于莫个值 就会触发, 持续时间大概1分钟,
    之后会恢复。
    修改了下代码, 把图片大小为10400的重回队列
    然后可以设置下载时间间隔, 自己调试下
    这个应该没什么太好的办法 想下载的快 只能上代理ip池了
  • cliya 21天前
    引用 13
    怎么用 有使用教程吗
  • 游客
    14
返回