基于Python实现ComicReaper漫画自动爬取脚本过程解析


Posted in Python onNovember 11, 2019

这篇文章主要介绍了基于Python实现ComicReaper漫画自动爬取脚本过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

讲真的, 手机看漫画翻页总是会手残碰到页面上的广告好吧...

要是能只需要指定一本漫画的主页URL就能给我返回整本漫画就好了...

这促使我产生了使用Python 3来实现, 做一个 ComicReaper(漫画收割者) 的想法!

本文所用漫画链接 : http://www.manhuadb.com/manhua/2317

总体流程

基于Python实现ComicReaper漫画自动爬取脚本过程解析

那就开始吧

做一些准备工作

先用字符串存储两个链接, 一个是本次漫画网站站点的域名URL, 另一个是当前我们要爬取的漫画的主页URL

再定义一个 header 字典, 用于存储我们的 User-Agent 和 Referer Referrer (由于早期HTTP规范的拼写错误, 为了保持向后兼容就将错就错了)

首部字段 User-Agent

首部字段 User-Agent 告诉服务器当前创建请求的浏览器是什么(有的网站会针对不同的浏览器提供不同的页面, 比如如果是手机浏览器提出的请求, 服务器就向客户端提供网站的手机版页面)

比如说同样是请求 GitHub 的主页, 左边是使用笔记本电脑上面的浏览器请求的页面, 右边是在安卓手机上请求的页面

基于Python实现ComicReaper漫画自动爬取脚本过程解析

首部字段 Referer

首部字段 Referer 告诉服务器当前请求的页面是从哪个Web页面发起的(一般情况下 Referer 字段用于防盗链)

有的网站不允许直接访问网站里面的URL, 只能通过从主页点击某个链接来进行跳转, 或者...我们在请求之前把 User-Agent 字段设置为主页或发起页即可

url_domainame = r'http://www.manhuadb.com'
url_host = r'http://www.manhuadb.com/manhua/2317'
header = {
  'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:70.0) Gecko/20100101 Firefox/70.0',
  'Referer' : ''
  }

获取章节目录

首先我们对我们接下来要做的事情做一个具体流程分析

我们要获取当前漫画所有章节的标题与URL(标题用于后期存储时文件夹的命名, URL用于跳转到当前章节的开始页面)并且存储在列表中

基于Python实现ComicReaper漫画自动爬取脚本过程解析

将会使用到Python的两个库, re 与 urllib

import re


 # 导入正则表达式
 import urllib.request  # 导入 urllib.request

对在浏览器中按下 [F12] 键打开开发者工具来对漫画的章节页面进行分析

基于Python实现ComicReaper漫画自动爬取脚本过程解析

我们可以看到页面中有很多章节, 也就是章节跳转链接, 每个链接的<a>标签中正好具有我们需要的标题和URL, 分别是<a>标签的 title 属性与 href 属性, 我们将使用字典来存储它

先不慌着前进, 考虑到整个HTML中有非常多的链接, 那么也就意味着页面中具有大量的<a>标签, 如果我们只是单纯地从HTML中过滤出<a>标签, 这样我们会得到大量我们并不需要的<a>标签, 这是不明智的, 我们必须只过滤出章节跳转链接的<a>标签, 仔细观察, 发现章节跳转链接的<a>标签们都具有一个特点, 那就是它们都具有 class 属性并且属性值为 "fixed-a-es" , 这就找到了一个可以定位章节<a>标签的依据, 把这一点加入到我们的正则表达式的匹配规则中去

现在就可以定义一个正则表达式匹配字符串了:

pat = r'<a class="fixed-a-es" href="(.*?)" rel="external nofollow" rel="external nofollow" title="(.*?)"'

为什么要这么写 :

  • 在Python中, 在字符串常量的开头加一个 'r' 表示本字符串中的 '\' 字符将不会用来作转义字符使用, 保留了它原本的含义, 也就是反斜杠字符
  • 在正则表达式中, '.' 字符用于匹配任何字符(当匹配时具有 're.S' 标志时此话成立, 否则只能匹配任意但除了 '\n' 以外的字符)
  • 在正则表达式中, '*' 字符用于描述它左边的匹配字符的出现次数为0次或若干次
  • 在正则表达式中, '(.*?)' 的组合用来表示一个贪婪匹配(并且会被捕捉到)

使用这个正则表达式, 就可以匹配到 title 属性与 href 属性的属性值中的双引号里面的内容了

具体实现是 chapterIndexReaper 函数, 主要用来"收割"当前漫画的所有章节并存储为字典列表

代码如下 :

#获取一本漫画的所有章节的目录
def chapterIndexReaper(url_host, header):
  # 定义一个临时字典, 用于临时存储一个章节的标题与url
  dic_temp = {
    'Title' : '',
    'Url' : ''
    }
  # 章节字典列表, 存储当前漫画的所有章节字典
  set_dic = []
  # 构建Request对象
  req = urllib.request.Request(url = url_host, headers = header)
  # 读取所请求的req并用utf-8编码来进行解码, 所得到的的字符串赋值给html
  html = urllib.request.urlopen(req).read().decode('utf-8')
  # 爬取漫画章节标题与url的正则表达式
  pat = r'<a class="fixed-a-es" href="(.*?)" rel="external nofollow" rel="external nofollow" title="(.*?)"'
  # 使用pat在html中进行进行匹配(re.S参数是为了让"."除了能够匹配本身规定的字符,
  # 另外也能匹配"\n"), 返回一个结果列表res
  res = re.findall(pat, html, re.S)
  for i in res:
    dic_temp['Title'] = i[1]
    dic_temp['Url'] = url_head + i[0]
    # 向当前的章节字典列表的后面追加新的章节, 注意, 此处要使用浅拷贝
    # (因为dic_temp是一个临时变量, 需要创建它的副本并追加到set_dic中去,
    # 否则当dic_temp刷新时set_dic中的元素会相应发生改变)
    set_dic.append(dic_temp.copy())
  return set_dic

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python安装Imaging报错:The _imaging C module is not installed问题解决方法
Aug 22 Python
Python通过matplotlib绘制动画简单实例
Dec 13 Python
Python实现识别手写数字 简易图片存储管理系统
Jan 29 Python
python编辑用户登入界面的实现代码
Jul 16 Python
python查看列的唯一值方法
Jul 17 Python
对python文件读写的缓冲行为详解
Feb 13 Python
详解python项目实战:模拟登陆CSDN
Apr 04 Python
Python3多线程版TCP端口扫描器
Aug 31 Python
Pytorch实现基于CharRNN的文本分类与生成示例
Jan 08 Python
解决pycharm编辑区显示yaml文件层级结构遇中文乱码问题
Apr 27 Python
Django+RestFramework API接口及接口文档并返回json数据操作
Jul 12 Python
python通配符之glob模块的使用详解
Apr 24 Python
Python多继承以及MRO顺序的使用
Nov 11 #Python
python 有效的括号的实现代码示例
Nov 11 #Python
Python+OpenCV实现实时眼动追踪的示例代码
Nov 11 #Python
python的pyecharts绘制各种图表详细(附代码)
Nov 11 #Python
python OpenCV GrabCut使用实例解析
Nov 11 #Python
Python上下文管理器用法及实例解析
Nov 11 #Python
Django 请求Request的具体使用方法
Nov 11 #Python
You might like
提升PHP性能的21种方法介绍
2013/06/25 PHP
THINKPHP2.0到3.0有哪些改进之处
2015/01/04 PHP
PHP自定义图片缩放函数实现等比例不失真缩放的方法
2016/08/19 PHP
laravel 判断查询数据库返回值的例子
2019/10/11 PHP
利用404错误页面实现UrlRewrite的实现代码
2008/08/20 Javascript
js控制的遮罩层实例介绍
2013/05/29 Javascript
js中如何把字符串转化为对象、数组示例代码
2013/07/17 Javascript
Jquery实现的角色左右选择特效
2014/05/21 Javascript
JS封装的自动创建表格的实现代码
2016/06/15 Javascript
JS留言功能的简单实现案例(推荐)
2016/06/23 Javascript
JS之获取样式的简单实现方法(推荐)
2016/09/13 Javascript
jQuery web 组件 后台日历价格、库存设置的代码
2016/10/14 Javascript
nodejs个人博客开发第六步 数据分页
2017/04/12 NodeJs
nodejs接入阿里大鱼短信验证码的方法
2017/07/10 NodeJs
nodejs动态创建二维码的方法
2017/08/12 NodeJs
关于react中组件通信的几种方式详解
2017/12/10 Javascript
jQuery实现滚动到底部时自动加载更多的方法示例
2018/02/18 jQuery
vue组件定义,全局、局部组件,配合模板及动态组件功能示例
2019/03/19 Javascript
vue实现多条件和模糊搜索功能
2019/05/28 Javascript
vue实现路由懒加载及组件懒加载的方式
2019/06/11 Javascript
JS判断数组四种实现方法详解
2020/06/29 Javascript
Vue和React有哪些区别
2020/09/12 Javascript
python代码编写计算器小程序
2020/03/30 Python
Python定时任务APScheduler的实例实例详解
2019/07/22 Python
关于python中plt.hist参数的使用详解
2019/11/28 Python
python中的错误如何查看
2020/07/08 Python
基于css3实现漂亮便签样式
2013/03/18 HTML / CSS
CSS3实现线性渐变用法示例代码详解
2020/08/07 HTML / CSS
移动web模拟客户端实现多方框输入密码效果【附代码】
2016/03/25 HTML / CSS
html5的pushstate以及监听浏览器返回事件的实现
2020/08/11 HTML / CSS
数百万免费的图形资源:Freepik
2020/09/21 全球购物
网络书店创业计划书
2014/02/07 职场文书
教师党员一句话承诺
2014/03/28 职场文书
班主任对学生的评语
2014/04/26 职场文书
电子专业自荐信
2014/07/01 职场文书
幼儿园开学温馨提示
2015/07/15 职场文书