|
@@ -109,8 +109,9 @@
|
|
|
:loading-config="{icon: 'vxe-icon-indicator roll', text: '加载中...'}" :data="this[listStr+'List']" :scroll-y="{enabled: true}">
|
|
:loading-config="{icon: 'vxe-icon-indicator roll', text: '加载中...'}" :data="this[listStr+'List']" :scroll-y="{enabled: true}">
|
|
|
<vxe-column field="title" title="名称"></vxe-column>
|
|
<vxe-column field="title" title="名称"></vxe-column>
|
|
|
<vxe-column field="page" title="页数" width="160">
|
|
<vxe-column field="page" title="页数" width="160">
|
|
|
- <template #default="{ row }">
|
|
|
|
|
- 第{{row.currentPage}}页,共{{row.totalPage}}页
|
|
|
|
|
|
|
+ <template #default="{ row }" >
|
|
|
|
|
+ <span v-if="row.totalCnt">共{{row.currentPage}}页,共{{row.totalCnt}}条</span>
|
|
|
|
|
+ <span v-else>第{{row.currentPage}}页,共{{row.totalPage}}页</span>
|
|
|
</template>
|
|
</template>
|
|
|
</vxe-column>
|
|
</vxe-column>
|
|
|
<vxe-column field="filesize" title="条数" width="100">
|
|
<vxe-column field="filesize" title="条数" width="100">
|
|
@@ -128,6 +129,14 @@
|
|
|
<i class="el-icon-success" style="font-size: 16px; color: #19be6b;"></i>
|
|
<i class="el-icon-success" style="font-size: 16px; color: #19be6b;"></i>
|
|
|
<span>导出成功</span>
|
|
<span>导出成功</span>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
+ <template v-if="row.status == '3'">
|
|
|
|
|
+ <i class="el-icon-loading" style="font-size: 16px; color: #999;"></i>
|
|
|
|
|
+ <span>分析中...</span>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ <template v-if="row.status == '4'">
|
|
|
|
|
+ <i class="el-icon-error" style="font-size: 16px; color: #ed4014;"></i>
|
|
|
|
|
+ <span>拦截验证,请稍后重试</span>
|
|
|
|
|
+ </template>
|
|
|
</template>
|
|
</template>
|
|
|
</vxe-column>
|
|
</vxe-column>
|
|
|
<vxe-column title="操作" width="160">
|
|
<vxe-column title="操作" width="160">
|
|
@@ -207,6 +216,7 @@
|
|
|
jdList: [],
|
|
jdList: [],
|
|
|
redList: [],
|
|
redList: [],
|
|
|
commonList: [],
|
|
commonList: [],
|
|
|
|
|
+ alibabaShop: {},
|
|
|
|
|
|
|
|
execNum: 100, //限制
|
|
execNum: 100, //限制
|
|
|
checkLoading: false, //点击检测登录状态
|
|
checkLoading: false, //点击检测登录状态
|
|
@@ -224,9 +234,7 @@
|
|
|
loginBrowser: null, // 登录用的浏览器实例
|
|
loginBrowser: null, // 登录用的浏览器实例
|
|
|
pauseFlag: true, //暂停中止标志
|
|
pauseFlag: true, //暂停中止标志
|
|
|
addLoading: false,
|
|
addLoading: false,
|
|
|
- allLoading: false,
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
|
|
+ allLoading: false
|
|
|
};
|
|
};
|
|
|
},
|
|
},
|
|
|
computed: {
|
|
computed: {
|
|
@@ -562,6 +570,7 @@
|
|
|
let index = Number(this.menuIndex) - 1;
|
|
let index = Number(this.menuIndex) - 1;
|
|
|
|
|
|
|
|
if(this.menuIndex == '1'){ // 阿里巴巴
|
|
if(this.menuIndex == '1'){ // 阿里巴巴
|
|
|
|
|
+ this.alibabaList = [];
|
|
|
if(this.alibabaStatus == 1 || this.alibabaStatus == 3){ // 未检测登录状态/或提示未登录状态,开始检测
|
|
if(this.alibabaStatus == 1 || this.alibabaStatus == 3){ // 未检测登录状态/或提示未登录状态,开始检测
|
|
|
await this.checkAlibabaLogin().then((data) => {
|
|
await this.checkAlibabaLogin().then((data) => {
|
|
|
if(data != 2){ // 未登录
|
|
if(data != 2){ // 未登录
|
|
@@ -684,98 +693,234 @@
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 1、搜索页面
|
|
|
|
|
+ * https://s.taobao.com/search?initiative_id=staobaoz_20251013&page=1&q=123&tab=all
|
|
|
|
|
+ * https://search.taobao.com/search?initiative_id=staobaoz_20251013&page=1&q=123&tab=all
|
|
|
|
|
+ *
|
|
|
|
|
+ * 2、淘宝店铺主页
|
|
|
|
|
+ * https://shop129008953.taobao.com/shop/view_shop.htm?appUid=RAzN8HWKfxsFarWFEi9gLm2itTXHaYPr4nA4TWswCv3gerYvjs8&spm=a21n57.1.hoverItem.10
|
|
|
|
|
+ * https://yyyy.taobao.com
|
|
|
|
|
+ * 淘宝店铺搜索
|
|
|
|
|
+ * https://shop71610707.taobao.com/search.htm?keyword=%B4%BA%D6%F1%D1%F2%C3%AB%BF%E3%C4%D0&spm=a21xtw.29178619.0.0
|
|
|
|
|
+ *
|
|
|
|
|
+ * 3、天猫店铺主页
|
|
|
|
|
+ * https://cexu.tmall.com/shop/view_shop.htm?appUid=RAzN8HWRk67qBqZaMatNxpJ7z2rznpMGpbayXUUXf5rWRaQ5EVP&spm=a21n57.1.hoverItem.2
|
|
|
|
|
+ * 天猫店铺搜索
|
|
|
|
|
+ * https://cexu.tmall.com/search.htm?keyword=%D0%C2%D6%D0%CA%BD%C4%D0%D7%B0&spm=a21xtw.29178619.0.0
|
|
|
|
|
+ *
|
|
|
|
|
+ * 5、天猫国际店铺主页
|
|
|
|
|
+ * https://jp.tmall.hk/?spm=a1z10.3-b.1997427721.d4918089.13aa32643EEzRU
|
|
|
|
|
+ *
|
|
|
|
|
+ **/
|
|
|
|
|
+
|
|
|
// 天猫/淘宝扫描网址
|
|
// 天猫/淘宝扫描网址
|
|
|
tbScanUrl(url){
|
|
tbScanUrl(url){
|
|
|
(async () => {
|
|
(async () => {
|
|
|
try{
|
|
try{
|
|
|
let authority = this.$refs.headerRef.authority.isAuthority;
|
|
let authority = this.$refs.headerRef.authority.isAuthority;
|
|
|
let page = await this.tbBrowser.newPage();
|
|
let page = await this.tbBrowser.newPage();
|
|
|
-
|
|
|
|
|
- let responseVideo = [];
|
|
|
|
|
let waitUntil = 'networkidle2';
|
|
let waitUntil = 'networkidle2';
|
|
|
waitUntil = this.initDevelop().waitUntil;
|
|
waitUntil = this.initDevelop().waitUntil;
|
|
|
- await page.goto(url, {waitUntil : waitUntil});
|
|
|
|
|
|
|
|
|
|
- let searchTitle = await this.getTitle(page, '淘宝商品搜索');
|
|
|
|
|
- let outObj = {};
|
|
|
|
|
- let pageHandle = await page.$$('[class^=next-pagination-display]');
|
|
|
|
|
- let currentPage = 1;
|
|
|
|
|
- let totalPage = 1;
|
|
|
|
|
- if(pageHandle && pageHandle.length > 0){
|
|
|
|
|
- let pageValue = await page.$eval('[class^=next-pagination-display]', el => el.innerText);
|
|
|
|
|
- currentPage = pageValue.replace('\n', '').split('/')[0] || 1;
|
|
|
|
|
- totalPage = pageValue.replace('\n', '').split('/')[1] || 1;
|
|
|
|
|
|
|
+ let searchReg = /^https?:\/\/(s|search).taobao.com\/search/;
|
|
|
|
|
+ let tbShopReg = /^https?:\/\/(?!www|item)(shop\d+|[\w-]+)\.taobao\.com(\/[^\s]*)?$/; //店铺首页
|
|
|
|
|
+ let tbShopReg2 = /^https?:\/\/(?!www|item)(shop\d+|[\w-]+)\.(taobao|tmall)\.com(\/(search|category)[^\s]*)?$/; // 店铺搜索和店铺分类
|
|
|
|
|
+ let tmallShopReg = /^https?:\/\/(?!www|list|detail)([\w-]+)\.tmall\.(com|hk)(\/[^\s]*)?$/
|
|
|
|
|
+ let shopGoodsCurrentPage = 1;
|
|
|
|
|
+ let shopGoodstotalPage = 1;
|
|
|
|
|
+ let tbShopGoods = {
|
|
|
|
|
+ title: '店铺主页',
|
|
|
|
|
+ currentPage: 1,
|
|
|
|
|
+ totalPage: 1,
|
|
|
|
|
+ urls: [],
|
|
|
|
|
+ status: '1',
|
|
|
|
|
+ loading: false,
|
|
|
|
|
+ shopName: '',
|
|
|
|
|
+ shopUrl: '',
|
|
|
|
|
+ type: 'tbShop',
|
|
|
|
|
+ totalCnt: 0
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ let typeStr = '';
|
|
|
|
|
+ if(tbShopReg.test(url) || tmallShopReg.test(url)){ // 淘宝店铺主页
|
|
|
|
|
+ typeStr = 'tbShop';
|
|
|
|
|
+ if(tbShopReg2.test(url)){
|
|
|
|
|
+ typeStr = 'tbCategory'
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- for(let i = Number(currentPage); i < Number(totalPage)+1; i++){
|
|
|
|
|
- let pValue = i + 1;
|
|
|
|
|
- let pageHandle = await page.$$('.next-pagination-jump-input input');
|
|
|
|
|
- if(pageHandle && pageHandle.length > 0){ // 页码多,可以点击跳转制定页码
|
|
|
|
|
- await page.type('.next-pagination-jump-input input', pValue.toString());
|
|
|
|
|
|
|
+ page.on('response', async(response) => {
|
|
|
|
|
+ if (response.headers()['content-type'] && response.headers()['content-type'].indexOf('application/json') > -1) {
|
|
|
|
|
+ if(response.url().indexOf('taobao.shop') > -1){ //淘宝店铺首页
|
|
|
|
|
+ if(response.url().indexOf('punishTextFetch') > -1){ //拦截
|
|
|
|
|
+ this.tbList.map((item, index) => { //修改任务状态
|
|
|
|
|
+ if(item.status == '3'){
|
|
|
|
|
+ item.status = '4';
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ let listFag = false;
|
|
|
|
|
+ if(typeStr == 'tbCategory'){ //搜索
|
|
|
|
|
+ let recommendObj = await page.$$('[class^=container-]>div[class^=title-]');
|
|
|
|
|
+ if(recommendObj && recommendObj.length > 0){ //搜索结果数量不多,不存在分页情况
|
|
|
|
|
+ listFag = true; //此时只获取mtop.taobao.shop.simple.fetch中的数据
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ try {
|
|
|
|
|
+ let data = await response.text();
|
|
|
|
|
+ let detailInfo = JSON.parse(data);
|
|
|
|
|
+
|
|
|
|
|
+ if(detailInfo.data && detailInfo.data.signInfoDTO){
|
|
|
|
|
+ let shopInfo = detailInfo.data.signInfoDTO;
|
|
|
|
|
+ tbShopGoods.title = shopInfo.shopName;
|
|
|
|
|
+ tbShopGoods.shopName = shopInfo.shopName;
|
|
|
|
|
+ tbShopGoods.shopUrl = shopInfo.shopUrl;
|
|
|
|
|
+ }
|
|
|
|
|
+ if(detailInfo.data){
|
|
|
|
|
+ tbShopGoods.status = '3';
|
|
|
|
|
+ let itemInfo = ''; // 分页数据
|
|
|
|
|
+ if(!listFag){
|
|
|
|
|
+ itemInfo = detailInfo.data;
|
|
|
|
|
+ }
|
|
|
|
|
+ if(detailInfo.data.itemInfoDTO){
|
|
|
|
|
+ itemInfo = detailInfo.data.itemInfoDTO
|
|
|
|
|
+ }
|
|
|
|
|
+ shopGoodsCurrentPage = itemInfo.page;
|
|
|
|
|
+ shopGoodstotalPage = Math.ceil(itemInfo.totalCnt / itemInfo.pageSize);
|
|
|
|
|
+ tbShopGoods.totalCnt = itemInfo.totalCnt;
|
|
|
|
|
+ if(itemInfo.data && itemInfo.data.length > 0){
|
|
|
|
|
+ for(let i = 0; i < itemInfo.data.length; i++){
|
|
|
|
|
+ let item = itemInfo.data[i];
|
|
|
|
|
+ let info = {
|
|
|
|
|
+ id: item.itemId,
|
|
|
|
|
+ title: item.title,
|
|
|
|
|
+ href: item.itemUrl,
|
|
|
|
|
+ price: isNaN(Number(item.discountPrice)) ? '' : item.discountPrice,
|
|
|
|
|
+ realSales: item.vagueSold365,
|
|
|
|
|
+ shopNameText: tbShopGoods.shopName,
|
|
|
|
|
+ shopUrl: tbShopGoods.shopUrl,
|
|
|
|
|
+ mainPic: item.image
|
|
|
|
|
+ }
|
|
|
|
|
+ tbShopGoods.urls.push(info);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ let flag = true;
|
|
|
|
|
+ for(let j = 0 ;j < this.tbList.length; j++){
|
|
|
|
|
+ if(tbShopGoods.shopName == this.tbList[j].shopName && tbShopGoods.shopUrl == this.tbList[j].shopUrl){
|
|
|
|
|
+ flag = false;
|
|
|
|
|
+ this.tbList[j].urls = tbShopGoods.urls;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if(flag){
|
|
|
|
|
+ this.tbList.push(tbShopGoods);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('店铺页面详情解析失败:', error);
|
|
|
|
|
+ this.showError(error);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- let itemTitle = searchTitle + '-' + i;
|
|
|
|
|
- const imgInfo = await page.evaluate((authority, execNum, itemTitle) => {
|
|
|
|
|
- let outObj = {
|
|
|
|
|
- title: itemTitle,
|
|
|
|
|
- currentPage: 1,
|
|
|
|
|
- totalPage: 1,
|
|
|
|
|
- urls: [],
|
|
|
|
|
- status: '1',
|
|
|
|
|
- loading: false
|
|
|
|
|
- };
|
|
|
|
|
- let total = document.querySelector('[class^=next-pagination-display]');
|
|
|
|
|
- if(total){
|
|
|
|
|
- outObj.currentPage = total.innerText.replace('\n', '').split('/')[0];
|
|
|
|
|
- outObj.totalPage = total.innerText.replace('\n', '').split('/')[1];
|
|
|
|
|
|
|
+ });
|
|
|
|
|
+ await page.goto(url, {waitUntil : waitUntil});
|
|
|
|
|
+ await page.waitForTimeout(3000);
|
|
|
|
|
+
|
|
|
|
|
+ if(tbShopReg.test(url) || tmallShopReg.test(url)){ // 店铺主页
|
|
|
|
|
+ let searchTitle = await this.getTitle(page, '店铺主页');
|
|
|
|
|
+ let typeStr = 'tbShop';
|
|
|
|
|
+ if(tbShopReg2.test(url)){
|
|
|
|
|
+ typeStr = 'tbCategory';
|
|
|
|
|
+ }
|
|
|
|
|
+ await this.initScrollShop(typeStr, page, shopGoodsCurrentPage, shopGoodstotalPage, searchTitle);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if(searchReg.test(url)){//普通搜索页面
|
|
|
|
|
+ let searchTitle = await this.getTitle(page, '淘宝商品搜索');
|
|
|
|
|
+ let outObj = {};
|
|
|
|
|
+ let pageHandle = await page.$$('[class^=next-pagination-display]');
|
|
|
|
|
+ let currentPage = 1;
|
|
|
|
|
+ let totalPage = 1;
|
|
|
|
|
+ if(pageHandle && pageHandle.length > 0){
|
|
|
|
|
+ let pageValue = await page.$eval('[class^=next-pagination-display]', el => el.innerText);
|
|
|
|
|
+ currentPage = pageValue.replace('\n', '').split('/')[0] || 1;
|
|
|
|
|
+ totalPage = pageValue.replace('\n', '').split('/')[1] || 1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ for(let i = Number(currentPage); i < Number(totalPage)+1; i++){
|
|
|
|
|
+ let pValue = i + 1;
|
|
|
|
|
+ let pageHandle = await page.$$('.next-pagination-jump-input input');
|
|
|
|
|
+ if(pageHandle && pageHandle.length > 0){ // 页码多,可以点击跳转制定页码
|
|
|
|
|
+ await page.type('.next-pagination-jump-input input', pValue.toString());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- //主图
|
|
|
|
|
- let arr1 = document.querySelectorAll('a[id*=item_id]');
|
|
|
|
|
- for(let i=0; i< arr1.length; i++){
|
|
|
|
|
- let href = arr1[i].href;
|
|
|
|
|
- let id = arr1[i].id.replace('item_id_', '');
|
|
|
|
|
- let title = arr1[i].querySelector('[class^=title]') ? arr1[i].querySelector('[class^=title]').innerText : '淘宝商品'+new Date().getTime();
|
|
|
|
|
- let priceInt = arr1[i].querySelector('[class^=priceInt]') ? arr1[i].querySelector('[class^=priceInt]').innerText : 0;
|
|
|
|
|
- let priceFloat = arr1[i].querySelector('[class^=priceFloat]') ? arr1[i].querySelector('[class^=priceFloat]').innerText : '';
|
|
|
|
|
- let price = priceInt + priceFloat;
|
|
|
|
|
- let realSales = arr1[i].querySelector('[class^=realSales]') ? arr1[i].querySelector('[class^=realSales]').innerText : '';
|
|
|
|
|
- let shopNameText = arr1[i].querySelector('[class^=shopNameText]') ? arr1[i].querySelector('[class^=shopNameText]').innerText : '';
|
|
|
|
|
- let shopUrl = arr1[i].querySelector('a[class^=shopName]') ? arr1[i].querySelector('a[class^=shopName]').href : '';
|
|
|
|
|
- let mainPic = arr1[i].querySelector('img[class^=mainImg]') ? arr1[i].querySelector('img[class^=mainImg]').src : '';
|
|
|
|
|
|
|
+ let itemTitle = searchTitle + '-' + i;
|
|
|
|
|
+ const imgInfo = await page.evaluate((itemTitle) => {
|
|
|
|
|
+ let outObj = {
|
|
|
|
|
+ title: itemTitle,
|
|
|
|
|
+ currentPage: 1,
|
|
|
|
|
+ totalPage: 1,
|
|
|
|
|
+ urls: [],
|
|
|
|
|
+ status: '1',
|
|
|
|
|
+ loading: false
|
|
|
|
|
+ };
|
|
|
|
|
+ let total = document.querySelector('[class^=next-pagination-display]');
|
|
|
|
|
+ if(total){
|
|
|
|
|
+ outObj.currentPage = total.innerText.replace('\n', '').split('/')[0];
|
|
|
|
|
+ outObj.totalPage = total.innerText.replace('\n', '').split('/')[1];
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- let info = {
|
|
|
|
|
- id: id,
|
|
|
|
|
- title: title,
|
|
|
|
|
- href: href,
|
|
|
|
|
- price: price,
|
|
|
|
|
- realSales: realSales,
|
|
|
|
|
- shopNameText: shopNameText,
|
|
|
|
|
- shopUrl: shopUrl,
|
|
|
|
|
- mainPic: mainPic
|
|
|
|
|
|
|
+ //主图
|
|
|
|
|
+ let arr1 = document.querySelectorAll('a[id*=item_id]');
|
|
|
|
|
+ for(let i=0; i< arr1.length; i++){
|
|
|
|
|
+ let href = arr1[i].href;
|
|
|
|
|
+ let id = arr1[i].id.replace('item_id_', '');
|
|
|
|
|
+ let title = arr1[i].querySelector('[class^=title]') ? arr1[i].querySelector('[class^=title]').innerText : '淘宝商品'+new Date().getTime();
|
|
|
|
|
+ let priceInt = arr1[i].querySelector('[class^=priceInt]') ? arr1[i].querySelector('[class^=priceInt]').innerText : 0;
|
|
|
|
|
+ let priceFloat = arr1[i].querySelector('[class^=priceFloat]') ? arr1[i].querySelector('[class^=priceFloat]').innerText : '';
|
|
|
|
|
+ let price = priceInt + priceFloat;
|
|
|
|
|
+ let realSales = arr1[i].querySelector('[class^=realSales]') ? arr1[i].querySelector('[class^=realSales]').innerText : '';
|
|
|
|
|
+ let shopNameText = arr1[i].querySelector('[class^=shopNameText]') ? arr1[i].querySelector('[class^=shopNameText]').innerText : '';
|
|
|
|
|
+ let shopUrl = arr1[i].querySelector('a[class^=shopName]') ? arr1[i].querySelector('a[class^=shopName]').href : '';
|
|
|
|
|
+ let mainPic = arr1[i].querySelector('img[class^=mainImg]') ? arr1[i].querySelector('img[class^=mainImg]').src : '';
|
|
|
|
|
+
|
|
|
|
|
+ let info = {
|
|
|
|
|
+ id: id,
|
|
|
|
|
+ title: title,
|
|
|
|
|
+ href: href,
|
|
|
|
|
+ price: price,
|
|
|
|
|
+ realSales: realSales,
|
|
|
|
|
+ shopNameText: shopNameText,
|
|
|
|
|
+ shopUrl: shopUrl,
|
|
|
|
|
+ mainPic: mainPic
|
|
|
|
|
+ }
|
|
|
|
|
+ outObj.urls.push(info);
|
|
|
}
|
|
}
|
|
|
- outObj.urls.push(info);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- //page.$$('.next-pagination-jump-input input');
|
|
|
|
|
- // let skuHandle = document.querySelector('.next-pagination-jump-go');
|
|
|
|
|
- // if(skuHandle){
|
|
|
|
|
- // skuHandle.click({force: true});
|
|
|
|
|
- // }
|
|
|
|
|
|
|
+
|
|
|
|
|
+ //跳转到指定页
|
|
|
|
|
+ //page.$$('.next-pagination-jump-input input');
|
|
|
|
|
+ // let skuHandle = document.querySelector('.next-pagination-jump-go');
|
|
|
|
|
+ // if(skuHandle){
|
|
|
|
|
+ // skuHandle.click({force: true});
|
|
|
|
|
+ // }
|
|
|
|
|
+
|
|
|
|
|
+ let nextHandle = document.querySelector('button[class*=next-next]');
|
|
|
|
|
+ if(nextHandle){
|
|
|
|
|
+ nextHandle.click({force: true});
|
|
|
|
|
+ }
|
|
|
|
|
+ return outObj;
|
|
|
|
|
+ }, itemTitle);
|
|
|
|
|
|
|
|
- let nextHandle = document.querySelector('button[class*=next-next]');
|
|
|
|
|
- if(nextHandle){
|
|
|
|
|
- nextHandle.click({force: true});
|
|
|
|
|
- }
|
|
|
|
|
- return outObj;
|
|
|
|
|
- }, authority, this.execNum, itemTitle);
|
|
|
|
|
|
|
+ this.tbList.push(imgInfo);
|
|
|
|
|
+ await this.delay();
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- this.tbList.push(imgInfo);
|
|
|
|
|
- await this.delay();
|
|
|
|
|
|
|
+ await this.tbBrowser.close();
|
|
|
|
|
+ this.addLoading = false;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- await this.tbBrowser.close();
|
|
|
|
|
- this.addLoading = false;
|
|
|
|
|
|
|
|
|
|
}catch(e){
|
|
}catch(e){
|
|
|
this.addLoading = false;
|
|
this.addLoading = false;
|
|
@@ -792,23 +937,105 @@
|
|
|
let page = await this.alibabaBrowser.newPage();
|
|
let page = await this.alibabaBrowser.newPage();
|
|
|
let gapTime = Number(this.initGap()) * 1000;
|
|
let gapTime = Number(this.initGap()) * 1000;
|
|
|
|
|
|
|
|
- let responseVideo = [];
|
|
|
|
|
let waitUntil = 'networkidle2';
|
|
let waitUntil = 'networkidle2';
|
|
|
waitUntil = this.initDevelop().waitUntil;
|
|
waitUntil = this.initDevelop().waitUntil;
|
|
|
|
|
+
|
|
|
|
|
+ page.on('response', async(response) => {
|
|
|
|
|
+ if (response.headers()['content-type'] && response.headers()['content-type'].indexOf('application/json') > -1) {
|
|
|
|
|
+ if(response.url().indexOf('alibaba') > -1 && response.url().indexOf('callback=mtopjsonp') == -1){ //店铺首页
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ let data = await response.text();
|
|
|
|
|
+ let detailInfo = JSON.parse(data);
|
|
|
|
|
+ let currentPage = 1;
|
|
|
|
|
+ let totalPage = 1;
|
|
|
|
|
+ let nextBtn = await page.$x("//button[contains(text(), '下一页 >')]");
|
|
|
|
|
+ if(nextBtn && nextBtn.length > 0){
|
|
|
|
|
+ let nextSibling = await page.$x("//button[contains(text(), '下一页 >')]/following-sibling::*[1]");
|
|
|
|
|
+ if(nextSibling && nextSibling.length > 0){
|
|
|
|
|
+ let page = await nextSibling[0].evaluate(el => el.innerText.trim());
|
|
|
|
|
+ if(page){
|
|
|
|
|
+ currentPage = page.split('/')[0];
|
|
|
|
|
+ totalPage = page.split('/')[1];
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if(this.alibabaList.length == 0){
|
|
|
|
|
+ let searchTitle = await this.getTitle(page, '阿里巴巴商品链接');
|
|
|
|
|
+ let outObj = {
|
|
|
|
|
+ title: searchTitle + '-1',
|
|
|
|
|
+ currentPage: currentPage,
|
|
|
|
|
+ totalPage: totalPage,
|
|
|
|
|
+ urls: [],
|
|
|
|
|
+ status: '1',
|
|
|
|
|
+ loading: false
|
|
|
|
|
+ };
|
|
|
|
|
+ this.alibabaList.push(outObj);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if(detailInfo.data && detailInfo.data.content){
|
|
|
|
|
+ let offerList = detailInfo.data.content.offerList;
|
|
|
|
|
+ for(let i = 0; i < offerList.length; i++){
|
|
|
|
|
+ let item = offerList[i];
|
|
|
|
|
+ let imgUrl = '';
|
|
|
|
|
+ if(item.offerImages[0]){
|
|
|
|
|
+ imgUrl = 'https://cbu01.alicdn.com/' + item.offerImages[0].imageURI;
|
|
|
|
|
+ }
|
|
|
|
|
+ let info = {
|
|
|
|
|
+ id: item.id,
|
|
|
|
|
+ title: item.subject,
|
|
|
|
|
+ href: "https://detail.1688.com/offer/" + item.id +".html",
|
|
|
|
|
+ price: item.handPrice,
|
|
|
|
|
+ realSales: item.vagueSaleQuantity,
|
|
|
|
|
+ shopNameText: '',
|
|
|
|
|
+ shopUrl: '',
|
|
|
|
|
+ mainPic: imgUrl
|
|
|
|
|
+ }
|
|
|
|
|
+ this.alibabaList[Number(currentPage)-1].urls.push(info);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('店铺页面详情解析失败:', error);
|
|
|
|
|
+ this.showError(error);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ });
|
|
|
await page.goto(url, {waitUntil : waitUntil});
|
|
await page.goto(url, {waitUntil : waitUntil});
|
|
|
|
|
+ await page.waitForTimeout(3000);
|
|
|
|
|
|
|
|
- let searchTitle = await this.getTitle(page, '阿里巴巴商品搜索');
|
|
|
|
|
- //找页码信息
|
|
|
|
|
- let outObj = {};
|
|
|
|
|
- let pageHandle = await page.$$('[class^=pagination-container] span');
|
|
|
|
|
- let currentPage = 1;
|
|
|
|
|
- let totalPage = 1;
|
|
|
|
|
- if(pageHandle && pageHandle.length > 0){
|
|
|
|
|
- totalPage = await page.$eval('[class^=pagination-container] span', el => el.innerText);
|
|
|
|
|
- currentPage = await page.$eval('[class^=pagination-container] .fui-current', el => el.innerText);
|
|
|
|
|
|
|
+ let alibabaReg = /^https?:\/\/(?!www)(shop\d+|[\w-]+)\.1688\.com(\/page\/offerlist[^\s]*)?$/; //店铺首页
|
|
|
|
|
+ let searchTitle = await this.getTitle(page, '阿里巴巴商品链接');
|
|
|
|
|
+ if(alibabaReg.test(url)){ // 店铺列表
|
|
|
|
|
+ let currentPage = 1;
|
|
|
|
|
+ let totalPage = 1;
|
|
|
|
|
+ let nextBtn = await page.$x("//button[contains(text(), '下一页 >')]");
|
|
|
|
|
+ if(nextBtn && nextBtn.length > 0){
|
|
|
|
|
+ let nextSibling = await page.$x("//button[contains(text(), '下一页 >')]/following-sibling::*[1]");
|
|
|
|
|
+ if(nextSibling && nextSibling.length > 0){
|
|
|
|
|
+ let page = await nextSibling[0].evaluate(el => el.innerText.trim());
|
|
|
|
|
+ if(page){
|
|
|
|
|
+ currentPage = page.split('/')[0];
|
|
|
|
|
+ totalPage = page.split('/')[1];
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ await this.initScrollShop('alibaba', page, Number(currentPage), Number(totalPage), searchTitle);
|
|
|
|
|
+ }else{
|
|
|
|
|
+ //找页码信息
|
|
|
|
|
+ let outObj = {};
|
|
|
|
|
+ let pageHandle = await page.$$('[class^=pagination-container] span');
|
|
|
|
|
+ let currentPage = 1;
|
|
|
|
|
+ let totalPage = 1;
|
|
|
|
|
+ if(pageHandle && pageHandle.length > 0){
|
|
|
|
|
+ totalPage = await page.$eval('[class^=pagination-container] span', el => el.innerText);
|
|
|
|
|
+ currentPage = await page.$eval('[class^=pagination-container] .fui-current', el => el.innerText);
|
|
|
|
|
+ }
|
|
|
|
|
+ await this.initScroll('alibaba', page, Number(currentPage), Number(totalPage), searchTitle);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- await this.initScroll('alibaba', page, Number(currentPage), Number(totalPage), searchTitle);
|
|
|
|
|
}catch(e){
|
|
}catch(e){
|
|
|
this.addLoading = false;
|
|
this.addLoading = false;
|
|
|
this.showError(e);
|
|
this.showError(e);
|
|
@@ -824,31 +1051,54 @@
|
|
|
let page = await this.jdBrowser.newPage();
|
|
let page = await this.jdBrowser.newPage();
|
|
|
let gapTime = Number(this.initGap()) * 1000;
|
|
let gapTime = Number(this.initGap()) * 1000;
|
|
|
|
|
|
|
|
- let responseVideo = [];
|
|
|
|
|
let waitUntil = 'networkidle2';
|
|
let waitUntil = 'networkidle2';
|
|
|
waitUntil = this.initDevelop().waitUntil;
|
|
waitUntil = this.initDevelop().waitUntil;
|
|
|
await page.goto(url, {waitUntil : waitUntil});
|
|
await page.goto(url, {waitUntil : waitUntil});
|
|
|
|
|
+ await page.waitForTimeout(3000);
|
|
|
|
|
|
|
|
- let searchTitle = await this.getTitle(page, '京东商品搜索');
|
|
|
|
|
- //找页码信息
|
|
|
|
|
- let outObj = {};
|
|
|
|
|
- let pageHandle = await page.$$('[class*=quick-result]');
|
|
|
|
|
- let currentPage = 1;
|
|
|
|
|
- let totalPage = 1;
|
|
|
|
|
- if(pageHandle && pageHandle.length > 0){
|
|
|
|
|
- let pageContent = await page.$eval('[class*=quick-result]', el => el.innerText);
|
|
|
|
|
- pageContent = pageContent.replace('\n', '').replace('\n', '');
|
|
|
|
|
- currentPage =pageContent.split('/')[0];
|
|
|
|
|
- totalPage = pageContent.split('/')[1];
|
|
|
|
|
|
|
+ let jdShopReg = /^https?:\/\/mall\.jd\.(com|hk)(\/(view_search|index)[^\s]*)?$/; //店铺首页
|
|
|
|
|
+ if(jdShopReg.test(url)){
|
|
|
|
|
+ let searchTitle = await this.getTitle(page, '京东店铺商品');
|
|
|
|
|
+ //找页码信息
|
|
|
|
|
+ let outObj = {};
|
|
|
|
|
+ let pageHandle = await page.$$('[id^=J_topPage]');
|
|
|
|
|
+ let currentPage = 1;
|
|
|
|
|
+ let totalPage = 1;
|
|
|
|
|
+ if(pageHandle && pageHandle.length > 0){
|
|
|
|
|
+ let pageContent = await page.$eval('[id^=J_topPage] [class^=fp-text]', el => el.innerText);
|
|
|
|
|
+ currentPage =pageContent.split('/')[0];
|
|
|
|
|
+ totalPage = pageContent.split('/')[1];
|
|
|
|
|
+ }else{
|
|
|
|
|
+ let pageHandle = await page.$$('[class=jPage]');
|
|
|
|
|
+ if(pageHandle && pageHandle.length > 0){
|
|
|
|
|
+ currentPage = await page.$eval('[class=jPage] [class*=jPageCurrent]', el => el.innerText);
|
|
|
|
|
+ totalPage = await page.$$eval('[class=jPage] a', links => links[links.length - 2].textContent);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ await this.initScrollShop('jdShop', page, Number(currentPage), Number(totalPage), searchTitle);
|
|
|
}else{
|
|
}else{
|
|
|
- let pageHandle = await page.$$('[class*=pagination_center]');
|
|
|
|
|
|
|
+ let searchTitle = await this.getTitle(page, '京东商品搜索');
|
|
|
|
|
+ //找页码信息
|
|
|
|
|
+ let outObj = {};
|
|
|
|
|
+ let pageHandle = await page.$$('[class*=quick-result]');
|
|
|
|
|
+ let currentPage = 1;
|
|
|
|
|
+ let totalPage = 1;
|
|
|
if(pageHandle && pageHandle.length > 0){
|
|
if(pageHandle && pageHandle.length > 0){
|
|
|
- currentPage = await page.$eval('[class*=pagination_center] [class*=active]', el => el.innerText);
|
|
|
|
|
- let totalInfo = await page.$eval('[class*=pagination_total]', el => el.innerText);
|
|
|
|
|
- totalPage = totalInfo.replace('共', '').replace('页', '');
|
|
|
|
|
|
|
+ let pageContent = await page.$eval('[class*=quick-result]', el => el.innerText);
|
|
|
|
|
+ pageContent = pageContent.replace('\n', '').replace('\n', '');
|
|
|
|
|
+ currentPage =pageContent.split('/')[0];
|
|
|
|
|
+ totalPage = pageContent.split('/')[1];
|
|
|
|
|
+ }else{
|
|
|
|
|
+ let pageHandle = await page.$$('[class*=pagination_center]');
|
|
|
|
|
+ if(pageHandle && pageHandle.length > 0){
|
|
|
|
|
+ currentPage = await page.$eval('[class*=pagination_center] [class*=active]', el => el.innerText);
|
|
|
|
|
+ let totalInfo = await page.$eval('[class*=pagination_total]', el => el.innerText);
|
|
|
|
|
+ totalPage = totalInfo.replace('共', '').replace('页', '');
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
+ await this.initScroll('jd', page, Number(currentPage), Number(totalPage), searchTitle);
|
|
|
}
|
|
}
|
|
|
- await this.initScroll('jd', page, Number(currentPage), Number(totalPage), searchTitle);
|
|
|
|
|
|
|
+
|
|
|
}catch(e){
|
|
}catch(e){
|
|
|
this.addLoading = false;
|
|
this.addLoading = false;
|
|
|
this.showError(e);
|
|
this.showError(e);
|
|
@@ -863,7 +1113,7 @@
|
|
|
let authority = this.$refs.headerRef.authority.isAuthority;
|
|
let authority = this.$refs.headerRef.authority.isAuthority;
|
|
|
let page = await this.redBrowser.newPage();
|
|
let page = await this.redBrowser.newPage();
|
|
|
|
|
|
|
|
- let responseVideo = [];
|
|
|
|
|
|
|
+
|
|
|
let waitUntil = 'networkidle2';
|
|
let waitUntil = 'networkidle2';
|
|
|
waitUntil = this.initDevelop().waitUntil;
|
|
waitUntil = this.initDevelop().waitUntil;
|
|
|
await page.goto(url, {waitUntil : waitUntil});
|
|
await page.goto(url, {waitUntil : waitUntil});
|
|
@@ -978,7 +1228,7 @@
|
|
|
let authority = this.$refs.headerRef.authority.isAuthority;
|
|
let authority = this.$refs.headerRef.authority.isAuthority;
|
|
|
let page = await this.commonBrowser.newPage();
|
|
let page = await this.commonBrowser.newPage();
|
|
|
|
|
|
|
|
- let responseVideo = [];
|
|
|
|
|
|
|
+
|
|
|
let waitUntil = 'networkidle2';
|
|
let waitUntil = 'networkidle2';
|
|
|
waitUntil = this.initDevelop().waitUntil;
|
|
waitUntil = this.initDevelop().waitUntil;
|
|
|
await page.goto(url, {waitUntil : waitUntil});
|
|
await page.goto(url, {waitUntil : waitUntil});
|
|
@@ -1076,7 +1326,298 @@
|
|
|
})();
|
|
})();
|
|
|
},
|
|
},
|
|
|
|
|
|
|
|
- // 滚动到页面底部或者滚动次数固定
|
|
|
|
|
|
|
+ // 滚动到页面底部或者滚动次数固定 -- 淘宝和天猫和阿里巴巴的店铺主页
|
|
|
|
|
+ async initScrollShop(typeStr, page, currentPage, totalPage, searchTitle){
|
|
|
|
|
+ let gapTime = Number(this.initGap()) * 1000;
|
|
|
|
|
+ let outCurrent = 1,outTotal = 1;
|
|
|
|
|
+ if(typeStr == 'alibaba'){
|
|
|
|
|
+ let nextBtn = await page.$x("//button[contains(text(), '下一页 >')]");
|
|
|
|
|
+ if(nextBtn && nextBtn.length > 0){
|
|
|
|
|
+ let nextSibling = await page.$x("//button[contains(text(), '下一页 >')]/following-sibling::*[1]");
|
|
|
|
|
+ if(nextSibling && nextSibling.length > 0){
|
|
|
|
|
+ let page = await nextSibling[0].evaluate(el => el.innerText.trim());
|
|
|
|
|
+ if(page){
|
|
|
|
|
+ outCurrent = page.split('/')[0];
|
|
|
|
|
+ outTotal = page.split('/')[1];
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if(typeStr == 'jdShop'){
|
|
|
|
|
+ let pageHandle = await page.$$('[id^=J_topPage]');
|
|
|
|
|
+ if(pageHandle && pageHandle.length > 0){
|
|
|
|
|
+ let pageContent = await page.$eval('[id^=J_topPage] [class^=fp-text]', el => el.innerText);
|
|
|
|
|
+ outCurrent =pageContent.split('/')[0];
|
|
|
|
|
+ outTotal = pageContent.split('/')[1];
|
|
|
|
|
+ }else{
|
|
|
|
|
+ let pageHandle = await page.$$('[class=jPage]');
|
|
|
|
|
+ if(pageHandle && pageHandle.length > 0){
|
|
|
|
|
+ outCurrent = await page.$eval('[class=jPage] [class*=jPageCurrent]', el => el.innerText);
|
|
|
|
|
+ outTotal = await page.$$eval('[class=jPage] a', links => links[links.length - 2].textContent);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ let pageInfo = await page.evaluate((typeStr, outCurrent, outTotal) => {
|
|
|
|
|
+ let cHeight = document.documentElement.clientHeight;
|
|
|
|
|
+ let scrollHeight = document.body.scrollHeight;
|
|
|
|
|
+
|
|
|
|
|
+ let currentPage = -1,totalPage = -1;
|
|
|
|
|
+ let paginationDom = document.querySelectorAll('[class^=pagination]');
|
|
|
|
|
+ if(paginationDom && paginationDom.length > 0){
|
|
|
|
|
+ let pInfo = document.querySelector('[class^=pagination] [class=page-info]');
|
|
|
|
|
+ if(pInfo){ // 淘宝店铺
|
|
|
|
|
+ let pText = pInfo.innerText || '1/1';
|
|
|
|
|
+ currentPage = Number(pText.split('/')[0]) || -1;
|
|
|
|
|
+ totalPage = Number(pText.split('/')[1]) || -1;
|
|
|
|
|
+ }else{ //天猫店铺
|
|
|
|
|
+ pInfo = document.querySelector('[class^=ui-page-s-len]');
|
|
|
|
|
+ if(pInfo){
|
|
|
|
|
+ let pText = pInfo.innerText || '1/1';
|
|
|
|
|
+ currentPage = Number(pText.split('/')[0]) || -1;
|
|
|
|
|
+ totalPage = Number(pText.split('/')[1]) || -1;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if(typeStr == 'alibaba' || typeStr == 'jdShop'){
|
|
|
|
|
+ currentPage = outCurrent;
|
|
|
|
|
+ totalPage = outTotal;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return {'scrollHeight': scrollHeight, 'cHeight': cHeight, 'currentPage': currentPage, 'totalPage': totalPage}
|
|
|
|
|
+ }, typeStr, outCurrent, outTotal);
|
|
|
|
|
+
|
|
|
|
|
+ if(pageInfo.currentPage > 0){ // 返回当前页面大于0,特殊页面分页处理
|
|
|
|
|
+ currentPage = pageInfo.currentPage;
|
|
|
|
|
+ totalPage = pageInfo.totalPage;
|
|
|
|
|
+
|
|
|
|
|
+ for(let i = Number(currentPage); i < Number(totalPage)+1; i++){
|
|
|
|
|
+ let pValue = i + 1;
|
|
|
|
|
+ let itemTitle = searchTitle + '-' + i;
|
|
|
|
|
+
|
|
|
|
|
+ if(typeStr == 'jdShop'){
|
|
|
|
|
+ await new Promise(resolve => setTimeout(resolve, 1000)).then(async() => {
|
|
|
|
|
+ await page.evaluate(() => {
|
|
|
|
|
+ window.scrollTo({
|
|
|
|
|
+ top: 1500,
|
|
|
|
|
+ behavior: "smooth"
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ await new Promise(resolve => setTimeout(resolve, gapTime)).then(async() => {
|
|
|
|
|
+ const imgInfo = await page.evaluate((currentPage, totalPage, itemTitle, typeStr) => {
|
|
|
|
|
+ let outObj = {
|
|
|
|
|
+ title: itemTitle,
|
|
|
|
|
+ currentPage: currentPage,
|
|
|
|
|
+ totalPage: totalPage,
|
|
|
|
|
+ urls: [],
|
|
|
|
|
+ status: '1',
|
|
|
|
|
+ loading: false
|
|
|
|
|
+ };
|
|
|
|
|
+ //主图
|
|
|
|
|
+ let arr1 = document.querySelectorAll('[class*=goods-list] li[class*=gl-item]');
|
|
|
|
|
+ for(let i=0; i< arr1.length; i++){
|
|
|
|
|
+ let href = arr1[i].querySelector('[class^=jPic] a').href;
|
|
|
|
|
+ let id = arr1[i].querySelector('[class^=jPic] a').dataset.sku;
|
|
|
|
|
+ let title = arr1[i].querySelector('[class^=jDesc]') ? arr1[i].querySelector('[class^=jDesc]').innerText : '京东商品标题'+new Date().getTime();
|
|
|
|
|
+ let priceInt = arr1[i].querySelector('[class^=jdPrice]') ? arr1[i].querySelector('[class^=jdPrice]').innerText : '0';
|
|
|
|
|
+ let price = priceInt.replace('¥ ', '');
|
|
|
|
|
+ let realSales = arr1[i].querySelector('[class^=jExtra]') ? arr1[i].querySelector('[class^=jExtra]').innerText : '';
|
|
|
|
|
+ let mainPic = arr1[i].querySelector('[class^=jPic] img') ? arr1[i].querySelector('[class^=jPic] img').src : '';
|
|
|
|
|
+ let shopNameText = document.querySelector('[class=jShopHeader] a[href*="mall.jd.com"]') ? document.querySelector('[class=jShopHeader] a[href*="mall.jd.com"]').innerText : '';
|
|
|
|
|
+ let shopUrl = document.querySelector('[class=jShopHeader] a[href*="mall.jd.com"]') ? document.querySelector('[class=jShopHeader] a[href*="mall.jd.com"]').href : '';
|
|
|
|
|
+
|
|
|
|
|
+ let info = {
|
|
|
|
|
+ id: id,
|
|
|
|
|
+ title: title,
|
|
|
|
|
+ href: href,
|
|
|
|
|
+ price: price,
|
|
|
|
|
+ realSales: realSales,
|
|
|
|
|
+ shopNameText: shopNameText,
|
|
|
|
|
+ shopUrl: shopUrl,
|
|
|
|
|
+ mainPic: mainPic
|
|
|
|
|
+ }
|
|
|
|
|
+ outObj.urls.push(info);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ let nextHandle = document.querySelector('[id^=J_topPage] [class^=fp-next]');
|
|
|
|
|
+ if(nextHandle){
|
|
|
|
|
+ nextHandle.click({force: true});
|
|
|
|
|
+ }else{
|
|
|
|
|
+ nextHandle = document.querySelectorAll('[class=jPage] a');
|
|
|
|
|
+ if(nextHandle && nextHandle.length > 0){
|
|
|
|
|
+ let index = Number(nextHandle.length);
|
|
|
|
|
+ nextHandle[index-1].click({force: true});
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return outObj;
|
|
|
|
|
+ }, currentPage, totalPage, itemTitle, typeStr);
|
|
|
|
|
+
|
|
|
|
|
+ this.jdList.push(imgInfo);
|
|
|
|
|
+ });
|
|
|
|
|
+ }else{
|
|
|
|
|
+ let nextBtn = await page.$x("//button[contains(text(), '下一页 >')]");
|
|
|
|
|
+ if(typeStr == 'alibaba'){ // 阿里巴巴分页
|
|
|
|
|
+ let outObj = {
|
|
|
|
|
+ title: searchTitle + '-' + Number(i+1),
|
|
|
|
|
+ currentPage: 1,
|
|
|
|
|
+ totalPage: 1,
|
|
|
|
|
+ urls: [],
|
|
|
|
|
+ status: '1',
|
|
|
|
|
+ loading: false
|
|
|
|
|
+ };
|
|
|
|
|
+ if(nextBtn && nextBtn.length > 0){
|
|
|
|
|
+ let nextSibling = await page.$x("//button[contains(text(), '下一页 >')]/following-sibling::*[1]");
|
|
|
|
|
+ if(nextSibling && nextSibling.length > 0){
|
|
|
|
|
+ let page = await nextSibling[0].evaluate(el => el.innerText.trim());
|
|
|
|
|
+ if(page){
|
|
|
|
|
+ outObj.currentPage = Number(page.split('/')[0])+1;
|
|
|
|
|
+ outObj.totalPage = Number(page.split('/')[1]);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if(outObj.currentPage <= outObj.totalPage){
|
|
|
|
|
+ this.alibabaList.push(outObj);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const imgInfo = await page.evaluate((currentPage, totalPage, itemTitle, typeStr) => {
|
|
|
|
|
+ let outObj = {
|
|
|
|
|
+ title: itemTitle,
|
|
|
|
|
+ currentPage: currentPage,
|
|
|
|
|
+ totalPage: totalPage,
|
|
|
|
|
+ urls: [],
|
|
|
|
|
+ status: '1',
|
|
|
|
|
+ loading: false
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ let total = document.querySelector('[class^=pagination] [class=page-info]');
|
|
|
|
|
+ if(total){
|
|
|
|
|
+ outObj.currentPage = total.innerText.split('/')[0];
|
|
|
|
|
+ outObj.totalPage = total.innerText.split('/')[1];
|
|
|
|
|
+ }else{
|
|
|
|
|
+ total = document.querySelector('[class^=ui-page-s-len]');
|
|
|
|
|
+ if(total){
|
|
|
|
|
+ outObj.currentPage = total.innerText.split('/')[0];
|
|
|
|
|
+ outObj.totalPage = total.innerText.split('/')[1];
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ //主图
|
|
|
|
|
+ let arr1 = document.querySelectorAll('dl[class^=item]');
|
|
|
|
|
+ for(let i=0; i< arr1.length; i++){
|
|
|
|
|
+ let href = arr1[i].querySelector('[class^=photo] a').href;
|
|
|
|
|
+ let id = arr1[i].dataset.id;
|
|
|
|
|
+ let title = arr1[i].querySelector('[class^=item-name]') ? arr1[i].querySelector('[class^=item-name]').innerText : '淘宝商品'+new Date().getTime();
|
|
|
|
|
+ let priceInt = arr1[i].querySelector('[class^=c-price]') ? arr1[i].querySelector('[class^=c-price]').innerText : 0;
|
|
|
|
|
+ let price = isNaN(priceInt) ? '' : priceInt;
|
|
|
|
|
+ let realSales = arr1[i].querySelector('[class^=sale-area]') ? arr1[i].querySelector('[class^=sale-area]').innerText : '';
|
|
|
|
|
+ let mainPic = arr1[i].querySelector('[class^=photo] img') ? arr1[i].querySelector('[class^=photo] img').src : '';
|
|
|
|
|
+ let shopNameText = document.querySelector('a[class^=shop-name]') ? document.querySelector('a[class^=shop-name]').innerText : document.querySelector('a[class^=slogo-shopname]') ? document.querySelector('a[class^=slogo-shopname]').innerText : '';
|
|
|
|
|
+ let shopUrl = document.querySelector('a[class^=shop-name]') ? document.querySelector('a[class^=shop-name]').href : document.querySelector('a[class^=slogo-shopname]') ? document.querySelector('a[class^=slogo-shopname]').href : '';
|
|
|
|
|
+
|
|
|
|
|
+ let info = {
|
|
|
|
|
+ id: id,
|
|
|
|
|
+ title: title,
|
|
|
|
|
+ href: href,
|
|
|
|
|
+ price: price,
|
|
|
|
|
+ realSales: realSales,
|
|
|
|
|
+ shopNameText: shopNameText,
|
|
|
|
|
+ shopUrl: shopUrl,
|
|
|
|
|
+ mainPic: mainPic
|
|
|
|
|
+ }
|
|
|
|
|
+ outObj.urls.push(info);
|
|
|
|
|
+ }
|
|
|
|
|
+ let nextHandle = document.querySelectorAll('[class*=pagination-mini] a')[1];
|
|
|
|
|
+ if(nextHandle){
|
|
|
|
|
+ nextHandle.click({force: true});
|
|
|
|
|
+ }else{
|
|
|
|
|
+ nextHandle = document.querySelector('a[class^=ui-page-s-next]');
|
|
|
|
|
+ if(nextHandle){
|
|
|
|
|
+ nextHandle.click({force: true});
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return outObj;
|
|
|
|
|
+ }, currentPage, totalPage, itemTitle, typeStr);
|
|
|
|
|
+
|
|
|
|
|
+ if(typeStr != 'alibaba'){
|
|
|
|
|
+ this.tbList.push(imgInfo);
|
|
|
|
|
+ }else{
|
|
|
|
|
+ if(nextBtn && nextBtn.length > 0){
|
|
|
|
|
+ nextBtn[0].click({force: true});
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ await this.delay();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if(typeStr == 'alibaba'){
|
|
|
|
|
+ await this.alibabaBrowser.close();
|
|
|
|
|
+ }else if(typeStr == 'jdShop'){
|
|
|
|
|
+ await this.jdBrowser.close();
|
|
|
|
|
+ }else{
|
|
|
|
|
+ await this.tbBrowser.close();
|
|
|
|
|
+ }
|
|
|
|
|
+ this.addLoading = false;
|
|
|
|
|
+ }else{ // 滚动加载店铺主页
|
|
|
|
|
+ let scrollHeight = pageInfo.scrollHeight;
|
|
|
|
|
+ let cHeight = pageInfo.cHeight;
|
|
|
|
|
+ let num = Math.ceil(scrollHeight / cHeight);
|
|
|
|
|
+ let start = -1;
|
|
|
|
|
+ let scrollTime = this.initMs();
|
|
|
|
|
+ let scrollInt = setInterval(async() => {
|
|
|
|
|
+ if(this.tbBrowser && !this.tbBrowser.isConnected()){
|
|
|
|
|
+ clearInterval(scrollInt);
|
|
|
|
|
+ await this.tbBrowser.close();
|
|
|
|
|
+ this.tbBrowser = null;
|
|
|
|
|
+
|
|
|
|
|
+ this.tbList.map((item, index) => { //修改任务状态
|
|
|
|
|
+ if(item.status == '3'){
|
|
|
|
|
+ item.status = '1';
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ start ++;
|
|
|
|
|
+ let scrollHeight = await page.evaluate((start, typeStr) => {
|
|
|
|
|
+ let scrollHeight = document.body.scrollHeight;
|
|
|
|
|
+ let cHeight = document.documentElement.clientHeight;
|
|
|
|
|
+ window.scrollTo({
|
|
|
|
|
+ top: cHeight * start,
|
|
|
|
|
+ behavior: "smooth"
|
|
|
|
|
+ });
|
|
|
|
|
+ if(typeStr == 'tbCategory'){
|
|
|
|
|
+ let foundDom = document.querySelectorAll('[class^=container-]>div[class^=title-]')
|
|
|
|
|
+ if(foundDom && foundDom.length > 0){
|
|
|
|
|
+ scrollHeight = 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return scrollHeight;
|
|
|
|
|
+ }, start, typeStr);
|
|
|
|
|
+
|
|
|
|
|
+ if(scrollHeight > 0){
|
|
|
|
|
+ num = Math.ceil(scrollHeight / cHeight);
|
|
|
|
|
+ }else{
|
|
|
|
|
+ num = 0;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if(start > num || start > 300){ //防止页面过长,滚动300次自动停止
|
|
|
|
|
+ clearInterval(scrollInt);
|
|
|
|
|
+ await this.tbBrowser.close();
|
|
|
|
|
+ this.tbBrowser = null;
|
|
|
|
|
+ this.addLoading = false;
|
|
|
|
|
+ this.tbList.map((item, index) => { //修改任务状态
|
|
|
|
|
+ if(item.status == '3'){
|
|
|
|
|
+ item.status = '1';
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ }, scrollTime);
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ // 滚动到页面底部或者滚动次数固定 -- 京东和阿里巴巴的搜索列表页面
|
|
|
async initScroll(typeStr, page, currentPage, totalPage, searchTitle){
|
|
async initScroll(typeStr, page, currentPage, totalPage, searchTitle){
|
|
|
let pageInfo = await page.evaluate(() => {
|
|
let pageInfo = await page.evaluate(() => {
|
|
|
let cHeight = document.documentElement.clientHeight;
|
|
let cHeight = document.documentElement.clientHeight;
|