mirror of
https://github.com/primedigitaltech/azon_seeker.git
synced 2026-01-29 18:53:19 +08:00
feat: Modify determineHasNextPage
This commit is contained in:
parent
3a8110171f
commit
6f15a8bcb5
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "azon-seeker",
|
||||
"displayName": "Azon Seeker v0.7.1.1-beta",
|
||||
"displayName": "Azon Seeker v0.7.1.2-beta",
|
||||
"version": "0.7.2",
|
||||
"private": true,
|
||||
"description": "Starter modify by honestfox101 and PetrichorFun",
|
||||
|
||||
@ -14,15 +14,17 @@ defineProps<{
|
||||
<template>
|
||||
<n-card class="progress-report" title="数据获取情况">
|
||||
<n-timeline v-if="timelines.length > 0">
|
||||
<n-timeline-item
|
||||
v-for="(item, index) in timelines.toReversed()"
|
||||
:key="index"
|
||||
:type="item.type"
|
||||
:title="item.title"
|
||||
:time="item.time"
|
||||
>
|
||||
<div v-for="line in item.content.split('\n')">{{ line }}</div>
|
||||
</n-timeline-item>
|
||||
<n-infinite-scroll style="max-height: 40vh; padding-right: 16px" :distance="10">
|
||||
<n-timeline-item
|
||||
v-for="(item, index) in timelines.toReversed()"
|
||||
:key="index"
|
||||
:type="item.type"
|
||||
:title="item.title"
|
||||
:time="item.time"
|
||||
>
|
||||
<div v-for="line in item.content.split('\n')">{{ line }}</div>
|
||||
</n-timeline-item>
|
||||
</n-infinite-scroll>
|
||||
</n-timeline>
|
||||
<n-empty v-else size="large">
|
||||
<template #icon>
|
||||
|
||||
@ -118,20 +118,109 @@ export class AmazonSearchPageInjector extends BaseInjector {
|
||||
});
|
||||
}
|
||||
|
||||
public async determineHasNextPage() {
|
||||
// /**
|
||||
// * 检测当前亚马逊搜索页面是否有下一页,并自动点击翻页按钮。
|
||||
// *
|
||||
// * 该方法在页面上下文中执行,查找亚马逊标准分页按钮('.s-pagination-next'),
|
||||
// * 检查按钮是否未被禁用('s-pagination-disabled' 类),然后模拟用户点击。
|
||||
// * 点击前会随机等待 500-1000 毫秒以避免被识别为机器人。
|
||||
// *
|
||||
// * @returns `true` 表示有下一页且已点击翻页按钮,页面正在加载下一页内容;
|
||||
// * `false` 表示没有下一页(按钮不存在或被禁用)。
|
||||
// */
|
||||
// public async determineHasNextPage() {
|
||||
// return this.run(async () => {
|
||||
// const nextButton = document.querySelector<HTMLLinkElement>('.s-pagination-next');
|
||||
// if (nextButton) {
|
||||
// if (!nextButton.classList.contains('s-pagination-disabled')) {
|
||||
// await new Promise((resolve) => setTimeout(resolve, 500 + ~~(500 * Math.random())));
|
||||
// nextButton.click();
|
||||
// return true;
|
||||
// } else {
|
||||
// return false;
|
||||
// }
|
||||
// } else {
|
||||
// return false;
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// /**
|
||||
// * 检测并执行亚马逊搜索页面翻页,等待页面刷新完成。
|
||||
// * @returns 能否翻页(true=翻页成功,false=没有下一页或翻页失败)
|
||||
// */
|
||||
// public async determineHasNextPage(): Promise<boolean> {
|
||||
// return this.run(async () => {
|
||||
// const nextButton = document.querySelector<HTMLLinkElement>('.s-pagination-next');
|
||||
|
||||
// if (nextButton && !nextButton.classList.contains('s-pagination-disabled')) {
|
||||
// // 记录当前页码
|
||||
// const initialPage = await this.getCurrentPage();
|
||||
|
||||
// // 随机等待后点击
|
||||
// await new Promise((resolve) => setTimeout(resolve, 500 + ~~(500 * Math.random())));
|
||||
// nextButton.click();
|
||||
|
||||
// // 等待页面刷新完成
|
||||
// await this.waitForPageLoaded();
|
||||
|
||||
// // 验证翻页是否成功
|
||||
// const newPage = await this.getCurrentPage();
|
||||
|
||||
// // 只有页码真正变化才算翻页成功
|
||||
// return newPage !== null && newPage !== initialPage;
|
||||
// }
|
||||
|
||||
// return false;
|
||||
// });
|
||||
// }
|
||||
|
||||
/**
|
||||
* 检测并执行亚马逊搜索页面翻页,通过 URL 变化确认刷新完成。
|
||||
* @returns 能否翻页(true=已翻页,false=已是最后一页)
|
||||
*/
|
||||
public async determineHasNextPage(): Promise<boolean> {
|
||||
return this.run(async () => {
|
||||
const nextButton = document.querySelector<HTMLLinkElement>('.s-pagination-next');
|
||||
if (nextButton) {
|
||||
if (!nextButton.classList.contains('s-pagination-disabled')) {
|
||||
await new Promise((resolve) => setTimeout(resolve, 500 + ~~(500 * Math.random())));
|
||||
nextButton.click();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
|
||||
if (nextButton && !nextButton.classList.contains('s-pagination-disabled')) {
|
||||
// 1. 记录当前 URL
|
||||
const initialUrl = window.location.href;
|
||||
|
||||
// 2. 随机等待后点击
|
||||
await new Promise((resolve) => setTimeout(resolve, 500 + ~~(500 * Math.random())));
|
||||
nextButton.click();
|
||||
|
||||
// 3. 等待 URL 变化(表示页面已开始导航)
|
||||
await new Promise<void>((resolve) => {
|
||||
const checkUrl = () => {
|
||||
if (window.location.href !== initialUrl) {
|
||||
resolve();
|
||||
} else {
|
||||
setTimeout(checkUrl, 100);
|
||||
}
|
||||
};
|
||||
checkUrl();
|
||||
});
|
||||
|
||||
// 4. 等待页面稳定(document.readyState === 'complete')
|
||||
await new Promise<void>((resolve) => {
|
||||
const checkReadyState = () => {
|
||||
if (document.readyState === 'complete') {
|
||||
resolve();
|
||||
} else {
|
||||
setTimeout(checkReadyState, 100);
|
||||
}
|
||||
};
|
||||
checkReadyState();
|
||||
});
|
||||
|
||||
// 5. 额外等待确保内容加载
|
||||
await new Promise((resolve) => setTimeout(resolve, 500));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@ import { usePageWorker } from '~/page-worker';
|
||||
import MulInputModal from '~/sidepanel/views/components/MulInputModal.vue';
|
||||
const message = useMessage();
|
||||
const showModal = ref(false);
|
||||
|
||||
const initKeysCount = ref(0);
|
||||
//#region Initial Page Worker
|
||||
const worker = usePageWorker('amazon', { objects: ['search'] });
|
||||
worker.on('error', ({ message: msg }) => {
|
||||
@ -39,7 +39,8 @@ const launch = async () => {
|
||||
content: `关键词: ${kws[0]} 数据采集开始`,
|
||||
},
|
||||
];
|
||||
timelines.value.push();
|
||||
// timelines.value.push();
|
||||
initKeysCount.value = kws.length;
|
||||
await worker.runSearchPageTask(kws, {
|
||||
progress: (remains) => {
|
||||
if (remains.length > 0) {
|
||||
@ -79,15 +80,26 @@ const clickInputButton = (e: MouseEvent) => {
|
||||
|
||||
const handleModalConfirm = (keys: string[]) => {
|
||||
keywordsList.value = keys;
|
||||
// console.log(keys);
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="search-page-entry">
|
||||
<header-title @click-mul-input="clickInputButton">Amazon Search</header-title>
|
||||
<div class="overview-card">
|
||||
<span style="display: inline-block">总览:</span>
|
||||
<span style="display: inline-block"> 总关键词数量: {{ initKeysCount }} 条</span>
|
||||
<span style="display: inline-block"> 当前剩余关键词数量: {{ keywordsList.length }} 条</span>
|
||||
<span style="display: inline-block">
|
||||
现在爬到第
|
||||
{{
|
||||
initKeysCount - keywordsList.length + 1 ? '---' : initKeysCount - keywordsList.length + 1
|
||||
}}
|
||||
条</span
|
||||
>
|
||||
</div>
|
||||
<div class="interactive-section">
|
||||
<n-infinite-scroll style="max-height: 60vh; padding-right: 16px" :distance="10">
|
||||
<n-infinite-scroll style="max-height: 40vh; padding-right: 16px" :distance="10">
|
||||
<n-dynamic-input
|
||||
:disabled="worker.isRunning.value"
|
||||
v-model:value="keywordsList"
|
||||
@ -100,8 +112,7 @@ const handleModalConfirm = (keys: string[]) => {
|
||||
placeholder="请输入关键词采集信息"
|
||||
/>
|
||||
</n-infinite-scroll>
|
||||
<!-- <n-dynamic-input :disabled="worker.isRunning.value" v-model:value="keywordsList" :min="1" :max="999"
|
||||
class="search-input-box" autosize size="large" round placeholder="请输入关键词采集信息" /> -->
|
||||
|
||||
<n-button
|
||||
v-if="!worker.isRunning.value"
|
||||
type="primary"
|
||||
@ -129,8 +140,9 @@ const handleModalConfirm = (keys: string[]) => {
|
||||
<n-alert title="Warning" type="warning"> 警告,在插件运行期间请勿与浏览器交互。 </n-alert>
|
||||
</div>
|
||||
<progress-report class="progress-report" :timelines="timelines" />
|
||||
|
||||
<MulInputModal v-model:show-modal="showModal" @confirm="handleModalConfirm"> </MulInputModal>
|
||||
</div>
|
||||
<MulInputModal v-model:show-modal="showModal" @confirm="handleModalConfirm"> </MulInputModal>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@ -158,6 +170,18 @@ const handleModalConfirm = (keys: string[]) => {
|
||||
}
|
||||
}
|
||||
|
||||
.overview-card {
|
||||
border-radius: 10px;
|
||||
width: 80%;
|
||||
outline: 1px #00000020 dashed;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: stretch;
|
||||
gap: 15px;
|
||||
padding: 15px 25px;
|
||||
}
|
||||
|
||||
.running-tip-section {
|
||||
border-radius: 10px;
|
||||
cursor: wait;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user