mirror of
https://github.com/primedigitaltech/azon_seeker.git
synced 2026-07-21 21:42:01 +08:00
fix/detail-page-image (#25)
* fix: fix can`t get imgurls on the page * fix: 优化详情页图片下载逻辑,添加加载等待重试机制 * perf: 为打开see full view添加兜底机制 * fix(amazon): 使用 ul 类名 XPath 抓取五点描述 chore: 将扩展 displayName 更新为 v0.7.1.10-beta Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
2c503a9ab6
commit
b062d96742
1
.gitignore
vendored
1
.gitignore
vendored
@ -8,6 +8,7 @@
|
|||||||
*.pem
|
*.pem
|
||||||
*.xpi
|
*.xpi
|
||||||
*.zip
|
*.zip
|
||||||
|
*.7z
|
||||||
dist
|
dist
|
||||||
dist-ssr
|
dist-ssr
|
||||||
extension/manifest.json
|
extension/manifest.json
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "azon-seeker",
|
"name": "azon-seeker",
|
||||||
"displayName": "Azon Seeker v0.7.1.7-beta",
|
"displayName": "Azon Seeker v0.7.1.10-beta",
|
||||||
"version": "0.7.2",
|
"version": "0.7.2",
|
||||||
"private": true,
|
"private": true,
|
||||||
"description": "Starter modify by honestfox101 and PetrichorFun",
|
"description": "Starter modify by honestfox101 and PetrichorFun",
|
||||||
|
|||||||
@ -16,6 +16,7 @@ export const isFirefox = navigator.userAgent.includes('Firefox');
|
|||||||
|
|
||||||
// export const remoteHost = __DEV__ ? '127.0.0.1:8000' : '47.251.4.191:8000';
|
// export const remoteHost = __DEV__ ? '127.0.0.1:8000' : '47.251.4.191:8000';
|
||||||
// export const remoteHost = __DEV__ ? '127.0.0.1:18000' : 'vm8nc3zr-18000.usw2.devtunnels.ms';
|
// export const remoteHost = __DEV__ ? '127.0.0.1:18000' : 'vm8nc3zr-18000.usw2.devtunnels.ms';
|
||||||
export const remoteHost = __DEV__ ? 'ogsm-dev.rekeymed.com:8888' : 'amzplugin.rekeymed.com';
|
// export const remoteHost = __DEV__ ? 'ogsm-dev.rekeymed.com:8888' : 'amzplugin.rekeymed.com';
|
||||||
|
export const remoteHost = __DEV__ ? '127.0.0.1:18000' : 'amzplugin.rekeymed.com';
|
||||||
// export const remoteHost = __DEV__ ? '127.0.0.1:18000' : 'amzplugin.rekeymed.com';
|
// export const remoteHost = __DEV__ ? '127.0.0.1:18000' : 'amzplugin.rekeymed.com';
|
||||||
// export const remoteHost = '47.251.4.191:8000';
|
// export const remoteHost = '47.251.4.191:8000';
|
||||||
|
|||||||
@ -22,7 +22,16 @@ const httpClient = createAlova({
|
|||||||
method.config.headers['x-public-key'] = publicKeyBase64Data;
|
method.config.headers['x-public-key'] = publicKeyBase64Data;
|
||||||
},
|
},
|
||||||
responded: {
|
responded: {
|
||||||
onSuccess: (response) => response.json(),
|
// 使用 text() 而不是 json() 来避免 Response body 被重复读取的问题
|
||||||
|
// 参考: https://github.com/alovajs/alova/issues/XXX
|
||||||
|
onSuccess: async (response) => {
|
||||||
|
const text = await response.text();
|
||||||
|
// 检查空响应
|
||||||
|
if (!text || text.trim() === '') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return JSON.parse(text);
|
||||||
|
},
|
||||||
onError: (response: Response) => {
|
onError: (response: Response) => {
|
||||||
const message = useMessage();
|
const message = useMessage();
|
||||||
message.error(`HTTP Error: ${response.status}`);
|
message.error(`HTTP Error: ${response.status}`);
|
||||||
|
|||||||
@ -490,11 +490,17 @@ export class AmazonDetailPageInjector extends BaseInjector {
|
|||||||
public async getImageUrls() {
|
public async getImageUrls() {
|
||||||
return this.run(async () => {
|
return this.run(async () => {
|
||||||
const overlay = document.querySelector<HTMLElement>('.overlayRestOfImages');
|
const overlay = document.querySelector<HTMLElement>('.overlayRestOfImages');
|
||||||
|
|
||||||
if (overlay) {
|
if (overlay) {
|
||||||
if (document.querySelector<HTMLElement>('#ivThumbs')!.getClientRects().length === 0) {
|
if (document.querySelector<HTMLElement>('#ivThumbs')!.getClientRects().length === 0) {
|
||||||
overlay.click();
|
// Click to see full view
|
||||||
|
document.querySelector<HTMLElement>('#canvasCaption > a')?.click();
|
||||||
await new Promise((resolve) => setTimeout(resolve, 1000));
|
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// finally click to see full view if not clicked before
|
||||||
|
document.querySelector<HTMLElement>('#canvasCaption > a')?.click();
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||||
}
|
}
|
||||||
let script = document.evaluate(
|
let script = document.evaluate(
|
||||||
`//script[starts-with(text(), "\nP.when(\'A\').register") or contains(text(), "\nP.when('A').register")]`,
|
`//script[starts-with(text(), "\nP.when(\'A\').register") or contains(text(), "\nP.when('A').register")]`,
|
||||||
@ -512,7 +518,46 @@ export class AmazonDetailPageInjector extends BaseInjector {
|
|||||||
/(?<="large":")https:\/\/m.media-amazon.com\/images\/I\/[\w\d\.\-+]+(?=")/g,
|
/(?<="large":")https:\/\/m.media-amazon.com\/images\/I\/[\w\d\.\-+]+(?=")/g,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
document.querySelector<HTMLElement>('header > [data-action="a-popover-close"]')?.click();
|
|
||||||
|
if (urls.length === 0) {
|
||||||
|
const divs: NodeListOf<HTMLDivElement> =
|
||||||
|
document.querySelectorAll('.ivRow div.ivThumbImage');
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 500 + ~~(500 * Math.random())));
|
||||||
|
for (const div of divs) {
|
||||||
|
// click div com
|
||||||
|
div.click();
|
||||||
|
|
||||||
|
// wait for image to load
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 500 + ~~(500 * Math.random())));
|
||||||
|
|
||||||
|
// if img src is not loading gif, then get url and break, otherwise continue to wait, with a max retry count to avoid infinite loop
|
||||||
|
let retryCount = 0;
|
||||||
|
const maxRetries = 5;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
const loadingGifUrl =
|
||||||
|
'https://m.media-amazon.com/images/G/01/ui/loadIndicators/loading-large_labeled._CB485921664_.gif';
|
||||||
|
// get img dom
|
||||||
|
const imgDom = document.querySelector('#ivLargeImage > img');
|
||||||
|
|
||||||
|
// get url from img dom src attribute
|
||||||
|
if (imgDom && 'src' in imgDom && imgDom.src !== loadingGifUrl) {
|
||||||
|
urls.push(imgDom.src as string);
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
// wait for 500ms and try again
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 500 + ~~(500 * Math.random())));
|
||||||
|
retryCount++;
|
||||||
|
if (retryCount >= maxRetries) {
|
||||||
|
console.error('在detail页面下载图片,已达最大重试次数:');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.querySelector<HTMLElement>('body > div.a-modal-scroller.a-declarative')?.click();
|
||||||
return urls;
|
return urls;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -621,9 +666,9 @@ export class AmazonDetailPageInjector extends BaseInjector {
|
|||||||
}
|
}
|
||||||
return nodes.length > 0 ? nodes : undefined;
|
return nodes.length > 0 ? nodes : undefined;
|
||||||
};
|
};
|
||||||
const abouts = $x(
|
const abouts = $x<HTMLElement>(
|
||||||
`//*[normalize-space(text())='About this item']/following-sibling::ul[1]/li`,
|
`(//ul[contains(concat(' ', normalize-space(@class), ' '), ' a-unordered-list ') and contains(concat(' ', normalize-space(@class), ' '), ' a-vertical ') and contains(concat(' ', normalize-space(@class), ' '), ' a-spacing-mini ')])[1]/li`,
|
||||||
)?.map((el) => el.innerText);
|
)?.map((el) => el.innerText.trim());
|
||||||
const brand = $x(`//*[./span[normalize-space(text())='Brand']]/following-sibling::*[1]`)?.[0]
|
const brand = $x(`//*[./span[normalize-space(text())='Brand']]/following-sibling::*[1]`)?.[0]
|
||||||
.innerText;
|
.innerText;
|
||||||
const flavor = $x(
|
const flavor = $x(
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user