(Puppeteer) 有没有办法通过 x, y 获取元素查询?
(Puppeteer) Is there a way to get element query by x, y?
我想通过传递 x,y 坐标来获取元素查询选择器。
或者满足坐标的元素很少
也许我可以做 mouse.click(x, y) 然后获取点击的元素,但我不希望页面采取任何操作只获取元素的查询。
有可能吗?
你首先要考虑到你可能会在同一个位置上得到很多元素,包括主要的HTML元素。
首先,您需要获取所有元素:
Array.prototype.slice.call(document.getElementsByTagName("*"))
然后,我们现在每个元素都有一个名为 getClientRects
的函数,它将 return 一个 "boxes" 的数组。
在此基础上,我们可以筛选出您需要的坐标中所有具有一个框的元素:
var x = 150;
var y = 1250;
Array.prototype.slice.call(document.getElementsByTagName("*")).filter(e =>
Array.prototype.slice.call(e.getClientRects()).find(rect =>
rect.top <= x && rect.bottom >= x && rect.left <= y && rect.right >= y))
您可以在 Puppeteer 的 evaluate
调用中做类似的事情。
如果您只需要视口坐标的最顶层元素,您可以尝试 DocumentOrShadowRoot.elementFromPoint()
. If you need to compose a unique selector, you can try to process element array from the DocumentOrShadowRoot.elementsFromPoint()
(在下面的示例中添加更多检查 — 类、id、属性、子项计数和顺序等) :
'use strict';
const puppeteer = require('puppeteer');
(async function main() {
try {
const browser = await puppeteer.launch();
const [page] = await browser.pages();
await page.goto('https://example.org/');
console.log(await page.evaluate(() => {
return document.elementFromPoint(100, 100).tagName;
}));
console.log(await page.evaluate(() => {
return document.elementsFromPoint(100, 100)
.map(({ tagName }) => tagName).reverse().join(' > ');
}));
await browser.close();
} catch (err) {
console.error(err);
}
})();
DIV
HTML > BODY > DIV
我想通过传递 x,y 坐标来获取元素查询选择器。
或者满足坐标的元素很少
也许我可以做 mouse.click(x, y) 然后获取点击的元素,但我不希望页面采取任何操作只获取元素的查询。
有可能吗?
你首先要考虑到你可能会在同一个位置上得到很多元素,包括主要的HTML元素。
首先,您需要获取所有元素:
Array.prototype.slice.call(document.getElementsByTagName("*"))
然后,我们现在每个元素都有一个名为 getClientRects
的函数,它将 return 一个 "boxes" 的数组。
在此基础上,我们可以筛选出您需要的坐标中所有具有一个框的元素:
var x = 150;
var y = 1250;
Array.prototype.slice.call(document.getElementsByTagName("*")).filter(e =>
Array.prototype.slice.call(e.getClientRects()).find(rect =>
rect.top <= x && rect.bottom >= x && rect.left <= y && rect.right >= y))
您可以在 Puppeteer 的 evaluate
调用中做类似的事情。
如果您只需要视口坐标的最顶层元素,您可以尝试 DocumentOrShadowRoot.elementFromPoint()
. If you need to compose a unique selector, you can try to process element array from the DocumentOrShadowRoot.elementsFromPoint()
(在下面的示例中添加更多检查 — 类、id、属性、子项计数和顺序等) :
'use strict';
const puppeteer = require('puppeteer');
(async function main() {
try {
const browser = await puppeteer.launch();
const [page] = await browser.pages();
await page.goto('https://example.org/');
console.log(await page.evaluate(() => {
return document.elementFromPoint(100, 100).tagName;
}));
console.log(await page.evaluate(() => {
return document.elementsFromPoint(100, 100)
.map(({ tagName }) => tagName).reverse().join(' > ');
}));
await browser.close();
} catch (err) {
console.error(err);
}
})();
DIV
HTML > BODY > DIV