Python《成功破解简单的 动态加载 的爬虫》

今天我们来爬取一个漫画网站
在这里插入图片描述

这里由于漫画数量过于庞大,于是我就简单地爬取曾经小时候看过的漫画吧。
比如下面的五个漫画:
在这里插入图片描述

先来分析分析,拿《火影忍者》举例:
点击进去后可以看到所有的章节罗列。
在这里插入图片描述

嗯,这个没啥说的了,就是搜索出所有的< a>元素,找出其章节的标签,并且得到具体章节的链接,这个简单。

继续点击其中某个章节进去后发现,是存在多个页面的插画,共同组成一个章节,这个总体来说也不难,因为url很有规律,url是递增的,直到共X页面,且每一页只有一张图片,我们只需要跳转到每一页下载一张图就行,看着思路可还行。
http://comic.kkkkdm.com/comiclist/3/3/1.htm
http://comic.kkkkdm.com/comiclist/3/3/2.htm
http://comic.kkkkdm.com/comiclist/3/3/3.htm
一直到
http://comic.kkkkdm.com/comiclist/3/3/X.htm
在这里插入图片描述

结果,在获取Img的时候获取不到,始终是空的,是None值。
原因是这个img的元素是经过javascript脚本动态添加的,因此我们无法获得其img元素,但是我们也能看到具体嵌入的javascript脚本信息,这里面是产生img的代码,因此我们可以通过解析这个代码字符串的地址来获得具体图片的地址。
在这里插入图片描述

可是还是会遇到一个问题就是,这个字符串的地址信息包含一个变量,而且经过信息打印,发现一共包含多个不同名称的变量,那么这个变量值是多少呢?

由于它们是javascript的变量值,因此我们就在本页面找所有的javascript文件,从中去找。
终于在本页中找到了一个js文件如下:
在这里插入图片描述

打开后能看到
在这里插入图片描述

这下全部就清晰了,其实那么多变量的值都是指向了同一个地址。好了这下问题全部清楚了,
讲真的幸亏自己曾经大学时候自学过一些简单的HTML / CSS / JavaScript的知识,不然的话就无法完成漫画下载了。

我们来找一个图片来试试水。
在这里插入图片描述

测试代码如下:

Import requests

def run11():
    with open("D:/estimages/mn.jpg", "wb") as f :
        f.write(requests.get("https://v2.kukudm.com/kuku6comic6/200910/20091010/glgs/Vol_01/cccc.rar 00003A.jpg").content)
        f.close

if __name__ == "__main__":   #主程序入口
    run11()    #调用上面的run方法

在这里插入图片描述

效果还行,那么接下来我们上完整代码:

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

rootrurl = 'http://comic.kkkkdm.com'
server_url = 'https://v2.kukudm.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 saveOneCapCore(dir, img_url):
    img = requests.get(img_url)  # 请求图片的实际URL
    with open(
            '{}/{}'.format(dir, img.url.split("/")[-1]), 'wb') as jpg:  # 请求图片并写进去到本地文件
        jpg.write(img.content)
        print(img_url)


# 从 script 元素里面获得出图片的链接地址
def parseImgUrl(info):
    tmp = info.split('+')[2]
    return server_url + tmp[tmp.find('"') + 1: tmp.find("'")]


def saveOneCap(dir, href):
    # 找到共有多少页?
    html = BeautifulSoup(requests.get(href, headers=headers).text.encode('iso-8859-1').decode('gbk'),
                         features="html.parser")
    tbl = html.find_all('table')[1]
    info = tbl.find('td')
    totalPages = int(info.get_text().split('|')[1].strip()[1:-1])

    tmpurl = href[: href.find(href.split('/')[-1])]
    for i in range(1, (totalPages + 1)):
        url = '{}{}.htm'.format(tmpurl, i)
        print(url)
        html = BeautifulSoup(requests.get(url, headers=headers).text.encode('iso-8859-1').decode('gbk'),
                             features="html.parser")

        tbl = html.find_all('table')[1]
        info = tbl.find('td').find('script').string

        # saveOneCapCore(dir, html.find('img', {"id" : "comicpic"}).get('src'))  # 动态生成的,无法直接获得img的地址
        saveOneCapCore(dir, parseImgUrl(info))   # img的地址是动态生成,因此需要从javascript中解析出来


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, rootrurl + cap.get('href'))
    pass


def tagSpider(tag, url):
    # 解析当前页面
    html = BeautifulSoup(requests.get(url, headers=headers).text.encode('iso-8859-1').decode('gbk'),
                         features="html.parser")
    # 提交一个保存页面的任务
    saveOnePageFunc(tag, html.find('dl', {'id': 'comiclistn'}).find_all('a')[::4])

    print("thread work over. ")


if __name__ == '__main__':

    # 获得所有标签
    taglist = {'火影忍者': 'http://comic.kkkkdm.com/comiclist/3/',
               '犬夜叉': 'http://comic.kkkkdm.com/comiclist/833/',
               '灌篮高手': 'http://comic.kkkkdm.com/comiclist/34/',
               '网球王子': 'http://comic.kkkkdm.com/comiclist/720/',
               '通灵王': 'http://comic.kkkkdm.com/comiclist/163/'}

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

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

效果如下:
在这里插入图片描述

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值