Я работаю над кодом кукловода и столкнулся с проблемой, которую хочу лучше понять.
При работе с XPaths у меня возникают проблемы с пониманием того, почему этот код работает:
await page.goto(url)
//identify element with absolute xpath then click
const b = (await page.$x("<absolute XPath>"))[0]
//Works!
b.click()
//But this won't work
const b = (await page.$x("<absolute XPath>"))
b.click()
//And this won't work
b.click()
const b = await page.$x("<absolute XPath>")
Почему заключение оператора await page.$x в круглых скобках работает? Что там происходит?
Когда я удаляю круглые скобки, удаляю индекс массива, любые изменения... и т. д., я получаю стандартные ошибки, такие как, например, "щелчок не является функцией b". У меня сложилось впечатление, что я оцениваю абсолютный XPath... один элемент. Откуда взялся массив? И что происходит, когда все это заключено в круглые скобки и указан элемент массива, который вычисляет это идеально и прямо к нужному элементу без проблем?
Буду признателен за любую информацию или ссылки на нужную информацию. Я надеюсь, что это не то, что я пропустил в документах
Вы действительно хотите переключиться на css, когда это возможно, из соображений производительности, а также потому, что код будет чище.



Это не parenthesis, но [0] все меняет.
xpath может найти много элементов, поэтому он всегда возвращает список/массив, даже если он находит только один элемент или ничего, и вам нужно использовать [0], чтобы получить первый элемент из списка. Или вы можете использовать другой индекс для получения другого элемента из списка (если список длиннее). (Конечно, список может быть пустым и [0] может вызвать ошибку)
Вы не можете сделать list.click(). Вы должны сделать first = list[0] и позже first.click(). Или вы можете использовать forEach для выполнения click для всех элементов в списке.
Нужно только parenthesis выполнять команды в правильном порядке - сначала await, потом [0].
Если вы не используете parenthesis, он попытается сначала выполнить [0], а затем await.
Так что вы могли бы переписать его на несколько строк
const all_results = await page.$x("<XPath>")
const first = all_results[0]
first.click()
или пиши короче
const all_results = await page.$x("<XPath>")
all_results[0].click()
или
const first = (await page.$x("<XPath>"))[0]
first.click()
Если бы вы использовали console.info(b), вы бы увидели, что у вас действительно есть в этой переменной в разных версиях.
КСТАТИ:
То же самое может быть и с селектором CSS — page.$("<css selection>") — он также возвращает список/массив.
Обновлено:
Как @ggorlen он упомянул в комментарии, вы можете назначить первый элемент, используя массив слева.
[first] = await page.$x("<XPath>")
first.click()
Есть еще const [el] = await page.$x("...").
@ggorlen спасибо, я не специалист по puppeteer и javascript - я использую xpath в Python.
Большое спасибо вам обоим!!! Красиво объяснил, теперь понял!
это не скобки, а
[0]все меняет.xpathможет найти много элементов, поэтому он всегда возвращает список (даже если он находит только один элемент или ничего), и вам нужно использовать[0], чтобы получить первый элемент из списка - вы не можете сделатьlist.click(). Вы должны сделатьfirst = list[0]и позжеfirst.click()