Python 爬取漫画以及JS解析

漫画屋 - 爬取所有漫画(js解析-只要有就能获取)

JS解析网站大体流程(自我感觉一般都是这个流程)

  1. 网站踩点 ----- 先去查看这个网站数据加载的一种方式或者说网站加载的流程
  2. 接口分析 ----- 找到数据接口分析出必要的加密参数
  3. 加密算法 ----- 通过加密的参数找到加密算法的JS代码
  4. 伪造请求 ----- JS简单的话可以翻译成python代码,如果复杂可以使用nodejs、execjs等去进行调用
  5. 获取数据 ----- 可以进一步的进行数据清洗以及后期扩展

1. 解析网站

要进行爬取的网站:http://www.dm5.com/manhua-list-p1/
在这里插入图片描述

  1. 我们先看看全部漫画,它的漫画封面 漫画名字是怎么请求的以及翻页
    在这里插入图片描述

  2. 既然找到漫画封面加载方式那么就点开一个漫画看看,这种连载章名是可以直接获取出来的
    在这里插入图片描述

  3. 那就打开章节漫画看看里面的漫画是如何加载的
    在这里插入图片描述

在这里插入图片描述

  1. 但多点击几页发现一直会请求这两个数据包 每一个都返回了这个eval函数, 这一点有些不同
    在这里插入图片描述
  2. 把这段js代码放到控制台 此时我们就找到了这个图片的URL存储地址
    在这里插入图片描述
  3. 既然找到了图片的加载方式,那就看看它是怎么进行获取的
    在这里插入图片描述

在这里插入图片描述
7. 那我们继续搜索DM5_VIEWSIGN这个参数最后发现这个参数是在源码中 既然这个参数在源码中那么其他的参数也应该是在源码中了 现在我们找到了所有的参数那么我们就可以进行伪造请求获取数据了
在这里插入图片描述

2. 代码实现

代码分析流程:获取漫画名字以及漫画详情的URL并创建漫画文件夹 ----- 获取漫画详情章节并创建章节文件夹 ----- 获取图片URL取出js代码片段 ----- 调用js代码获取图片链接 ----- 进行下载保存漫画图片

使用模块:os、re、execjs、requests、BeautifulSoup

import os
import re

import execjs
import requests
from bs4 import BeautifulSoup as bs


HOST = 'http://www.dm5.com'
ROOT = '漫画'


def safe_string(str):
    """去除特殊符号"""
    return re.sub('[:,.\'@#$%……¥&*~`]', '_', str)

def get_index():
    """获取所有漫画的URL"""
    page = 1
    while 1:
        headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36"}
        api_url = 'http://www.dm5.com/dm5.ashx?'
        data = {
            'pagesize': 68,
            'pageindex': page,
            'tagid': 0,
            'areaid': 0,
            'status': 0,
            'usergroup': 0,
            'pay': -1,
            'char': '',
            'sort': 10,
            'action': 'getclasscomics'
        }
        response = requests.post(api_url, data, headers=headers)
        reult = response.json()
        Update_items = reult['UpdateComicItems']
        if not Update_items:
            pass
        for x in Update_items:
            comic_name = x['Title']
            comic_url = HOST +'/' + x['UrlKey']
            try:
                detail_comic(comic_name, comic_url)
            except Exception as e:
                print(comic_name, '>章节调整中')

        page += 1

def detail_comic(comic_name, comic_url):
    """获取漫画章节"""
    _path_one = os.sep.join([ROOT, safe_string(comic_name)])
    if not os.path.exists(_path_one):
        os.makedirs(_path_one)
    print(f'漫画:<{comic_name}> 正在下载中')
    response = requests.get(comic_url)
    dom = bs(response.text, 'lxml')
    div = dom('div', id='chapterlistload')[0]
    li_list = div.ul('li')
    for li in li_list:
        chapter_url = HOST + li.a['href']
        chapter_name = re.sub('[ ]', '', li.text)
        # print(chapter_url, chapter_name)
        try:
            parse_chapter(chapter_url, chapter_name, _path_one)
        except Exception as e:
            print(f"章节<{chapter_name}>下载错误,{e}")

def parse_chapter(chapter_url, chapter_name, _path_one):
    """解析漫画"""
    _path_two = os.sep.join([_path_one, chapter_name])
    if not os.path.exists(_path_two):
        os.makedirs(_path_two)
    # 获取漫画的必要参数
    response = requests.get(chapter_url)
    text = response.text
    cid = re.findall('var DM5_CID=(.*?);', text)[0].strip()
    mid = re.findall('var DM5_MID=(.*?);', text)[0].strip()
    dt = re.findall('var DM5_VIEWSIGN_DT="(.*?)";', text)[0].strip()
    sign = re.findall('var DM5_VIEWSIGN="(.*?)";', text)[0].strip()
    page_count = int(re.findall('var DM5_IMAGE_COUNT=(.*?);', text)[0].strip())
    # print(cid, mid, dt, sign, page_count)
    page = 1
    while page <= page_count:
        js_api = f'{chapter_url}chapterfun.ashx?cid={cid}&page={page}&key=&language=1&gtk=6&_cid={cid}&_mid={mid}&_dt={dt}&_sign={sign}'
        headers = {
            'referer': HOST
        }
        ret = requests.get(js_api, headers=headers)
        js_code = ret.text
        print(js_code)
        image_url = execjs.eval(js_code)
        img_url = image_url[0]
        img_name = chapter_name + str(page)
        try:
            download_image(img_url, img_name, _path_two)
        except Exception as e:
            print(f'章节<{chapter_name}>图片{img_name}下载失败:{e}')
        page += 1

def download_image(img_url, img_name, _path_two):
    """下载漫画图片"""
    save_path = os.sep.join([_path_two, img_name])
    if os.path.exists(save_path):
        return
    response = requests.get(img_url)
    with open(save_path+'.jpg', 'wb') as f:
        f.write(response.content)
        print(f'{img_name}, 下载成功')

if __name__ == '__main__':
    get_index()

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值