原标题:运用Python多线程爬虫下载漫画

前言:

以前,我都是买漫画书看的,那个时候没有电脑。今天,我到网上看了一下,发现网上提供漫画看,但是时时需要网络啊!为什么不将它下载下来呢!

 1.怎样实现

这个项目需要的模块有:requests、urllib、threading、os、sys
其中requests模块也可以不用,只要urllib模块即可,但我觉得requests模块爬取数据代码量少。
os模块主要是为了创建文件夹,sys主要是为了结束程序(当然,这里我只是判断是否已经存在我即将创建的文件夹,如果存在,我就直接结束程序了,这个位于代码的开头)。

1.1 爬取我们需要的数据(网页链接、漫画名称、漫画章节名称)

我爬取漫画的网址为:https://www.mkzhan.com/

我们到搜索栏上输入 一个漫画名称

我输入的是:斗破苍穹,点击搜索,可以看到这个界面:

对这个网址进行分析:https://www.mkzhan.com/search/?keyword={}
大括号代表的内容就是我们输入的漫画名称,我们只要这样组合,就可以得到这个网址:

  1. from urllib import parse
  2.  
  3. _name=input('请输入你想看的漫画:')
  4. name_=parse.urlencode({'keyword':_name})
  5. url='https://www.mkzhan.com/search/?{}'.format(name_)

之后,就是对这个网址下面的内容进行爬取了,这个过程很容易,我就不讲了。
我们点击一下其中的一本漫画,来到这个界面

这个网址,需要我们从上一个网址中得到并进行拼接,我们需要得到这个网址下面的漫画所有章节的链接和名称。
我们按F12来到开发者工具:
可以发现这些章节的内容在这个标签下面:

  1. html1=requests.get(url=url1)
  2. content1=html1.text
  3. soup1=BeautifulSoup(content1,'lxml')
  4. str2=soup1.select('ul.chapter__list-box.clearfix.hide')[0]
  5. list2=str2.select('li>a')
  6. name1=[]
  7. href1=[]
  8. for str3 in list2:
  9. href1.append(str3['data-hreflink']) # 漫画一章的链接
  10. name1.append(str3.get_text().strip()) # 漫画一章的题目,去空格

这样我们就可以得到我们想要的内容了,我们点击其中的一章进入,发现里面只不过是一些图片罢了,我们只需把这些图片下载下来就行了。

代码运行结果:

下载完成之后,会在同一个文件夹下面多出一个文件夹,文件夹的名称为你输入漫画名称,这个文件夹下面会有很多文件夹,这些文件夹的名称是漫画章节的名称。

 2.完整代码:

  1. import requests
  2. from urllib import parse
  3. from bs4 import BeautifulSoup
  4. import threading
  5. import os
  6. import sys
  7.  
  8. _name=input('请输入你想看的漫画:')
  9.  
  10. try:
  11. os.mkdir('./{}'.format(_name))
  12. except:
  13. print('已经存在相同的文件夹了,程序无法在继续进行!')
  14. sys.exit()
  15.  
  16. name_=parse.urlencode({'keyword':_name})
  17. url='https://www.mkzhan.com/search/?{}'.format(name_)
  18. html=requests.get(url=url)
  19. content=html.text
  20. soup=BeautifulSoup(content,'lxml')
  21. list1=soup.select('div.common-comic-item')
  22. names=[]
  23. hrefs=[]
  24. keywords=[]
  25. for str1 in list1:
  26. names.append(str1.select('p.comic__title>a')[0].get_text()) # 匹配到的漫画名称
  27. hrefs.append(str1.select('p.comic__title>a')[0]['href']) # 漫画的网址
  28. keywords.append(str1.select('p.comic-feature')[0].get_text()) # 漫画的主题
  29. print('匹配到的结果如下:')
  30. for i in range(len(names)):
  31. print('【{}】-{} {}'.format(i+1,names[i],keywords[i]))
  32.  
  33. i=int(input('请输入你想看的漫画序号:'))
  34. print('你选择的是{}'.format(names[i-1]))
  35.  
  36. url1='https://www.mkzhan.com'+hrefs[i-1] # 漫画的链接
  37. html1=requests.get(url=url1)
  38. content1=html1.text
  39. soup1=BeautifulSoup(content1,'lxml')
  40. str2=soup1.select('ul.chapter__list-box.clearfix.hide')[0]
  41. list2=str2.select('li>a')
  42. name1=[]
  43. href1=[]
  44. for str3 in list2:
  45. href1.append(str3['data-hreflink']) # 漫画一章的链接
  46. name1.append(str3.get_text().strip()) # 漫画一章的题目,去空格
  47.  
  48. def Downlad(href1,path):
  49. headers = {
  50. 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3756.400 QQBrowser/10.5.4039.400'}
  51. url2='https://www.mkzhan.com'+href1
  52. html2=requests.get(url=url2,headers=headers)
  53. content2=html2.text
  54. soup2=BeautifulSoup(content2,'lxml')
  55. list_1=soup2.select('div.rd-article__pic.hide>img.lazy-read') # 漫画一章中的所有内容列表
  56. urls=[]
  57. for str_1 in list_1:
  58. urls.append(str_1['data-src'])
  59.  
  60. for i in range(len(urls)):
  61. url=urls[i]
  62. content3=requests.get(url=url,headers=headers)
  63. with open(file=path+'/{}.jpg'.format(i+1),mode='wb') as f:
  64. f.write(content3.content)
  65. return True
  66.  
  67. def Main_Downlad(href1:list,name1:list):
  68. while True:
  69. if len(href1)==0:
  70. break
  71. href=href1.pop()
  72. name=name1.pop()
  73. try:
  74. path='./{}/{}'.format(_name,name)
  75. os.mkdir(path=path)
  76. if Downlad(href, path):
  77. print('线程{}正在下载章节{}'.format(threading.current_thread().getName(),name))
  78. except:
  79. pass
  80.  
  81. threading_1=[]
  82. for i in range(30):
  83. threading1=threading.Thread(target=Main_Downlad,args=(href1,name1,))
  84. threading1.start()
  85. threading_1.append(threading1)
  86. for i in threading_1:
  87. i.join()
  88. print('当前线程为{}'.format(threading.current_thread().getName()))

3.总结

我觉得这个程序还有很大的改进空间,如做一个ip代理池,这样再也不用担心ip被封了,另外,还可以做一个自动播放漫画图片的程序,这样就可以减少一些麻烦了。
注意:本程序代码仅供娱乐和学习,且莫用于商业活动,一经发现,概不负责。
如果大家觉得这个还可以的话,记得给我点一个小小的赞。

过去,我买漫画看;现在,我用Python爬虫来看的更多相关文章

  1. 《奥威Power-BI案例应用:带着漫画看报告》腾讯课程开课啦

    元旦小假期过去了,不管是每天只给自己两次下床机会的你,还是唱K看电影逛街样样都嗨的你,是时候重振旗鼓,重新上路了!毕竟为了不给国家的平均工资水平拖后腿,还是要努力工作的.话说2016年已经过去了,什么 ...

  2. 小白学 Python 爬虫(26):为啥上海二手房你都买不起

    人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...

  3. 面试前赶紧看了5道Python Web面试题,Python面试题No17

    目录 本面试题题库,由公号:非本科程序员 整理发布 第1题: Flask中的请求上下文和应用上下文是什么? 第2题:django中间件的使用? 第3题: django开发中数据做过什么优化? 第4题: ...

  4. python爬虫08 | 你的第二个爬虫,要过年了,爬取豆瓣最受欢迎的250部电影慢慢看

    马上就要过年啦 过年在家干啥咧 准备好被七大姑八大姨轮番「轰炸」了没? 你的内心 os 是这样的 但实际上你是这样的 应付完之后 闲暇时刻不妨看看电影 接下来咱们就来爬取豆瓣上评分最高的 250部电影 ...

  5. 看完100篇Python技术精华文章,平均涨薪30%!

    一个以技术为立身根基的教育机构做出来的微信号,干货程度会有多高? 马哥Linux运维公众号运营五年,从一开始的定位就是给技术人分享加薪干货的地方.这五年里,公众号运营最重的任务就是做内容.内容并不好做 ...

  6. 菜鸟版JAVA设计模式—从买房子看代理模式

    今天学习了代理模式. 相对于适配器模式,或者说装饰器模式,代理模式理解起来更加简单. 代理这个词应该比較好理解,取代去做就是代理. 比方,我们买卖房子,那么我们会找中介,我要卖房子,可是我们没有时间去 ...

  7. 为了给女朋友买件心怡内衣,我用Python爬虫了天猫内衣售卖数据

    真爱,请置顶或星标 大家好,希望各位能怀着正直.严谨.专业的心态观看这篇文章.ヾ(๑╹◡╹)ノ" 接下来我们尝试用 Python 抓取天猫内衣销售数据,并分析得到中国女性普遍的罩杯数据.最受 ...

  8. Python爬虫---爬取腾讯动漫全站漫画

    目录 操作环境 网页分析 明确目标 提取漫画地址 提取漫画章节地址 提取漫画图片 编写代码 导入需要的模块 获取漫画地址 提取漫画的内容页 提取章节名 获取漫画源网页代码 下载漫画图片 下载结果 完整 ...

  9. 大概看了一天python request源码。写下python requests库发送 get,post请求大概过程。

    python requests库发送请求时,比如get请求,大概过程. 一.发起get请求过程:调用requests.get(url,**kwargs)-->request('get', url ...

随机推荐

  1. linux学习之路第三天

    开机,重启和用户登陆注销 关机&重启命令 shutdown shutdown -h now :表示立即关机 shutdown -h 1 :表示一分钟后关机 shutdown -r now :表 ...

  2. css--filter(滤镜) 属性

    前言 前段时间找工作面试官问到一个问题,你如何将一个网页整体置灰?面试遇到这样的问题,一下束手无策,之前没有接触过这样的需求,因此没有回答上来,面试结束我才知道了这是考查对 CSS3 的新属性的了解. ...

  3. linux驱动之LED驱动

    通过之前的学习,了解到linux驱动编写的流程是:先通过注册函数注册我们编写的入口函数,然后在入口函数中获取设备号->注册字符设备->自动创建设备节点->获取设备树信息,最后通过销毁 ...

  4. asp.net c# 保存图片到sql2008

    //图像数据表:tx//字段id (nvarchar(50) ,image(image)//tgav为图片ID,实质为上传前的主名 (省略了.jpg)private void kkkkk(byte[] ...

  5. Python之抖音快手代码舞--字符舞

    先上效果,视频敬上: 字符舞: 代码舞 源代码: video_2_code_video.py 1 import argparse 2 import os 3 import cv2 4 import s ...

  6. Leetcode12. 整数转罗马数字Leetcode18. 四数之和

    > 简洁易懂讲清原理,讲不清你来打我~ 输入整数,输出对应的罗马字符串![在这里插入图片描述](https://img-blog.csdnimg.cn/54b001c62a0d4d348c962 ...

  7. Beam Search快速理解及代码解析(下)

    Beam Search的问题 先解释一下什么要对Beam Search进行改进.因为Beam Search虽然比贪心强了不少,但还是会生成出空洞.重复.前后矛盾的文本.如果你有文本生成经验,一定对这些 ...

  8. mysql实现主从复制、读写分离的配置方法(二)

    由于接触主从复制,读写分离的时间比较短,应用还不够熟练,目的是能通过MyCat实现基础的读写分离操作. 其核心功能是分库分表,配合数据库的主从模式还可实现读写分离. 1. 测试环境 一台win10主机 ...

  9. vue3 自学(一)基础知识学习和搭建一个脚手架

    两年前曾自学过几天vue,那时候版本还是vue2,但后来项目中一直没用到,当时也觉得学习成本太高,便没有继续学习下去.初学者可以看下链接文章以前的吐槽~~ 学习 Vue ,从入门到放弃 最近部门决定升 ...

  10. 第4天 JavaDoc生成文档&Java流程控制(第一节:用户交互Scanner)

    JavaDoc生成文档 javadoc命令是用来生成自己的API文档 参数信息: @author 作者名 @version 版本号 @since 指明需要最早使用的jdk版本 @param 参数名 @ ...