相关文章推荐
无邪的八宝粥  ·  Caused by: ...·  11 月前    · 
python解析JS爬取漫画网站--动态爬虫

python解析JS爬取漫画网站--动态爬虫

我前两天无聊,鬼灭之刃第一季完结了,我暂时没啥动漫看,就想着看看鬼灭之刃的漫画,找了半天,找一个叫漫画堆的网站

网页版的还可以,但是我当时拿手机在看,翻一个页就是一个性感XX,在线发牌在下面晃。

晃的爷好烦a!

然后我就想着干脆爬取整个鬼灭之刃,自己慢慢看,省着看广告

虽然不难,但是这整个过程也没那么简单。

因为涉及到一点点字符串解密。

而且也比较闲,弄点技术相关的东西也总比发呆好

我把这个程序归到动态爬虫里,但是好像又不算动态爬虫,有点特殊。

BB is cheap,show me your code

代码如下:

#开始时间:2019年10月22日 16:07:40
#结束时间:2019年10月28日 08:47:33
#作者:DMaple
#功能:爬取漫画堆漫画-鬼灭之刃
#版本1.0
前提条件:需要在文件工程下添加那个下面的js文件。
断断续续写了一周,
涉及功能:
request 获取网页代码
json & execjs   python调用js代码
os 文件的读写
re 正则表达式的应用
import requests
import json
import time
import os
import re
import execjs
host='https://mhcdn.manhuazj.com/'
l_url = "https://www.manhuadui.com"
url = "https://www.manhuadui.com/manhua/guimiezhiren/"
headers = {  # 模拟浏览器访问网页
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36'}
response = requests.get(url=url, headers=headers)
def main():
    #获取章节地址
    list_source = dir()
    get_chapters(list_source)
功能:查找所有章节网址
返回值:字符串:包含每个章节的url以及章节名称
def dir():
    #正则,匹配章节url以及章节名称
    pattern = re.compile('href=\"\/manhua\/.+\.html.+title=.+\"')
    print("dir 正则过滤-----------------------------")
    print("正在查找该漫画所有章节的url以及名称")
    list_source=pattern.findall(response.text)
    #print(list_source)
    return list_source
功能:获得章节的url以及名称
心得:正则表达式的写法以及python正则表达式的使用
def get_chapters(list_source):
    #遍历所有章节的url
    i=0
    for chapter in list_source:
        #print(chapter)
        r_url = re.search('\/manhua\/.+\.html', chapter).group()
        # 章节url
        chapter_url = l_url + r_url
        print(chapter_url)
        chapter_name = re.search('title=\".+\" ', chapter).group()
        chapter_name = chapter_name[7:-2]
        print(chapter_name)
        #获取具体章节网页的静态代码
        res = requests.get(chapter_url, headers)
        chapter_image_list = get_js_chapterImage(res)
        chapter_path = get_chapter_Path(res)
        print("down_url:")
        chapter_root='gmzr//'+chapter_name
        count=1
        for chapter_image in chapter_image_list:
            down_url = host+chapter_path+chapter_image
            print(down_url)
            download_image(down_url,chapter_root,chapter_image,count)
            count+=1
        # 降低服务器压力,每爬取一个章节的所有图片,延时10秒
        # 每爬取5个章节,再延时20秒
        print('延时20秒')
        time.sleep(20)
        i += 1
        if (i % 5 == 0):
            print('延时60秒')
            time.sleep(20)
#这里从网页的script标签里,找数据,chapterImage被后台加密,放到script标签里
参数:章节url
ex:https://www.manhuadui.com/manhua/guimiezhiren/410940.html
返回值:章节所有图片的名称 [***.jpg]
返回值类型:list
def get_js_chapterImage(res):
    #print(res.text)
    #正则过滤数据
    chapter_image_code = re.search('chapterImages = \".+\";var chapterPath', res.text).group()
    chapter_image_code = re.search('\".+\"', chapter_image_code).group()
    print("chapter_image_code")
    print(chapter_image_code)
    chapter_image_code = chapter_image_code[1:-1]
    #解密章节图片乱码,还原成*.jpg格式
    chapter_Image_list = get_decryptImages(chapter_image_code)
    print("正在查询当前章节的所有图片")
    print(chapter_Image_list)
    return chapter_Image_list
def get_chapter_Path(res):
    chapter_path = re.search('chapterPath = \".+\";var chapterP', res.text).group()
    chapter_path = re.search('\".+\"', chapter_path).group()
    chapter_path = chapter_path[1:-1]
    #print(chapter_path)
    return chapter_path
def get_js():
    # f = open("D:/WorkSpace/MyWorkSpace/jsdemo/js/des_rsa.js",'r',encoding='UTF-8')
    f = open("decrypt20180904.js", 'r', encoding='UTF-8')
    line = f.readline()
    htmlstr = ''
    while line:
        htmlstr = htmlstr + line
        line = f.readline()
    #print(htmlstr)
    return htmlstr
def get_decryptImages(chapterImages):
    #获取解密js,进行解密
    js_str = get_js()
    ctx = execjs.compile(js_str)
    print(chapterImages)
    images =  ctx.call('decrypt20180904',chapterImages)
    #过滤数据:把字符串两边的符号["........."]过滤,以中间符号","进行切分
    images_list=str(images)[2:-2].split('","')
    return images_list
#下载图片
def download_image(url,chapter_root,image_name,count):
    root = 'D://ManHua//TEST//'  #给个目录
    root = root+chapter_root+'//'
    #url = 'https://mhcdn.manhuazj.com/images/comic/5/8412/1551394269327841209ad0db6d.jpg'
    path = root + str(count)+'页.jpg'
    print(path)
    try:
        if not os.path.exists(root):
            os.mkdir(root)
            # 判断根目录是否存在,os.madir()创建根目录
        if not os.path.exists(path):
            r = requests.get(url)
            # 判断文件是否存在,不存在将从get函数获取
            with open(path, 'wb')as f:
                # wb存为二进制文件
                f.write(r.content)
                # 将返回内容写入文件 r.content返回二进制形式
                f.close()
                print('文件保存成功')
        else:
            print('文件已经存在')
    except:
        print('爬取失败')
if __name__ == '__main__':
    main()


前提条件:需要在文件工程下添加decrypt20180904.js文件。像上图那样。

这个文件我做了一点小修改,是decrypt和crypto整合修改出来的

decrypt20180904改成这样,因为我们只要那个decryptedStr

function decrypt20180904(chapterImages) {
    var key = CryptoJS.enc.Utf8.parse("123456781234567G");  //十六位字符作为密钥
    var iv = CryptoJS.enc.Utf8.parse('ABCDEF1G34123412');