Python动态网页爬虫-----动态网页真实地址破解原理

1.目标网站

本次爬虫爬取的是漫画网站,目标网站是动态加载漫画图片,加密传输漫画真实地址,使用缓存技术加快访问加载速度,同时使用网络图片压缩降低数据传输量。
目标网址:在这里插入图片描述
没错,本次要挑战的就是搜索第四名的网站。
为什么选择这个网站?
第一个需要花钱才能看,破解太难。
第二个打开太慢。
第三个有访问验证。
第四个访问地址加密,总体较为容易破解。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.目标网站行为分析

首先这个漫画网站会监听大多数的按键与鼠标事件,所以,如果漫画正文的相关的js文件加载后就无法使用浏览器的一些工具。
在这里插入图片描述
所以需要提前打开工具,然后访问目标漫画网站。
在这里插入图片描述

3.目标文件依赖加载分析

首先使用PostMan访问漫画正文网站,获取网站的静态代码:
在这里插入图片描述

<!DOCTYPE html><html lang="zh-cn"><head><meta http-equiv=Content-Type content="text/html; charset=UTF-8"><title>逆天邪神预告 逆天邪神漫画预告 漫画台</title><meta name="keywords" content="逆天邪神预告,逆天邪神漫画预告" /><meta name="description" content="漫画台是为您提供逆天邪神预告、逆天邪神漫画预告免费阅读,本站是更新逆天邪神漫画最快的网站。" /><meta http-equiv="Cache-Control" content="no-siteapp" /><meta http-equiv="Cache-Control" content="no-transform" /><meta name="applicable-device" content="pc"/><link rel="alternate" media="only screen and(max-width:640px)" href="//m.manhuatai.com/nitianxieshen/yg.html" ><meta name="mobile-agent" content="format=html5;url=//m.manhuatai.com" /><meta http-equiv="imagetoolbar" content="no"><meta name="renderer" content="webkit"><link rel="prefetch prerender" href="1.html" /><script type="text/javascript">window.gobal_info={comic_id: 106518,site_id: "manhuatai"};</script><script src="/springcss/style.js?20190507115118" type="text/javascript" charset="utf-8"></script><!--[if lt IE 8]>  <script src="/static/json2.js"></script><![endif]--><script src="//static.321mh.com/js/comic.read.min.js?20190507115118" type="text/javascript" charset="utf-8"></script><link rel="shortcut icon" href="/favicon.ico" /></head><body><div class="mh_nav"><div class="mh_wrap"><div class="bdsharebuttonbox bdshare"><a class="bds_more" data-cmd="more"></a><a class="bds_count" data-cmd="count"></a></div><p>将逆天邪神漫画分享给朋友:</p>当前位置:<a href="/" title="漫画台">漫画台</a> &gt; <a href="./" title="逆天邪神">逆天邪神</a> &gt; <a href="yg.html" title="逆天邪神预告">逆天邪神预告</a></div></div><div class="mh_wrap tc"><div class="mh_readtitle"><h1><strong>逆天邪神预告</strong></h1><p class="readtip"><span class="tip">热键:</span> 鼠标左右键/AD键/方向键翻页,+-键缩放图片,0键恢复,V键回顶部,F11全屏</p><a href="./" title="逆天邪神漫画" class="l mh_btn">返回目录</a><a href="/" title="漫画台" class="r mh_btn">返回首页</a></div><div class="ggwarp"><div class="ggbox"><div class="w300"><script>__ad.readpage1a()</script></div><div class="w300"><script>__ad.readpage1b()</script></div><div class="w300"><script>__ad.readpage1c()</script></div></div></div><div class="mh_headpager"><a href="javascript:alert('已经是第一章了')" class="mh_prevbook mh_btn">上一章</a><select class="mh_select"></select><select class="mh_readmode"></select><a href="javascript:" target="_self" hidefocus="true" class="mh_bgcolor mh_btn"></a><a tabindex="-1" href="1.html" title="逆天邪神漫画第1话 两世为人" class="mh_nextbook mh_btn">下一章</a></div><div class="ggwarp"><div class="ggbox"><script>__ad.readpage2()</script></div></div></div><div class="mh_comiclist tc" id="comiclist"><script src="/springjs/j.js" type="text/javascript"></script><script>var mh_info={imgpath:"P\'4H\'G;\':2\':8\'G7\'C6\'C;\'G;\':4\'CC\'G9\'C7\';G\'4H\'G;\'C4\':6\'G7\';3\':C\'4H",startimg:1,totalimg:14,mhid:"nitianxieshen",mhname:"逆天邪神",pageid:1549702,pagename:"预告",pageurl:"yg",readmode:1,maxpreload:5,defaultminline:1,domain:"cnmanhua.com",comic_size:"-mht.middle",default_price:0,price:0,time_diff:20552898915,image_suffix:"jpg"};var cnzz_comic = ["_trackEvent","逆天邪神","mht_"+(isMobile?"wap":"pc"),"",0];_czc = [["_setAccount", "1261814609"]];_czc.push(cnzz_comic);  /* 图片加载时cnzz事件统计 */</script><script>__cr.init();</script><div class="ggwarp"><div class="ggbox"><div class="lxad"><script>__ad.readpage_lxad(0)</script></div><div class="lxad"><script>__ad.readpage_lxad(1)</script></div><div class="lxad"><script>__ad.readpage_lxad(2)</script></div><div class="lxad"><script>__ad.readpage_lxad(3)</script></div></div></div></div><div class="mh_wrap tc"><style>.mh_btn{color:#fff !important;}.mh_btn:hover{color:#fff !important;}.mh_btn:visited{color:#fff !important;}.mh_btn:active{color:#fff !important;}.mh_btn:focus{color:#fff !important;}</style><div class="mh_readend"><div class="km-chapter-end-container" style="position: relative;"></div>[ <a href="yg.html" title="逆天邪神预告">逆天邪神预告</a> ] 已阅读完毕,您还可以:<ul><li><a href="javascript:alert('已经是第一章了')"><strong>阅读上一章节</strong>已经是第一章了</a></li><li><a href="./" title="逆天邪神漫画"><strong>返回漫画目录</strong>逆天邪神漫画</a></li><li><a href="1.html" title="逆天邪神漫画第1话 两世为人"><strong>阅读下一章节</strong>第1话 两世为人</a></li></ul><div class="endtip2 clear">漫画台是更新<a href="./" title="逆天邪神漫画">逆天邪神漫画</a>最快的网站,喜欢<a href="./" title="逆天邪神">逆天邪神</a>就请将本站推荐给朋友</div></div><div class="ggwarp"><div class="ggbox"><script>__ad.readpage3()</script><script>__ad.readpage4()</script></div></div><div class="mh_footpager"><span class="mh_prevpage mh_btn">上一页</span><select class="mh_select"></select><select class="mh_readmode"></select><span class="mh_nextpage mh_btn">下一页</span></div><div class="ggwarp"><div class="ggbox"><div><script>__ad.readpage5()</script></div><div class="w300"><script>__ad.readpage5a()</script></div><div class="w300"><script>__ad.readpage5b()</script></div><div class="w300"><script>__ad.readpage5c()</script></div></div></div></div><script>__ad.allfloat();window._bd_share_config={"common":{"bdText":"逆天邪神漫画预告真是太精彩了,快来漫画台看看吧","bdMini":1,"bdPic":$(".mh_comiclist img:eq(0)").attr("src")},"share":{},"image":{}};if($(".bdsharebuttonbox").length && !window.isMobile) __ad.loadjs("//share.321mh.com/static/api/js/share.js",{async:true});//window.baiduImageTalk = {'token': 'aw5xeyctodvb'};//__ad.loadjs("http://bcscdn.baidu.com/public03/imageplus/tuhua/common_loader.js?cache="+(new Date()/36e5),{async:true});setTimeout(function(){$.get($("link[rel^='prefetch']").attr("href"))},5000);//5秒后预加载下一页</script><div class="mh_foot tc"><p><span class="tip">小提示:</span> 按 Ctrl+D 键可将《<strong>逆天邪神预告</strong>》加入收藏夹,下次阅读更方便!</p><div class="commend">好看的漫画推荐:<a href="/wdjszcwhq/" title="我的绝色总裁未婚妻">我的绝色总裁未婚妻</a><a href="/wmshijie/" title="完美世界">完美世界</a><a href="/tjcqzcfrxxt/" title="天价宠妻总裁夫人休想逃">天价宠妻总裁夫人休想逃</a><a href="/aoshijiuzhongtian/" title="傲世九重天">傲世九重天</a><a href="/nitianxieshen/" title="逆天邪神">逆天邪神</a><a href="/taotieji/" title="饕餮">饕餮</a><a href="/shenyidinv/" title="神医嫡女">神医嫡女</a><a href="/xianni/" title="仙逆">仙逆</a><a href="/yaoshenji/" title="妖神记">妖神记</a><a href="/doupocangqiong/" title="斗破苍穹">斗破苍穹</a><a href="/dldl3lwcs/" title="龙王传说">龙王传说</a><a href="/fayikuangfei/" title="法医狂妃">法医狂妃</a><a href="/wszz/" title="武神主宰">武神主宰</a><a href="/zhetian/" title="遮天">遮天</a></div><div class="copyright">Copyright &copy; 2019 ManHuaTai.Com&nbsp;<a href="//www.manhuatai.com">漫画台</a> &nbsp;川网文(2018)4025-124号 &nbsp;<a rel="nofollow" href="http://www.miitbeian.gov.cn">蜀ICP备17035423号-10</a>&nbsp;成都二次元动漫有限公司&nbsp;<a href="//static.321mh.com/html/contact/contact.html?type=mht" rel="nofollow" target="_blank">联系我们</a>  <p><a href="mailto:kefu@xiaomingtaiji.com" rel="nofollow" target="_blank">客服邮箱:kefu@xiaomingtaiji.com</a>  </p></div><script>__ad.footer()</script></div><script type="text/javascript">/* if(typeof __ad==="undefined") $("body").html("系统核心代码加载失败,这可能是由于浏览器广告过滤功能误屏蔽了网站功能代码,请在浏览器设置中关闭广告过滤后再刷新页面!"); */__comic = {"漫画名称":"逆天邪神","漫画ID":"106518","刊载媒体":"二次元动漫","产品名称":"漫画台","产品平台":isMobile?"手机网站":"电脑网站","页面名称":location.pathname.indexOf(".htm")?"阅读页":"目录页"};</script><script src="https://hm.baidu.com/hm.js?b6562a5f33e0f71fa4de1e0c66e08af6"></script><script src="https://vvip.cnzz.com/stat.php?id=1254059479&web_id=1254059479&show=none" language="JavaScript"></script><script src="https://vvip.cnzz.com/stat.php?id=1261814609&web_id=1261814609&show=none" language="JavaScript"></script><!--页面缓存于 2019-05-10 19:52:43,2次SQL查询,耗时31ms--></body></html>

接下来使用idea格式化查看html代码:
在这里插入图片描述
使用工具查看当我们访问漫画正文时,静态代码会引入哪些js,以及哪些css或者是ajax:
在这里插入图片描述
在这里插入图片描述
这就是访问静态的html代码时,访问的加载的依赖文件。
其中yg.html就是我们用postMan获取的html代码。
style.js?..从名字上就能看出是加载css样式的代码。
在这里插入图片描述
让这个网页动起来的就是
在这里插入图片描述
文件。
这个文件是一段js代码,我们也使用idea格式化分析。
在这里插入图片描述
代码太长,就不贴了。
剩下的文件稍微看下就知道是一些统计用的代码,对我们破解没什么用处。

4.静态网页分析

对静态网页的html分析:
我们可以得到漫画的章节名字:

在这里插入图片描述
通过对元素的检查与HTML的分析:

在这里插入图片描述
在这里插入图片描述
可以得到下一章的相对地址,为什么是相对地址?
在这里插入图片描述
在这里插入图片描述
前面部分都相同。
然后会在HTML代码中获取到最重要的一个信息:
在这里插入图片描述
这个信息包含了一整个章节的所有信息。

首先分析这个json的属性:
imgpath漫画图片的地址(地址的一部分,无法直接访问)
totalimg本章节漫画图片的个数
mhid这个就是网站首页的二级地址(先存疑,后面有详细说明)
pagename章节名字
pageurl章节地址(地址的一部分,无法直接访问)
maxpreload缓存图片数量
comic_size图片真实地址的一部分
在这里插入图片描述
image_suffix图片的后缀(没什么用)

这个对象很重要。
https://www.manhuatai.com/nitianxieshen/yg.html
这个是某一页的地址
在这里插入图片描述
https://www.manhuatai.com/nitianxieshen/1.html
在这里插入图片描述
这是第二章节的地址。
https://www.manhuatai.com/nitianxieshen/yg.html
https://www.manhuatai.com/nitianxieshen/1.html
前面部分完全相同:
https://www.manhuatai.com
访问这个地址在这里插入图片描述
就是网站的首页地址
然后是/nitianxieshen这个字符
很明显,这个就是json对象中的mhid,通过名字分析,这个mhid应该是网站里面区分不同的漫画的唯一标识,如果两个漫画的名字拼音相同,就无法区分了,需要增加附加字符。
所以现在大概的思路也就有了:
首先输入第一张漫画图片的正文的网址,然后解析出漫画下一章的地址;
然后把下一章的漫画的地址作为输入,解析出第三章的地址。
这样爬虫就动起来了,目前能获取到所有章节的第一张图片的地址了。

5.动态加载代码分析

说实话,这个动态加载的js代码有630行,一开始直接看确实很闷的。
所以我们想个比较简单的办法:
在这里插入图片描述
js的最后是一个document的对象的写的方法,那而且这一行代码特别的长有5299个字符,这尼玛,真长。
仔细的看下,这不就是我们拿到的html代码吗?
只不过这里用js生成的,我们把双引号去掉。
然后格式化:
在这里插入图片描述
发现只是样式,没用。。。。苦恼,继续看js代码。
在这里插入图片描述
发现有一个__cr的对象,这个对象有好多的方法。
那么我们就大概看下这个对象有些什么方法(只看方法名猜,先不要看具体的方法实现)
在这里插入图片描述
搜索查看:
在这里插入图片描述
有这么一句,和真实地址有关系啊:
在这里插入图片描述
进入这个方法查看:
在这里插入图片描述
在这里插入图片描述
这不就是一些js的代码吗,虽然没学过前端什么语言,但是根据js和jquery大概能看懂这两行,大概就是创建一个img标签,src地址就是在这里插入图片描述
继续进入这个方法:
在这里插入图片描述
在这个方法中看到了一个熟悉的名字:
mh_info,这个不就是我们获取的从HTML代码中得到的json对象吗?
我们需要的应该是n
为什么呢?
在这里插入图片描述
还记得这个地址吗?
https://mhpic.manhualang.com/comic/N%2F逆天邪神%2F预告%2F1.jpg-mht.middle.webp
和代码中拼接的结果差不多,对照分析大概可以猜出来了:
n=
https
+
//mhpic.manhualang.com/comic/
+
%%%%%%%%%
+
.jpg
+
-mht.middle
+
.webp
我们可以认为前两个是固定的:
https://mhpic.manhualang.com/comic/
后面三个也是固定的:
.jpg-mht.middle.webp
接下来发现如果按照上述规则得到的地址无法访问
https://mhpic.manhualang.com/comic/P’4H’G;’:2’:8’G7’C6’C;‘G;’:4’CC’G9’C7’;G’4H’G;‘C4’:6’G7’;3’:C’4H.jpg-mht.middle.webp

说实话,我在HTML代码和js代码中没有找到图片地址解析的代码,但是多看几个图片,验证上述规则大概就能找到规律:
在这里插入图片描述
发现图片的真实地址中加密的部分解密后第一个字符总是大写的N这个字符,那么为什么是这个字符呢?
这个字符有什么特殊吗?
所有的漫画都是这个字符吗?
我们换个漫画看下
在这里插入图片描述
我很机智的发现了解密的方式:
迁移法。
加密方法–迁移法

什么是迁移法?
就是我把明文按照顺序移动一定的位置,然后把移动后的字符作为密文。
比如:
明文:1314
标志位第一位
密文:
6869

怎么解密呢?
第一位作为约定的解密标识位,没有任何其他的含义:
所以
6 - 1 = 5 :flag
8 - flag = 3
6 - flag = 1
9 - flag = 4
这样就解密成功了。

回归正题:
作为本漫画网站的加密手段,没想到被我们就这样破解了(但是大家千万不要做违法的事情,或者以损害目标网站的利益获利,毕竟这个网站不收费,可以免费看,而且速度还不错。所以请勿做坏事。)
验证一下:
https://mhpic.manhualang.com/comic/P’4H’G;’:2’:8’G7’C6’C;‘G;’:4’CC’G9’C7’;G’4H’G;‘C4’:6’G7’;3’:C’4H.jpg-mht.middle.webp
随便写段代码解密:

def getImagePath(mh_info, refStr):
    if mh_info:
        base = 'https://mhpic.manhualang.com/comic/'
        aim = mh_info['imgpath']
        flag = ord(refStr) - ord(aim[0])
        one_result = ''
        result =[]
        for one_char in aim:
            one_result += chr(ord(one_char) + flag)
        one_result = base + one_result
        for n in range(1, mh_info['totalimg']):
            result.append(one_result + str(n) + '.' + mh_info['image_suffix'] + mh_info['comic_size'] + '.webp')
        return result

发现还是不能访问。
既然不能访问,那么就回去继续看js代码:
在这里插入图片描述
通过这里分析:
n=
https
+
//mhpic.manhualang.com/comic/
+
%%%%%%%%%
+
页码
+
.jpg
+
-mht.middle
+
.webp
页码放在解密后的地址后面。
验证下:
在这里插入图片描述
在这里插入图片描述
与猜想一致。

6.万事俱备

现在我们爬虫的框架大概就很清晰了:

首先通过输入的url获取下一章,从HTML中得到mh_info,从mh_info中得到nextImagePath,解密图片地址,下载图片,大功告成。

但是高兴的太早了,尝试下载一张图片发现图片的格式不正确,是webp的格式,这个格式只能使用浏览器打开,是一种有损压缩的网络传输格式,所以还需要对图片进行转码。

现在整理一下爬虫的设计:

目标网站:漫画网站

输入:第一张漫画的url地址

解密标识

输出:以文件夹分割的章节名的漫画

1.根据输入的url获取html
2.根据html获取mh_info字典
3.根据html获取下一章
4.根据mh_info构造本章漫画地址列表
5.根据列表下载漫画到文件夹(文件夹名字是mh_info中的章节名字)
6.图片转码:webp->jpg
7.使用多线程(最好)

获取下一章地址:
从mh_info中提取mh_id
其中mh_id就是下一张的二级地址
然后从mh_info中提取pageUrl
然后加入当前页的序号
后面加入.html后缀
这就是下一章的地址

获取本章页数:
从mh_info中提取totalimg

获取本章的章节名字:
从mh_info中获取pagename

图片的地址:
Q(5I(H<(;3(;9(H8(D7(D<(H<(;5(DD(H:(D8(<H(5I93(H;(DI(<GJT(5I
N%2F%E9%80%86%E5%A4%A9%E9%82%AA%E7%A5%9E%2F60%E8%AF%9DGQ%2F 1
Q 81 N 78 -3
( 40 % 37 -3
5 53 2 50 -3

加密解密方法之迁移法

7.只欠东风

现在想法都有了,可行性也分析完毕了,完全可行,遇到的技术难题都解决了,可以实现了。
既然Python的模块化比较强大,可惜我之前学习java,刚接触Python,不太了解Python的一些正常写法,只能参考java的写法:
一个文件一个方法。
项目结构
在这里插入图片描述
在这里插入图片描述
其中GetHtmlUtil是其他工程的文件

7.1获取html代码

import requests


def getHtml(url):
    header = {
        'Accept': "*/*",
        'accept-encoding': "gzip, deflate",
        'Connection': "keep-alive",
        'Accept-Language' : 'zh-CN,zh;q=0.9',
        'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'
    }
    if url is not None and url.strip() != '':
        response = requests.request('GET', url = url.strip(), headers = header, timeout = 60)
        response.encoding = 'utf-8'
        return response.text

7.2获取mh_info

from demjson import decode
import re


def getMhInfo(soup):
    par = re.compile('var mh_info=\{.*?\}')
    script = re.search(par, str(soup))
    if script:
        par = re.compile(r'\{.*')
        script = re.search(par, script.group())
        return decode(str(script.group()))

7.3获取下一章的地址

def getNextZhangUrl(soup, mh_info):
    baseTag = soup.select("div[class='copyright'] > a:first-child")
    if len(baseTag):
        baseTag = baseTag.pop()
        nextTag = soup.select("a[class='mh_nextbook mh_btn']")
        for oneTag in nextTag:
            return 'https:' + baseTag['href'] + '/' + mh_info['mhid'] + '/' + oneTag['href']

7.4获取图片的真实地址

def getImagePath(mh_info, refStr):
    if mh_info:
        base = 'https://mhpic.manhualang.com/comic/'
        aim = mh_info['imgpath']
        flag = ord(refStr) - ord(aim[0])
        one_result = ''
        result =[]
        for one_char in aim:
            one_result += chr(ord(one_char) + flag)
        one_result = base + one_result
        for n in range(1, mh_info['totalimg']):
            result.append(one_result + str(n) + '.' + mh_info['image_suffix'] + mh_info['comic_size'] + '.webp')
        return result

7.5多线程

import threading
import os
from GetWebObj import getWebObj
from Webp2Jpg import webp2Jpg


class downloadZhang(threading.Thread):
    def __init__(self, imgurl):
        threading.Thread.__init__(self)
        self.imgurl = imgurl

    def run(self):
        for key, value in self.imgurl.items():
            if not os.path.exists(key):
                os.mkdir(key)
            flag = 0
            for i in value:
                iph = key + '\\' + str(flag) + '.webp'
                webObj = getWebObj(i)
                iFile = open(iph, 'wb')
                iFile.write(webObj.content)
                iFile.close()
                webp2Jpg(iph)
                flag += 1
                print(key[key.rfind('\\') + 1 : len(key)] + '\t' + str(flag) + '\t页下载完成')

7.6图片下载

import requests
import time


def getWebObj(url):
    header = {
        'Accept': "*/*",
        'accept-encoding': "gzip, deflate",
        'Connection': "keep-alive",
        'Accept-Language' : 'zh-CN,zh;q=0.9',
        'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'
    }
    if url is not None and url.strip() != '':
        flag = 0
        while flag < 20:
            try:
                return requests.request('GET', url = url.strip(), headers = header, timeout = 60)
            except:
                if flag < 20 :
                    time.sleep(2)
                    flag += 1
                    continue
                else:
                    print(url)
                    return None

7.7图片转码

from PIL import Image
import os


def webp2Jpg(sourceFile):
    image = Image.open(sourceFile)
    image.load()
    image.save(sourceFile.replace('.webp', '.jpg'), 'JPEG')
    os.remove(sourceFile)

7.8主程序

from GetImagePath import getImagePath
from GetMhInfo import getMhInfo
from bs4 import BeautifulSoup
from GetHtmlUtil import getHtml
from GetNextZhangUrl import getNextZhangUrl
from DownloadZhang import downloadZhang
import queue

zhangUrl = queue.Queue()
print('Please input first url:')
zhangUrl.put(input())
print('Please input save path:')
savePath = input()
print('Please input reference:')
refStr = input()
while not zhangUrl.empty():
    url = zhangUrl.get()
    try:
        html = getHtml(url)
    except:
        zhangUrl.put(url)
        continue
    soup = BeautifulSoup(html, 'html.parser')
    mh_info = getMhInfo(soup)
    zhangUrl.put(getNextZhangUrl(soup, mh_info))
    imgPath = getImagePath(mh_info, refStr)
    try:
        zhangPath = savePath + '\\' + mh_info['pagename']
    except:
        print(mh_info)
        continue
    if mh_info['pagename'].__eq__(str('你愿意为梦想付费吗')):
        continue
    downloadThrea = downloadZhang({zhangPath : imgPath})
    downloadThrea.start()

8.实现结果

验证漫画:

在这里插入图片描述
1.首先使用浏览器的f12获取此本漫画的图片地址解密标识字符:
在这里插入图片描述
N
2.在文件管理器中创建一个保存的目录:
在这里插入图片描述
3.拷贝地址启动程序:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
因为是多线程,所以下载顺序完全是乱的
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
发现最后一章少了一张图片,去网站看下,发现少的这一张图片是
在这里插入图片描述
是广告页,不要也罢。

9.总结

总体来说,破解这个网站还是相当有挑战性的,而且是利用下班业余时间做的,所以思维非常的不连贯,需要及时的做好记录,不仅仅是代码记录,思维记录同样重要。
而且最好先设计好在开始实现,否则做一半发现无法实现,也是非常的打击人,而且浪费时间。
Python给我的感觉是库非常的强大,但是动态语言嘛,有一个通病,或许不是问题,只是使用Java习惯了,一时没有适应,就是调用方法的时候,提示信息比较缺乏。
而且Python是动态强类型语言,静态是无类型的,导致写代码时,有时不知道对象是什么类型,只能通过调试确定实际的类型,这对于大型或者中型项目来说是一个非常不友好的。或许可以用强制类型转换解决,但是总觉得不好。这点我自己没有测试,只是猜想。
多线程是处理大量任务的不二选择。
此项目一开始是单线程完成的,下载这个漫画平均需要15分钟左右,大量的时间都被单线程的获取html连接,或者下载图片的连接阻塞。
后来发现对于每一章节可以使用多线程,完全独立的,可以大量的节省时间,使用多线程下载此本漫画只需要不到3分钟。
最后提醒一点,对于此网站不支持每张图片使用多线程,因为使用阿里云的缓存技术,每次缓存5张图片,所以如果对于每张图片使用多线程,会造成第五张之后的图片无法获取。
此项目还有一个缺陷,就是如果下载图片发生连接问题,会自动重试20次。
在这里插入图片描述

且没有提示,容易造成bug。

声明:
此文章只可用作学习交流使用,请勿用于任何商业用途,发生法律纠纷,本人不负任何责任。
如果目标漫画网站认为此文章造成侵权,请联系删除,对此发生的任何损失,本人不承担任何责任。

请各位看官不要使用本文章做任何有损他人利益的事情,谢谢。
感谢目标网站提供的漫画欣赏服务,本人破解无任何恶意,只是个人学习交流,请理解。
下载的漫画图片请24小时内删除,不可用作任何商业用途。

github地址:
https://github.com/a18792721831/StudyPython.git

  • 6
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值