mirror of
https://github.com/primedigitaltech/azon_seeker.git
synced 2026-10-05 23:33:21 +08:00
fix: exclude hidden Amazon ad cards
This commit is contained in:
parent
6b4aa2306a
commit
1d60213a33
@ -60,6 +60,24 @@ const html = `
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section style="display: none">
|
||||
<span>Sponsored</span>
|
||||
<article data-asin="B000000009">
|
||||
<h3 aria-label="Sponsored Ad - hidden preloaded product">Hidden preloaded product</h3>
|
||||
<a href="/sspa/click?url=%2Fdp%2FB000000009">
|
||||
<img src="https://example.com/hidden.jpg" />
|
||||
</a>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<section aria-hidden="true">
|
||||
<span>Sponsored</span>
|
||||
<article data-asin="B000000010">
|
||||
<h3>Hidden accessibility product</h3>
|
||||
<a href="/dp/B000000010"><img src="https://example.com/hidden-aria.jpg" /></a>
|
||||
</article>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<aside id="rightResultsATF" data-component-type="sponsored-display">
|
||||
@ -107,6 +125,8 @@ async function main() {
|
||||
assert.equal(byAsin.get('B000000008')?.adFormat, 'video');
|
||||
assert.equal(byAsin.get('B000000008')?.placement, 'bottomOfSearch');
|
||||
assert.equal(items.filter((item) => item.asin === 'B000000008').length, 1);
|
||||
assert.equal(byAsin.has('B000000009'), false);
|
||||
assert.equal(byAsin.has('B000000010'), false);
|
||||
assert.deepEqual(
|
||||
items.map((item) => item.pageRank),
|
||||
[1, 2, 3, 4, 5, 6, 7, 8],
|
||||
|
||||
@ -32,11 +32,30 @@ export async function collectAmazonSearchPageData(_: SearchPageCollectorPayload)
|
||||
const text = (node: Element | null | undefined) =>
|
||||
(node?.textContent || '').replace(/\s+/g, ' ').trim();
|
||||
|
||||
const isVisible = (node: HTMLElement) =>
|
||||
!node.hidden &&
|
||||
node.getAttribute('aria-hidden') !== 'true' &&
|
||||
node.style.display !== 'none' &&
|
||||
node.style.visibility !== 'hidden';
|
||||
const isVisible = (node: HTMLElement) => {
|
||||
for (let current: HTMLElement | null = node; current; current = current.parentElement) {
|
||||
if (current.hidden || current.getAttribute('aria-hidden') === 'true') return false;
|
||||
const style = current.ownerDocument.defaultView?.getComputedStyle(current);
|
||||
if (
|
||||
style &&
|
||||
(style.display === 'none' ||
|
||||
style.visibility === 'hidden' ||
|
||||
style.visibility === 'collapse' ||
|
||||
style.opacity === '0' ||
|
||||
style.getPropertyValue('content-visibility') === 'hidden')
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// JSDOM has no layout engine, so computed-style checks above are the authoritative test path.
|
||||
// In Chromium, require the card or one of its key visual descendants to own a real render box.
|
||||
if (node.ownerDocument.documentElement.getClientRects().length === 0) return true;
|
||||
return [node, ...Array.from(node.querySelectorAll<HTMLElement>('img, h2, h3'))].some(
|
||||
(candidate) =>
|
||||
Array.from(candidate.getClientRects()).some((rect) => rect.width > 0 && rect.height > 0),
|
||||
);
|
||||
};
|
||||
|
||||
const decodeRepeatedly = (value: string) => {
|
||||
let decoded = value;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user