Python《突破JS动态加载,成功爬取漫画》

今天就先挑战另外个动态加载的漫画网站,dmzj

漫画太多了,我们先挑选几个漫画下载试一试。
在这里插入图片描述

比如我们点击第一部漫画,进去后看看。
在这里插入图片描述

这里有很多章节,获得所有的章节这里不难。
接下来我们点击一个章节进去看看
在这里插入图片描述

我们看到了地址栏url后面有一些page的编号,如果我们换个编号就能跳到对应的页卡,而且我们在点击下一页和上一页的时候,页面没有刷新,这就是说明img的地址是全部存在于当前页面的,我们得去在本html内找到所有的img。

按F12后可以发现,这里存在所有的IMG地址
在这里插入图片描述
在这里插入图片描述

而且我们通过request在代码中是不能获得这俩元素的,说明这俩元素是动态生成的。这就是动态加载了。

我们把这一章节的所有img的url罗列下来,做个分析,毕竟是一个章节的,按道理img的url是有规律的啊,我们看到url是主要有三个数字组成,比如:
https://images.dmzj.com/img/chapterpic/1247/25304/14492330112801.jpg

这三个数字来自哪里?我们可以在所有的js文件和script里面搜索下,看看数字在哪里有存在即可,终于在一个script里面发现了猫腻啊。
在这里插入图片描述

这个是script是可以通过request获得的,对应关系如下:
我们把该script块和页卡选择框的元素放在一起去对照对照,如下取了第30章节和第29章节的内容:
在这里插入图片描述
在这里插入图片描述

因此我门需要的所有的url信息都是在这script的字符串里面可以去得到的呢。
我不想去追究这个逆天的字符串的顺序问题了,做个简单的吧(具体看code)。

完整代码如下:

# coding: utf-8
from concurrent.futures import ThreadPoolExecutor
import time
import os
import requests
from bs4 import BeautifulSoup

rootrurl = 'https://www.dmzj.com'
save_dir = 'D:/estimages/'

headers = {
    "Referer": rootrurl,
    'User-Agent': "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36",
    'Accept-Language': 'en-US,en;q=0.8',
    'Cache-Control': 'max-age=0',
    'Connection': 'keep-alive'
}  ###设置请求的头部,伪装成浏览器



def saveOneImg(dir, p1, p2, p3):
    img_url = 'https://images.dmzj.com/img/chapterpic/{}/{}/{}.jpg'.format(p1, p2, p3)
    new_headers = {
        "Referer": img_url,
        'User-Agent': "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36",
        'Accept-Language': 'en-US,en;q=0.8',
        'Cache-Control': 'max-age=0',
        'Connection': 'keep-alive'
    }  ###设置请求的头部,伪装成浏览器,实时换成新的 header 是为了防止403 http code问题,防止反盗链,

    try:
        img = requests.get(img_url, headers=new_headers)  # 请求图片的实际URL
        if (str(img).find('200') > 1):
            with open(
                    '{}/{}.jpg'.format(dir, img.url.split("/")[-1].split('.')[0].ljust(14, '0')), 'wb') as jpg:  # 请求图片并写进去到本地文件
                jpg.write(img.content)
                print(img_url)
                jpg.close()
            return True
        else:
            return False
    except Exception as e:
        print('exception occurs: ' + img_url)
        print(e)
        raise e

def getIms(p):
    strlist = str(p).split('|')
    dirlist = []
    imgslist = []
    for item in strlist:
        if item.isdigit():
            dirlist.append(item)
            if len(item) > 10:
                imgslist.append(item)
    dirlist = dirlist[:2]
    return dirlist, imgslist


def saveOneCap(dir, href):
    print(href)
    html = BeautifulSoup(requests.get(href, headers=headers).text, features="html.parser")
    dirlist, imgslist = getIms(html.find('script'))
    print(dirlist)
    print(imgslist)

    for jpg in imgslist:
        while 1:
            try:
                if saveOneImg(dir, dirlist[0], dirlist[1], jpg):  # first try
                    break
                saveOneImg(dir, dirlist[1], dirlist[0], jpg)  # try again if failed
                break
            except Exception as e:
                continue  # try again if occurs error




def saveOnePageFunc(dir, capters):
    for cap in capters:
        # 按照tag和图片组的内容来创建目录
        new_dir = '{}{}/{}'.format(save_dir, dir, cap.get_text())
        if not os.path.exists(new_dir):
            os.makedirs(new_dir)

        saveOneCap(new_dir, cap.get('href'))
        time.sleep(2)
    pass


def tagSpider(tag, url):
    # 解析当前页面
    html = BeautifulSoup(requests.get(url, headers=headers).text, features="html.parser")

    # 提交一个保存页面的任务
    saveOnePageFunc(tag, html.find('ul', {'class': 'list_con_li autoHeight'}).find_all('a'))

    print("thread work over. ")


if __name__ == '__main__':

    # 获得所有标签
    taglist = {'川灵物语': 'https://www.dmzj.com/info/chuanlingwuyu.html',
               '魔王与勇者与圣剑神殿': 'https://www.dmzj.com/info/mwyyzysjsd.html',
               '真励之徒弟': 'https://www.dmzj.com/info/zhenlizhitu.html',
               '妖神记': 'https://www.dmzj.com/info/yaoshenji.html'}

    # 给每个标签配备一个线程
    with ThreadPoolExecutor(max_workers=10) as t:  # 创建一个最大容纳数量为20的线程池
        for tag, url in taglist.items():
            t.submit(tagSpider, tag, url)

    # 单个连接测试下下
    # tagSpider('川灵物语', 'https://www.dmzj.com/info/chuanlingwuyu.html')

    # 等待所有线程都完成。
    while 1:
        print('-------------------')
        time.sleep(1)

效果如下:
请添加图片描述

请添加图片描述
请添加图片描述

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值