本文中的js有两段,都是用来批量下载p站图片的。模式一是从某一张图开始一直下载到画师最后一张图,模式二是在列表页中下载本页中所有的图。
第一个模式的使用场景很好理解,第二个模式在下载按tag筛选后的列表时特别有用,也可以用来单独下载画师作品列表中某一页的图片。
所有作品的所有大图都可以下载到,包括图集中的每一张图。动态图将会下载压缩包。
原理是使用iframe依次加载每个图片详情页,并获取大图下载下来。每个详情页完全加载完成之后(因为使用的是onload方法)才会下载图片,然后加载另一张图片的详情页。下载完所需要的时间会视每个人的网络情况而有所不同。
请务必使用chrome浏览器执行。IE和FF不支持a标签的download属性,所以无法使用本代码中的方法建立下载。
熟悉了下window对象的使用,在对窗口直接设置属性和添加事件时使用窗口的变量名,在使用窗口的document元素时需要使用窗口的name。
很多人反映说下载建立之后都任务失败,经过测试,发现和chrome版本有关。我以前用的是V39,没升级,代码可以用。昨天升到44就不能用了。于是跑到虚拟机里测试,用低版本chrome可以成功。
低版本chrome:
高版本:
具体原因不太明确,有一点猜测。不升级浏览器是不太现实的,不过可以用OX163网络图片下载器下载。
下面是模式一的代码,正确使用姿势是打开画师第一张图片的详情页面,然后在控制台执行以下代码。
//创建iframe
function createIframe () {
newFrame=document.createElement("iframe");
newFrame.name="myNewFrame";
newFrame.id="myNewFrame";
newFrame.width=0;
newFrame.height=0;
document.body.appendChild(newFrame);
}
createIframe();
//创建iframe2,这个用来打开图集页面
function createIframe2 () {
newFrame2=document.createElement("iframe");
newFrame2.name="myNewFrame2";
newFrame2.id="myNewFrame2";
newFrame2.width=0;
newFrame2.height=0;
document.body.appendChild(newFrame2);
}
createIframe2();
//创建顶级窗口中的单图下载链接
function getBigPic () {
bigPicHrefLink=document.createElement("a");
bigPicHrefLink.href=bigPicHref;
bigPicHrefLink.download=null;
document.body.appendChild(bigPicHrefLink);
bigPicHrefLink.click();
}
//创建iframe里面的单图下载链接
function getBigPic2 () {
bigPicHrefLink=document.createElement("a");
bigPicHrefLink.href=bigPicHref;
bigPicHrefLink.download=null;
window.myNewFrame.document.body.appendChild(bigPicHrefLink);
bigPicHrefLink.click();
}
//获取下一张图片
function getNextPic () {
clearInterval(t);
//如果iframe里面还有下一张图片
if (!!window.myNewFrame.document.getElementsByClassName("after")[0].getElementsByTagName("a")[0]) {
newFrame.src=window.myNewFrame.document.getElementsByClassName("after")[0].getElementsByTagName("a")[0].href;
newFrame.onload=function () {
if (!!window.myNewFrame.document.getElementsByClassName("original-image")[0]) {//如果是单图
bigPicHref=window.myNewFrame.document.getElementsByClassName("original-image")[0].getAttribute("data-src");//获取大图url
getBigPic2();
}else if (!!window.myNewFrame.document.getElementsByClassName("works_display")[0]) {
//如果是多图
if (!!window.myNewFrame.document.getElementsByTagName("canvas")[0]) {//如果是动图
bigPicHref=window.myNewFrame.pixiv.context.ugokuIllustFullscreenData.src;
getBigPic2();
}else{//如果是多图,在第二个iframe中打开图集的详情页
newFrame2.src=window.myNewFrame.document.getElementsByClassName("works_display")[0].getElementsByTagName("a")[0].href;
newFrame2.onload=function () {
tujiUrl=[];//存储图集中每个图的url
for (ii = 0; ii < window.myNewFrame2.document.getElementsByClassName("ui-scroll-view").length; ii++) {
tujiUrl[ii]=window.myNewFrame2.document.getElementsByClassName("ui-scroll-view")[ii].getAttribute("data-src");
bigPicHrefLink3=window.myNewFrame2.document.createElement("a");
bigPicHrefLink3.href=tujiUrl[ii];
bigPicHrefLink3.download=null;
window.myNewFrame2.document.body.appendChild(bigPicHrefLink3);
bigPicHrefLink3.click();
};
}
}
};
t=setInterval(getNextPic, 500);
}
if (!window.myNewFrame.document.getElementsByClassName("after")[0].getElementsByTagName("a")[0]) {//如果没有下一张则取消
clearInterval(t);
return;
};
};
}
//获取当前图片,在顶层窗口中
if (!!document.getElementsByClassName("original-image")[0]) {//如果是单图
bigPicHref=document.getElementsByClassName("original-image")[0].getAttribute("data-src");//获取大图url
getBigPic();
}else if(!!document.getElementsByClassName("works_display")[0]){
//如果是多图
if (!!document.getElementsByTagName("canvas")[0]) {//如果是动图
bigPicHref=pixiv.context.ugokuIllustFullscreenData.src;
getBigPic();
}else{//如果是多图,在第二个iframe中打开图集的详情页
newFrame2.src=document.getElementsByClassName("works_display")[0].getElementsByTagName("a")[0].href;
newFrame2.onload=function () {
tujiUrl=[];//存储图集中每个图的url
for (ii = 0; ii < window.myNewFrame2.document.getElementsByClassName("ui-scroll-view").length; ii++) {
tujiUrl[ii]=window.myNewFrame2.document.getElementsByClassName("ui-scroll-view")[ii].getAttribute("data-src");
bigPicHrefLink3=document.createElement("a");
bigPicHrefLink3.href=tujiUrl[ii];
bigPicHrefLink3.download=null;
window.myNewFrame2.document.body.appendChild(bigPicHrefLink3);
bigPicHrefLink3.click();
};
}
}
};
//如果顶层窗口存在下一张图,则
if (document.getElementsByClassName("after")[0].getElementsByTagName("a")[0]) {
newFrame.src=document.getElementsByClassName("after")[0].getElementsByTagName("a")[0].href;
newFrame.onload=function () {
if (!!window.myNewFrame.document.getElementsByClassName("original-image")[0]) {//如果是单图
bigPicHref=window.myNewFrame.document.getElementsByClassName("original-image")[0].getAttribute("data-src");//获取大图url
getBigPic2();
}else if(!!window.myNewFrame.document.getElementsByClassName("works_display")[0]){
//如果是多图
if (!!window.myNewFrame.document.getElementsByTagName("canvas")[0]) {//如果是动图
bigPicHref=window.myNewFrame.pixiv.context.ugokuIllustFullscreenData.src;
getBigPic2();
}else{//如果是多图,在第二个iframe中打开图集的详情页
newFrame2.src=window.myNewFrame.document.getElementsByClassName("works_display")[0].getElementsByTagName("a")[0].href;
newFrame2.onload=function () {
tujiUrl=[];//存储图集中每个图的url
for (ii = 0; ii < window.myNewFrame2.document.getElementsByClassName("ui-scroll-view").length; ii++) {
tujiUrl[ii]=window.myNewFrame2.document.getElementsByClassName("ui-scroll-view")[ii].getAttribute("data-src");
bigPicHrefLink3=window.myNewFrame2.document.createElement("a");
bigPicHrefLink3.href=tujiUrl[ii];
bigPicHrefLink3.download=null;
window.myNewFrame2.document.body.appendChild(bigPicHrefLink3);
bigPicHrefLink3.click();
};
}
}
};
t=setInterval(getNextPic, 500);//开启定时器一定要写在这个onload里面,否则下一步的判断会报错
if (!window.myNewFrame.document.getElementsByClassName("after")[0].getElementsByTagName("a")[0]) {//如果没有下一张则取消
clearInterval(t);
alert("最后一张图片正在下载中,下载即将完成。");
return;
};
}
};
下面是模式二的代码。这是在列表页使用的,每个列表页都需要执行一次。
//创建iframe1,打开作品页面
newFrame1=document.createElement("iframe");
newFrame1.name="mynewFrame1";
newFrame1.id="mynewFrame1";
newFrame1.width=0;
newFrame1.height=0;
document.body.appendChild(newFrame1);
//创建iframe2,用来打开图集页面
newFrame2=document.createElement("iframe");
newFrame2.name="mynewFrame2";
newFrame2.id="mynewFrame2";
newFrame2.width=0;
newFrame2.height=0;
document.body.appendChild(newFrame2);
//获取列表中作品的数量
var listNum=document.getElementsByClassName("_image-items")[0].getElementsByClassName("image-item");
//存储所有作品页面的url
var listUrl=new Array();
for (var i = 0; i < listNum.length; i++) {
listUrl[i]=listNum[i].getElementsByClassName("work")[0].href;
};
//在iframe1中打开作品
function getPic () {
clearInterval(t);//清除定时器
window.newFrame1.src=listUrl.shift();//输出并删除数组中的第一项
window.newFrame1.onload=function () {
if (!!window.mynewFrame1.document.getElementsByClassName("original-image")[0]) {//如果是单图
//获取大图url
bigPicHref=window.mynewFrame1.document.getElementsByClassName("original-image")[0].getAttribute("data-src");
//建立单图的下载链接并下载
bigPicHrefLink1=document.createElement("a");
bigPicHrefLink1.href=bigPicHref;
bigPicHrefLink1.download=null;
window.mynewFrame1.document.body.appendChild(bigPicHrefLink1);
bigPicHrefLink1.click();
}else if(!!window.mynewFrame1.document.getElementsByClassName("works_display")[0]){//如果是多图或者动图
if (!!window.mynewFrame1.document.getElementsByTagName("canvas")[0]) {//如果是动图
//建立动图的下载链接并下载
bigPicHrefLink1=document.createElement("a");
bigPicHrefLink1.href=window.mynewFrame1.pixiv.context.ugokuIllustFullscreenData.src;
bigPicHrefLink1.download=null;
window.mynewFrame1.document.body.appendChild(bigPicHrefLink1);
bigPicHrefLink1.click();
}else{//如果是多图,在第二个iframe中打开图集的详情页
window.newFrame2.src=window.mynewFrame1.document.getElementsByClassName("works_display")[0].getElementsByTagName("a")[0].href;
window.newFrame2.onload=function () {
//建立图集中每个图片的下载链接并下载
for (ii = 0; ii < window.mynewFrame2.document.getElementsByClassName("ui-scroll-view").length; ii++) {
bigPicHrefLink2=window.mynewFrame2.document.createElement("a");
bigPicHrefLink2.href=window.mynewFrame2.document.getElementsByClassName("ui-scroll-view")[ii].getAttribute("data-src");
bigPicHrefLink2.download=null;
window.mynewFrame2.document.body.appendChild(bigPicHrefLink2);
bigPicHrefLink2.click();
};
}
}
};
t=setInterval(getPic, 500);//开启定时器一定要写在这个onload里面,否则下一步的判断会报错
if (listUrl.length==0) {//如果已经全部下载完成
clearInterval(t);//取消定时器
alert("最后一张图片正在下载中,下载即将完成。");
return;
};
}
}
t=setInterval(getPic, 500);//开启下载图片的定时器