|
@@ -24,6 +24,9 @@
|
|
|
<el-menu-item index="1">
|
|
|
<img src="../assets/image/m-alibaba.png" class="m-image"/><span slot="title">阿里巴巴</span>
|
|
|
</el-menu-item>
|
|
|
+ <el-menu-item index="5">
|
|
|
+ <img src="../assets/image/m-hong.png" class="m-image"/><span slot="title">小红书</span>
|
|
|
+ </el-menu-item>
|
|
|
<el-menu-item index="10">
|
|
|
<img src="../assets/image/m-chrome.png" class="m-image"/><span slot="title">其他网址(Beta)</span>
|
|
|
</el-menu-item>
|
|
@@ -54,7 +57,7 @@
|
|
|
|
|
|
<soft-img ref="imgRef" v-show="['2-1', '2-2', '2-3', '2-5'].indexOf(menuIndex) > -1" @open-vip="openVip" @check-authority="checkAuthority"></soft-img>
|
|
|
|
|
|
- <el-main v-show="['1', '2', '3', '4', '10'].indexOf(menuIndex) > -1" ref="el-main" style="background-color: #fafafa;">
|
|
|
+ <el-main v-show="['1', '2', '3', '4', '5', '10'].indexOf(menuIndex) > -1" ref="el-main" style="background-color: #fafafa;">
|
|
|
<template>
|
|
|
<div class="content-top">
|
|
|
<div>
|
|
@@ -91,6 +94,7 @@
|
|
|
<span v-if="menuIndex == '2'">京东 - </span>
|
|
|
<span v-if="menuIndex == '3'">天猫 - </span>
|
|
|
<span v-if="menuIndex == '4'">淘宝 - </span>
|
|
|
+ <span v-if="menuIndex == '5'">小红书 - </span>
|
|
|
<span v-if="menuIndex == '10'">网页 - </span>
|
|
|
图片下载
|
|
|
</h3>
|
|
@@ -110,12 +114,17 @@
|
|
|
|
|
|
<div style="padding: 15px 0 20px;">
|
|
|
<el-row type="flex" justify="space-between">
|
|
|
+ <div v-if="menuIndex == '5'" style="padding-top: 10px;">
|
|
|
+ <label>下载类型:</label>
|
|
|
+ <el-checkbox :value="true" style="opacity: 0.6; cursor: not-allowed;">文章图</el-checkbox>
|
|
|
+ </div>
|
|
|
+
|
|
|
<div v-if="menuIndex == '10'" style="padding-top: 10px;">
|
|
|
<label>下载类型:</label>
|
|
|
<el-checkbox :value="true" style="opacity: 0.6; cursor: not-allowed;">图片</el-checkbox>
|
|
|
</div>
|
|
|
|
|
|
- <div v-if="menuIndex < 10" style="padding-top: 10px;">
|
|
|
+ <div v-if="['1', '2', '3', '4'].indexOf(menuIndex) > -1" style="padding-top: 10px;">
|
|
|
<label>下载类型:</label>
|
|
|
<el-checkbox-group :min="1" v-model="settingArr" style="display: inline-block;">
|
|
|
<el-checkbox label="mainImg">主图</el-checkbox>
|
|
@@ -307,6 +316,7 @@
|
|
|
jdList: [],
|
|
|
tbList: [],
|
|
|
tmallList: [],
|
|
|
+ redList: [],
|
|
|
commonList: [],
|
|
|
productName: pjson.softInfo.softName,
|
|
|
imgUrl: this.$api.imgUrl,
|
|
@@ -352,6 +362,9 @@
|
|
|
case '4':
|
|
|
str = 'tb';
|
|
|
break;
|
|
|
+ case '5':
|
|
|
+ str = 'red';
|
|
|
+ break;
|
|
|
case '10':
|
|
|
str = 'common';
|
|
|
break;
|
|
@@ -360,7 +373,6 @@
|
|
|
}
|
|
|
},
|
|
|
async mounted() {
|
|
|
-
|
|
|
this.$refs.updateRef.updateSoft(true);
|
|
|
|
|
|
let homedir = os.userInfo().homedir;
|
|
@@ -467,6 +479,9 @@
|
|
|
case '4':
|
|
|
type = 'tb';
|
|
|
break;
|
|
|
+ case '5':
|
|
|
+ type = 'red';
|
|
|
+ break;
|
|
|
case '10':
|
|
|
type = 'common';
|
|
|
break;
|
|
@@ -499,6 +514,9 @@
|
|
|
case '4':
|
|
|
this.tbList = [];
|
|
|
break;
|
|
|
+ case '5':
|
|
|
+ this.redList = [];
|
|
|
+ break;
|
|
|
case '10':
|
|
|
this.commonList = [];
|
|
|
break;
|
|
@@ -528,6 +546,9 @@
|
|
|
case '4':
|
|
|
this.tbList.push(info);
|
|
|
break;
|
|
|
+ case '5':
|
|
|
+ this.redList.push(info);
|
|
|
+ break;
|
|
|
case '10':
|
|
|
this.commonList.push(info);
|
|
|
break;
|
|
@@ -593,6 +614,9 @@
|
|
|
case '4':
|
|
|
this.tbList.push(info);
|
|
|
break;
|
|
|
+ case '5':
|
|
|
+ this.redList.push(info);
|
|
|
+ break;
|
|
|
case '10':
|
|
|
this.commonList.push(info);
|
|
|
break;
|
|
@@ -683,6 +707,9 @@
|
|
|
case '4': // 淘宝
|
|
|
fileList = this.tbList;
|
|
|
break;
|
|
|
+ case '5': // 小红书
|
|
|
+ fileList = this.redList;
|
|
|
+ break;
|
|
|
case '10': // 普通网址
|
|
|
fileList = this.commonList;
|
|
|
break;
|
|
@@ -755,6 +782,9 @@
|
|
|
case '4': // 淘宝
|
|
|
task = this.tbScanImg(item);
|
|
|
break;
|
|
|
+ case '5': // 小红书
|
|
|
+ task = this.redDownload(item);
|
|
|
+ break;
|
|
|
case '10': // 普通网址
|
|
|
task = this.normalDownload(item);
|
|
|
break;
|
|
@@ -809,9 +839,16 @@
|
|
|
let number = 0;
|
|
|
urlInfo.status = '2';
|
|
|
urlInfo.num = 0;
|
|
|
+ puppeteer.use(StealthPlugin());
|
|
|
const browser = await puppeteer.launch({
|
|
|
executablePath: puppeteer.executablePath().replace('win32-1', 'win64-1'),
|
|
|
- userDataDir: os.tmpdir() + separator + 'chrome-data-capture',
|
|
|
+ userDataDir: os.tmpdir() + separator + 'chrome-data-capture',
|
|
|
+ args: [
|
|
|
+ '--start-maximized',
|
|
|
+ '--no-sandbox',
|
|
|
+ '--disable-setuid-sandbox',
|
|
|
+ '--disable-blink-features=AutomationControlled',
|
|
|
+ ]
|
|
|
});
|
|
|
const page = await browser.newPage();
|
|
|
|
|
@@ -1970,6 +2007,137 @@
|
|
|
await browser.close();
|
|
|
},
|
|
|
|
|
|
+
|
|
|
+
|
|
|
+ // 5-小红书下载
|
|
|
+ async redDownload(urlInfo){
|
|
|
+ let task = await new Promise((resolve,reject) =>{
|
|
|
+ (async () => {
|
|
|
+ try{
|
|
|
+ let authority = this.$refs.headerRef.authority.isAuthority;
|
|
|
+ let number = 0;
|
|
|
+ urlInfo.status = '2';
|
|
|
+ urlInfo.num = 0;
|
|
|
+ puppeteer.use(StealthPlugin());
|
|
|
+ const browser = await puppeteer.launch({
|
|
|
+ executablePath: puppeteer.executablePath().replace('win32-1', 'win64-1'),
|
|
|
+ userDataDir: os.tmpdir() + separator + 'chrome-data-capture',
|
|
|
+ args: [
|
|
|
+ '--start-maximized',
|
|
|
+ '--no-sandbox',
|
|
|
+ '--disable-setuid-sandbox',
|
|
|
+ '--disable-blink-features=AutomationControlled',
|
|
|
+ ]
|
|
|
+ });
|
|
|
+ const page = await browser.newPage();
|
|
|
+
|
|
|
+ page.on('response', async(response) => {
|
|
|
+ // 检查响应的 MIME 类型是否以 'image/' 开头
|
|
|
+ if (response.headers()['content-type'] && response.headers()['content-type'].startsWith('image/') && response.headers()['content-length']) {
|
|
|
+ let imgArr = ['gif', 'jpeg', 'png', 'webp', 'svg', 'tiff', 'bmp', 'ico', 'avif'];
|
|
|
+ let imgType = 'jpg';
|
|
|
+ let isBase = false;
|
|
|
+ imgArr.map((item, index) => {
|
|
|
+ if(response.headers()['content-type'].indexOf(item) > -1){
|
|
|
+ imgType = item;
|
|
|
+ if(item == 'jpeg'){
|
|
|
+ imgType = 'jpg';
|
|
|
+ }else if(item == 'avif'){
|
|
|
+ imgType = 'png';
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ let url = response.url();
|
|
|
+ let regex = /^data:image\/[\w|+|-]+;base64,/;
|
|
|
+ if(regex.exec(url)){
|
|
|
+ url = response.url().replace(/^data:image\/[\w|+|-]+;base64,/, '');
|
|
|
+ isBase = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ let imgInfo = {
|
|
|
+ url: url,
|
|
|
+ contentType: response.headers()['content-type'],
|
|
|
+ status: response.status(),
|
|
|
+ imgType: imgType,
|
|
|
+ isBase: isBase
|
|
|
+ }
|
|
|
+
|
|
|
+ if(urlInfo.title){
|
|
|
+ if (fs.existsSync(this.downloadDir + separator + pjson.softInfo.softName + separator + urlInfo.title)) {
|
|
|
+ urlInfo.newPath = this.downloadDir + separator + pjson.softInfo.softName + separator + urlInfo.title;
|
|
|
+ } else {
|
|
|
+ fs.mkdirSync(this.downloadDir + separator + pjson.softInfo.softName + separator + urlInfo.title);
|
|
|
+ urlInfo.newPath = this.downloadDir + separator + pjson.softInfo.softName + separator + urlInfo.title;
|
|
|
+ }
|
|
|
+ }else{
|
|
|
+ await this.getTitle(page, urlInfo); // 生成页面标题对应的文件夹
|
|
|
+ }
|
|
|
+
|
|
|
+ let outputPath = urlInfo.newPath + '\\' + this.randomString(35) + '.' + imgInfo.imgType;
|
|
|
+
|
|
|
+ urlInfo.status = '3';
|
|
|
+ number++;
|
|
|
+ if(!authority && number <= this.execNum){
|
|
|
+ if(imgInfo.isBase){ //base64位图片下载
|
|
|
+ this.downloadBaseImage(imgInfo.url, outputPath, urlInfo)
|
|
|
+ }else{
|
|
|
+ this.downloadImage(imgInfo.url, outputPath, urlInfo);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if(authority){
|
|
|
+ if(imgInfo.isBase){ //base64位图片下载
|
|
|
+ this.downloadBaseImage(imgInfo.url, outputPath, urlInfo)
|
|
|
+ }else{
|
|
|
+ this.downloadImage(imgInfo.url, outputPath, urlInfo);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ await page.goto(urlInfo.url, {waitUntil : 'networkidle2'});
|
|
|
+
|
|
|
+ let pageInfo = await page.evaluate(() => {
|
|
|
+ let cHeight = document.documentElement.clientHeight;
|
|
|
+ let scrollHeight = document.body.scrollHeight;
|
|
|
+ return {'scrollHeight': scrollHeight, 'cHeight': cHeight}
|
|
|
+ });
|
|
|
+
|
|
|
+ let scrollHeight = pageInfo.scrollHeight;
|
|
|
+ let cHeight = pageInfo.cHeight;
|
|
|
+
|
|
|
+ let num = Math.ceil(scrollHeight / cHeight);
|
|
|
+ let start = -1;
|
|
|
+ let scrollInt = setInterval(async() => {
|
|
|
+ start ++;
|
|
|
+ await page.evaluate((start) => {
|
|
|
+ let cHeight = document.documentElement.clientHeight;
|
|
|
+ window.scrollTo({
|
|
|
+ top: cHeight * start,
|
|
|
+ behavior: "smooth"
|
|
|
+ });
|
|
|
+ }, start);
|
|
|
+ if(start > num || start > 200){ // 防止页面过长,滚动200次自动停止
|
|
|
+ clearInterval(scrollInt);
|
|
|
+ await browser.close();
|
|
|
+ urlInfo.status = '4';
|
|
|
+ resolve(true);
|
|
|
+ this.loading = false;
|
|
|
+ }
|
|
|
+ }, 300);
|
|
|
+
|
|
|
+ }catch(e){
|
|
|
+ urlInfo.status = '5';
|
|
|
+ reject(e);
|
|
|
+ this.showError(e);
|
|
|
+ }
|
|
|
+ })();
|
|
|
+ });
|
|
|
+
|
|
|
+ },
|
|
|
+
|
|
|
//
|
|
|
downloadExample(){
|
|
|
let url = 'https://www.xingyousoft.com/soft/XYCapture/example.xlsx';
|