大家,我最近一直在尝试实现Google表单的自动化功能,但对此下拉菜单感到很困惑。
我只是无法从弹出下拉菜单中选择所需的值。由于下拉列表自动完成,如果我使用puppeteer在字段中写ie。联合王国,当使用空格字符时,它会自动将表格自动填写为阿拉伯联合酋长国(联合王国之后的第一个值),并输入到表格中并选择第一个值。
我做了一个虚拟的Google表单来模拟我的情况:
https://docs.google.com/forms/d/e/1FAIpQLSeY-5GpBQ7ww3qm-EUn5ENTl-KOVD02PIwlyblw8ItjfOfhtQ/viewform?usp=sf_link
谢谢大家!
最佳答案
我尝试,这就是我编写的代码。
笔记:
我不是用通常的鼠标方法通过单击和选择元素来编写此代码的,因为在出错时很难调试。
您必须声明下拉列表的根选择器,如果有多个下拉列表,则必须自己找到合适的选择器。
并且不要忘记在此代码中选择desiredOption
。
const puppeteer = require ('puppeteer')
const formURL = 'https://docs.google.com/forms/d/e/1FAIpQLSeY-5GpBQ7ww3qm-EUn5ENTl-KOVD02PIwlyblw8ItjfOfhtQ/viewform'
const dropDownRootElemSelector = 'div.quantumWizMenuPaperselectEl'
const desiredOption = 'United Kingdom' // Write down your desired option here
;(async () => {
const browser = await puppeteer.launch ({
headless: false,
devtools: false
})
const [page] = await browser.pages ()
const open = await page.goto ( formURL, { waitUntil: 'networkidle0', timeout: 0 } )
while ( await page.evaluate ( dropDownRootElemSelector => !document.querySelector(dropDownRootElemSelector).classList.contains('isFocused'), dropDownRootElemSelector ) ) {
await page.keyboard.press('Tab')
await page.waitFor(250)
}
await page.keyboard.press('Space')
while ( await page.evaluate ( dropDownRootElemSelector => document.querySelector(dropDownRootElemSelector).lastElementChild.childElementCount === 0, dropDownRootElemSelector ) ) {
await page.waitFor(200)
}
const optionExist = async () => {
await page.evaluate ( (dropDownRootElemSelector, desiredOption) => {
var optionsDropDown = []
document.querySelectorAll( dropDownRootElemSelector + ' > div[role="presentation"] ~ div[role="presentation"] > div[role="option"] ~ div[role="presentation"] ~ div[role="option"]').forEach(elem => optionsDropDown.push(elem.textContent) )
return ( optionsDropDown.includes(desiredOption) )
}, dropDownRootElemSelector, desiredOption)
}
if ( optionExist () ) {
await page.keyboard.press('ArrowDown')
}
while ( await page.evaluate ( (dropDownRootElemSelector) => document.querySelector( dropDownRootElemSelector + ' > div[role="presentation"] ~ div[role="presentation"] > div[role="option"] ~ div[role="presentation"] ~ div[role="option"].isSelected') === null, dropDownRootElemSelector ) ) {
await page.waitFor(250)
}
while ( optionExist () && await page.evaluate ( (dropDownRootElemSelector, desiredOption) => document.querySelector( dropDownRootElemSelector + ' > div[role="presentation"] ~ div[role="presentation"] > div[role="option"] ~ div[role="presentation"] ~ div[role="option"].isSelected').dataset.value !== desiredOption, dropDownRootElemSelector, desiredOption) ) {
// console.log ( await page.evaluate ( (dropDownRootElemSelector) => document.querySelector( dropDownRootElemSelector + ' > div[role="presentation"] ~ div[role="presentation"] > div[role="option"] ~ div[role="presentation"] ~ div[role="option"].isSelected').dataset.value, dropDownRootElemSelector ) )
await page.keyboard.press('ArrowDown')
await page.waitFor(250)
}
await page.keyboard.press('Enter')
})()
如果您有多个下拉菜单,那么这很简单。
您可以在选择器上添加唯一标识符,对于本示例,可以为每个下拉列表添加
[data-item-id="ID_NUMBER"]
。不要忘记通过在每个下拉代码的末尾放置
await page.waitFor(1000)
来增加延迟,以避免由于快速运行的脚本而导致未选择的下拉菜单。为多个下拉菜单添加了新的答案:
const puppeteer = require ('puppeteer')
const formURL = 'https://docs.google.com/forms/d/e/1FAIpQLSeY-5GpBQ7ww3qm-EUn5ENTl-KOVD02PIwlyblw8ItjfOfhtQ/viewform'
const dropDownRootCountrySelector = '[data-item-id="1058991397"] > div.quantumWizMenuPaperselectEl'
const dropDownRootZoneSelector = '[data-item-id="50474009"] > div.quantumWizMenuPaperselectEl'
const desiredCountry = 'United Kingdom' // Write down your desired option here
const desiredZone = 'Europe' // Write down your desired option here
;(async () => {
const browser = await puppeteer.launch ({
headless: false,
devtools: false
})
const [page] = await browser.pages ()
const open = await page.goto ( formURL, { waitUntil: 'networkidle0', timeout: 0 } )
// FIRST DROPDOWN => COUNTRY
while ( await page.evaluate ( dropDownRootCountrySelector => !document.querySelector(dropDownRootCountrySelector).classList.contains('isFocused'), dropDownRootCountrySelector ) ) {
await page.keyboard.press('Tab')
await page.waitFor(250)
}
await page.keyboard.press('Space')
while ( await page.evaluate ( dropDownRootCountrySelector => document.querySelector(dropDownRootCountrySelector).lastElementChild.childElementCount === 0, dropDownRootCountrySelector ) ) {
await page.waitFor(200)
}
const optionExistCountry = async () => {
await page.evaluate ( (dropDownRootCountrySelector, desiredCountry) => {
var optionsDropDown = []
document.querySelectorAll( dropDownRootCountrySelector + ' > div[role="presentation"] ~ div[role="presentation"] > div[role="option"] ~ div[role="presentation"] ~ div[role="option"]').forEach(elem => optionsDropDown.push(elem.textContent) )
return ( optionsDropDown.includes(desiredCountry) )
}, dropDownRootCountrySelector, desiredCountry)
}
if ( optionExistCountry () ) {
await page.keyboard.press('ArrowDown')
}
while ( await page.evaluate ( (dropDownRootCountrySelector) => document.querySelector( dropDownRootCountrySelector + ' > div[role="presentation"] ~ div[role="presentation"] > div[role="option"] ~ div[role="presentation"] ~ div[role="option"].isSelected') === null, dropDownRootCountrySelector ) ) {
await page.waitFor(250)
}
while ( optionExistCountry () && await page.evaluate ( (dropDownRootCountrySelector, desiredCountry) => document.querySelector( dropDownRootCountrySelector + ' > div[role="presentation"] ~ div[role="presentation"] > div[role="option"] ~ div[role="presentation"] ~ div[role="option"].isSelected').dataset.value !== desiredCountry, dropDownRootCountrySelector, desiredCountry) ) {
// console.log ( await page.evaluate ( (dropDownRootCountrySelector) => document.querySelector( dropDownRootCountrySelector + ' > div[role="presentation"] ~ div[role="presentation"] > div[role="option"] ~ div[role="presentation"] ~ div[role="option"].isSelected').dataset.value, dropDownRootCountrySelector ) )
await page.keyboard.press('ArrowDown')
await page.waitFor(250)
}
await page.keyboard.press('Enter')
await page.waitFor(1000)
// SECOND DROPDOWN => ZONE
while ( await page.evaluate ( dropDownRootZoneSelector => !document.querySelector(dropDownRootZoneSelector).classList.contains('isFocused'), dropDownRootZoneSelector ) ) {
await page.keyboard.press('Tab')
await page.waitFor(250)
}
await page.keyboard.press('Space')
while ( await page.evaluate ( dropDownRootZoneSelector => document.querySelector(dropDownRootZoneSelector).lastElementChild.childElementCount === 0, dropDownRootZoneSelector ) ) {
await page.waitFor(200)
}
const optionExistZone = async () => {
await page.evaluate ( (dropDownRootZoneSelector, desiredZone) => {
var optionsDropDown = []
document.querySelectorAll( dropDownRootZoneSelector + ' > div[role="presentation"] ~ div[role="presentation"] > div[role="option"] ~ div[role="presentation"] ~ div[role="option"]').forEach(elem => optionsDropDown.push(elem.textContent) )
return ( optionsDropDown.includes(desiredZone) )
}, dropDownRootZoneSelector, desiredZone)
}
if ( optionExistZone () ) {
await page.keyboard.press('ArrowDown')
}
while ( await page.evaluate ( (dropDownRootZoneSelector) => document.querySelector( dropDownRootZoneSelector + ' > div[role="presentation"] ~ div[role="presentation"] > div[role="option"] ~ div[role="presentation"] ~ div[role="option"].isSelected') === null, dropDownRootZoneSelector ) ) {
await page.waitFor(250)
}
while ( optionExistZone () && await page.evaluate ( (dropDownRootZoneSelector, desiredZone) => document.querySelector( dropDownRootZoneSelector + ' > div[role="presentation"] ~ div[role="presentation"] > div[role="option"] ~ div[role="presentation"] ~ div[role="option"].isSelected').dataset.value !== desiredZone, dropDownRootZoneSelector, desiredZone) ) {
// console.log ( await page.evaluate ( (dropDownRootZoneSelector) => document.querySelector( dropDownRootZoneSelector + ' > div[role="presentation"] ~ div[role="presentation"] > div[role="option"] ~ div[role="presentation"] ~ div[role="option"].isSelected').dataset.value, dropDownRootZoneSelector ) )
await page.keyboard.press('ArrowDown')
await page.waitFor(250)
}
await page.keyboard.press('Enter')
})()