找回密码
 立即注册

扫一扫,访问微社区

QQ登录

只需一步,快速开始

查看: 4500|回复: 6

[代码与实例] 130行代码实现海贼王漫画下载

0

主题

0

帖子

0

积分

贫民

积分
0
Mr.Ogenki 发表于 2019-1-30 22:16:05 | 显示全部楼层 |阅读模式
本帖最后由 Mr.Ogenki 于 2019-2-2 23:30 编辑

给大家带来一点福利,但不是妹子图!不是妹子图!不是妹子图!
敲了130多行代码,利用协程实现漫画下载,亲测没问题,目前海贼王更新到930话,全部下载下来1小时左右,供大家参考,一起共勉。
代码烂了 大神别笑话我。
  1. from gevent import monkey;monkey.patch_all()
  2. from gevent.pool import Pool
  3. from bs4 import BeautifulSoup
  4. from fake_useragent import UserAgent
  5. from requests.packages.urllib3.exceptions import InsecureRequestWarning

  6. import gevent
  7. import requests
  8. import time
  9. import os
  10. import shutil


  11. def getSource(urls, headers, types):
  12.     try:
  13.         # 实例化UserAgent类
  14.         user_agent = UserAgent()
  15.         # 为头文件随机分配User-Agent
  16.         headers['User-Agent'] = user_agent.random
  17.         # 禁用安全请求警告
  18.         requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
  19.         # 实例化Session
  20.         request_session = requests.Session()
  21.         # 设置重连次数
  22.         request_session.mount('http://', requests.adapters.HTTPAdapter(max_retries=5))
  23.         request_session.mount('https://', requests.adapters.HTTPAdapter(max_retries=5))
  24.         # 执行请求
  25.         get_response = request_session.get(urls, headers=headers, verify=False, timeout=(10, 10))
  26.         # 关闭请求
  27.         request_session.close()
  28.         # 设置编码
  29.         get_response.encoding = 'UTF-8'
  30.         # 判断获取源码还是图片
  31.         if types == 'text':
  32.             get_response = get_response.text
  33.         if types == 'content':
  34.             get_response = get_response.content
  35.     except Exception as e:
  36.         print('getSource()函数异常:' + str(e))
  37.     else:
  38.         return get_response


  39. def sourceAnalysis(src, dic, typ):
  40.     # 定义章节链接、标题、内容列表
  41.     chapter_link = []
  42.     chapter_name = []
  43.     chapter_cont = []
  44.     # 实例化BeautifulSoup
  45.     soup = BeautifulSoup(src, 'html.parser')
  46.     # 解析章节链接和标题
  47.     if typ == 'chapter':
  48.         analysis_lists = soup.find_all(dic['label'], class_=dic['class'])
  49.         # 提取章节链接和标题
  50.         for i in range(len(analysis_lists)):
  51.             chapter_link.append(DOMAIN + analysis_lists[i].get('data-hreflink'))
  52.             chapter_name.append(analysis_lists[i].get_text().strip())
  53.         chapter_dic = {'chapter_link': chapter_link, 'chapter_name': chapter_name}
  54.         return chapter_dic
  55.     # 解析章节内图片链接
  56.     if typ == 'content':
  57.         analysis_lists = soup.find_all(dic['label'], class_=dic['class'])
  58.         # 提取章节内图片链接
  59.         for i in range(len(analysis_lists)):
  60.             chapter_cont.append(analysis_lists[i].get('data-src'))
  61.         return chapter_cont


  62. if __name__ == '__main__':
  63.     # 系统启动时间
  64.     start_time = time.time()

  65.     # 定义常量
  66.     DOMAIN = 'https://www.mkzhan.com/'
  67.     REQUEST_URL = 'https://www.mkzhan.com/209871/'
  68.     HEADERS = {'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
  69.                'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3',
  70.                'Connection': 'keep-alive',
  71.                'User-Agent': ''}
  72.     LINK_PROPERTY = {'label': 'a', 'class': 'j-chapter-link'}
  73.     IMAG_PROPERTY = {'label': 'img', 'class': 'lazy-read'}
  74.     POOL = Pool(100)
  75.     ROOT_PATH = "D:/OnePiece/"

  76.     # 创建存储漫画文件夹,如果已有文件夹,则删除再新建
  77.     if os.path.exists(ROOT_PATH):
  78.         shutil.rmtree(ROOT_PATH)
  79.     os.mkdir(ROOT_PATH)

  80.     # 获取目录页源码
  81.     function_run_time = time.time()
  82.     print(time.strftime('[%Y-%m-%d %H:%M:%S]', time.localtime()) + " 获取目录页源码开始...")
  83.     catalog_source = getSource(REQUEST_URL, HEADERS, 'text')
  84.     print(time.strftime('[%Y-%m-%d %H:%M:%S]', time.localtime()) + " 获取目录页源码完成...[ %.1fs ]" % (time.time() - function_run_time))

  85.     # 解析章节信息
  86.     function_run_time = time.time()
  87.     print(time.strftime('[%Y-%m-%d %H:%M:%S]', time.localtime()) + " 解析章节信息开始...")
  88.     chapter_info = sourceAnalysis(catalog_source, LINK_PROPERTY, 'chapter')
  89.     print(time.strftime('[%Y-%m-%d %H:%M:%S]', time.localtime()) + " 解析章节信息完成...[ %.1fs ]" % (time.time() - function_run_time))

  90.     # 获取每章节源码
  91.     function_run_time = time.time()
  92.     print(time.strftime('[%Y-%m-%d %H:%M:%S]', time.localtime()) + " 获取每章节源码开始...")
  93.     get_source_worker = [POOL.spawn(getSource, url, HEADERS, 'text') for url in chapter_info['chapter_link']]
  94.     gevent.joinall(get_source_worker)
  95.     chapter_source = [source.value for source in get_source_worker]
  96.     print(time.strftime('[%Y-%m-%d %H:%M:%S]', time.localtime()) + " 获取每章节源码完成...[ %.1fs ]" % (time.time() - function_run_time))

  97.     # 解析章节内图片链接
  98.     function_run_time = time.time()
  99.     print(time.strftime('[%Y-%m-%d %H:%M:%S]', time.localtime()) + " 解析章节内图片链接开始...")
  100.     get_imglink_worker = [POOL.spawn(sourceAnalysis, src, IMAG_PROPERTY, 'content') for src in chapter_source]
  101.     gevent.joinall(get_imglink_worker)
  102.     image_list = [link.value for link in get_imglink_worker]
  103.     print(time.strftime('[%Y-%m-%d %H:%M:%S]', time.localtime()) + " 解析章节内图片链接完成...[ %.1fs ]" % (time.time() - function_run_time))

  104.     # 下载漫画
  105.     for i in range(len(chapter_info['chapter_name'])):
  106.         function_run_time = time.time()
  107.         print(time.strftime('[%Y-%m-%d %H:%M:%S]', time.localtime()) + " 下载 " + chapter_info['chapter_name'][i] + " 开始...")
  108.         get_images_worker = [POOL.spawn(getSource, url, HEADERS, 'content') for url in image_list[i]]
  109.         gevent.joinall(get_images_worker)
  110.         # 创建章节文件夹
  111.         save_path = ROOT_PATH + chapter_info['chapter_name'][i] + '/'
  112.         os.mkdir(save_path)
  113.         for j in range(len(get_images_worker)):
  114.             with open(save_path + str(j) + '.jpg', 'wb') as image:
  115.                 image.write(get_images_worker[j].value)
  116.         print(time.strftime('[%Y-%m-%d %H:%M:%S]', time.localtime()) + " 下载 " + chapter_info['chapter_name'][i] + " 完成...[ %.1fs ]" % (time.time() - function_run_time))

  117.     print(time.strftime('[%Y-%m-%d %H:%M:%S]', time.localtime()) + ' System executing done...[ %.1fs ]' % (time.time() - start_time))
复制代码




1.png
回复

使用道具 举报

50

主题

1057

帖子

1108

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1108

活跃会员热心会员最佳导师默默耕耘突出贡献优秀版主荣誉管理论坛元老

blueelwang 发表于 2019-1-31 09:27:50 | 显示全部楼层
回复

使用道具 举报

0

主题

2

帖子

2

积分

贫民

积分
2
不会聪明 发表于 2019-2-2 10:49:32 | 显示全部楼层
您好,我的就不能啊,显示'NoneType' object has no attribute 'strip',请问什么原因呢
回复 支持 反对

使用道具 举报

0

主题

2

帖子

2

积分

贫民

积分
2
daodantou 发表于 2019-2-2 19:37:38 | 显示全部楼层

您好,我的就不能啊,显示'NoneType' object has no attribute 'strip',请问什么原因
回复 支持 反对

使用道具 举报

0

主题

0

帖子

0

积分

贫民

积分
0
Mr.Ogenki  楼主| 发表于 2019-2-2 23:26:01 | 显示全部楼层
不会聪明 发表于 2019-2-2 10:49
您好,我的就不能啊,显示'NoneType' object has no attribute 'strip',请问什么原因呢 ...

页面源码有些改动,估计是反爬虫。
chapter_name.append(analysis_lists.string.strip())改成chapter_name.append(analysis_lists.get_text().strip())即可,就是BeautifulSoup里面节点的问题
回复 支持 反对

使用道具 举报

0

主题

0

帖子

0

积分

贫民

积分
0
Mr.Ogenki  楼主| 发表于 2019-2-2 23:29:16 | 显示全部楼层
daodantou 发表于 2019-2-2 19:37
您好,我的就不能啊,显示'NoneType' object has no attribute 'strip',请问什么原因 ...

页面源码有些改动,估计是反爬虫。
chapter_name.append(analysis_lists.string.strip())改成chapter_name.append(analysis_lists.get_text().strip())即可,就是BeautifulSoup里面节点的问题
回复 支持 反对

使用道具 举报

0

主题

1

帖子

1

积分

贫民

积分
1
随风 发表于 2019-3-15 13:28:04 | 显示全部楼层

  File "C:/Users/Administrator/.spyder-py3/temp.py", line 10, in <module>
    from fake_useragent import UserAgent

ModuleNotFoundError: No module named 'fake_useragent'


这个模块怎么解决
回复 支持 反对

使用道具 举报

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

本版积分规则

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