coco漫画获取隐藏的图片链接
-
网站分析
打开目标网站:https://www.cocomanhua.com/, 随便打开一部漫画: https://www.cocomanhua.com/10330/1/205.html
F12 打开工具开始分析
先直接发送GET请求看是否可以拿到图片的下载链接
继续查看源代码, 找到突破口
最后得到一个名为mh_info 的json数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | mh_info = { startimg: 1, enc_code1: "aVp6aWlITE1XcGJmSllMd0Z2NFhIZz09" , mhid: "10330" , enc_code2: "dzNaUXJ5SXFUangvNFZDQzZPdjRFSGpsMEVyYzdtTFdNMUsyR2pXcHIzWVRuTGxqZlVYTkFwenhxWENDajVrYXlvS0ZOQkV1T0w3N0pDTDFneHhkblpobkwyWWx4ank3c0tCZ3ZDUk05c1k9" , mhname: "未婚爸爸" , pageid: 2823662, pagename: "二十几个壮汉" , pageurl: "1/205.html" , readmode: 3, maxpreload: 5, defaultminline: 1, domain: "img.cocomanhua.com" , manga_size: "" , default_price: 0, price: 0 }; |
然后又发现两个加密的东西enc_code1和enc_code2 ,到这里线索好像就断了没什么头绪那怎么办?我们再往下看看,有没有新的发现。
再打个断点调试一下看看,
两个字符串一模一样, 那么和mh_onfo联系起来了,好像有那么一点思路了。可以得到图片得地址就是:
1 | ' + mh_info[' domain '] + ' /comic/'+ __cdecrypt(_0xad15x7c, CryptoJS[__Oxa17db[0x4f]][__Oxa17db[0x52]][__Oxa17db[0x51]](mh_info[__Oxa17db[0x1c3]]).toString(CryptoJS[__Oxa17db[0x4f]].Utf8)) + 0001.jpg |
我们点击翻页, 看一下下一张图片得url链接:
1 | //img.cocomanhua.com/comic/10330/Z2hWczlBTFBwQzE2OW1hV2F3UW1LcnBrUzJiLzE2Wkw3YVdjc3FlOTZvYz0=/0002.jpg |
只有后面得0001.jpg 变成了 0002.jpg , 可以得到规律,下一张图片得链接就是变成0003.jpg
回头再看看刚才获得得mh_info 里面的数据只有一个stratimg,但是发现并不知道每一章节漫画你一共有多少张图片?
回到渲染好得页面看下, 找下突破口。
的到结论,总的图片页数就
1 2 3 4 5 | if ( typeof mh_info[__Ox97c0e[0x0]] == __Ox97c0e[0x1]) { totalImageCount = mh_info[__Ox97c0e[0x2]] } else { totalImageCount = parseInt(eval(base64[__Ox97c0e[0x4]](__Ox97c0e[0x3]))) } |
获取图片下载链接
整理一下思路就是 详情页---->获取C_DATA---->mh_info, 通过enc_code2 获取img_path, 通过enc_code1获取到totalImageCount
扒得到mh_info的代码
按照分析时候的套路扒到底后得到以下代码
1 2 3 4 5 6 7 8 | var __READKEY = 'fw12558899ertyui' ; var DECRIPT_DATA; try { DECRIPT_DATA = __cdecrypt(__READKEY, CryptoJS.enc.Base64.parse(C_DATA).toString(CryptoJS.enc.Utf8)); } catch (error) { DECRIPT_DATA = __cdecrypt( "JRUIFMVJDIWE569j" , CryptoJS.enc.Base64.parse(C_DATA).toString(CryptoJS.enc.Utf8)); } eval(DECRIPT_DATA); |
整理一下得到最后的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | var __READKEY = 'fw12558899ertyui' ; function __cdecrypt(key, word) { var key = CryptoJS.enc.Utf8.parse(key); var decrypt = CryptoJS.AES.decrypt(word, key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 }); return CryptoJS.enc.Utf8.stringify(decrypt).toString() }; function decode_data(C_DATA, key, default_key) { C_DATA = CryptoJS.enc.Base64.parse(C_DATA).toString( CryptoJS.enc.Utf8); try { C_DATA = __cdecrypt(key || __READKEY, C_DATA); } catch (e) { C_DATA = __cdecrypt( typeof default_key === 'string' ? default_key : "JRUIFMVJDIWE569j" , C_DATA); } return C_DATA; } var image_info = eval(decode_data(C_DATA)); |
安装一下node环境,运行看下结果
获取img_path
上面的函数整理一下大概的意思就是
1 | __cdecrypt( __READKEY,CryptoJS.enc.Base64.parse(enc_code2).toString(CryptoJS.enc.Utf8)) |
不难发现其实就是上面的decode_data函数, 所以最后就是
1 | decode_data(mh_info.enc_code2, "fw125gjdi9ertyui" , "" ) |
获取totalImageCount
1 2 3 4 5 6 7 8 | var __READKEY = 'fw12558899ertyui' ; var DECRIPT_DATA; try { DECRIPT_DATA = __cdecrypt(__READKEY, CryptoJS.enc.Base64.parse(mh_info.enc_code1).toString(CryptoJS.enc.Utf8)); } catch (error) { DECRIPT_DATA = __cdecrypt( "JRUIFMVJDIWE569j" , CryptoJS.enc.Base64.parse(mh_info.enc_code1).toString(CryptoJS.enc.Utf8)); } eval(DECRIPT_DATA); |
整理一下就是
1 | decode_data(mh_info.enc_code1) |
最后就是合成完整的图片路径
1 2 3 4 5 6 7 8 9 10 | var base_URL = 'https://www.cocomanhua.com/' var chapter_data = {} var chapter_image_base_path = base_URL.replace(/:\/\/.+/, '://' ) + mh_info.domain + "/comic/" + encodeURI(chapter_data .imgpath); chapter_data.image_list = []; for (; image_NO <= chapter_data.totalimg; image_NO++) { var image_url = chapter_image_base_path + (Array(4).join( "0" ) + image_NO).slice(-4) + ".jpg" ; mh_info.image_list.push(image_url); } |
完整运行一下代码看下结果
下载图片
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | # !/usr/bin/python3 # -*- coding: utf-8 -*- # Time : 2020/10/28 15:35 # Author : Amd794 # Email : 2952277346@qq.com # Github : https://github.com/Amd794 import re import execjs from threading_download_images import get_response class CoCoManHua( object ): @ staticmethod def _cocomanhua(detail_url): response = get_response(detail_url) data = re.findall( 'var C_DATA.*?\'(.*?)\'' , response.text)[ 0 ] ctx = execjs.get(). compile ( open ( '../js/_cocomanhua.js' , encoding = 'utf-8' ).read(), cwd = '../js/node_modules' ) images_url = ctx. eval (f 'getArr("{data}")' ) return images_url if __name__ = = '__main__' : print (CoCoManHua._cocomanhua( 'https://www.cocomanhua.com/11701/1/188.html' )) |
先运行下代码看下能不能得到链接
最后整合到主程序中运行看下效果
测试运行一下
在文章下方直接留言,请在备注中注明转载。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET开发智能桌面机器人:用.NET IoT库编写驱动控制两个屏幕
· 用纯.NET开发并制作一个智能桌面机器人:从.NET IoT入门开始
· 一个超经典 WinForm,WPF 卡死问题的终极反思
· ASP.NET Core - 日志记录系统(二)
· .NET 依赖注入中的 Captive Dependency
· 在外漂泊的这几年总结和感悟,展望未来
· 博客园 & 1Panel 联合终身会员上线
· 支付宝事故这事儿,凭什么又是程序员背锅?有没有可能是这样的...
· https证书一键自动续期,帮你解放90天限制
· 在 ASP.NET Core WebAPI如何实现版本控制?