今天就先挑战另外个动态加载的漫画网站,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)
效果如下: