Javascript 如何从谷歌表单弹出式下拉菜单中选择一个观点

Javascript 如何从谷歌表单弹出式下拉菜单中选择一个观点,javascript,node.js,forms,selector,puppeteer,Javascript,Node.js,Forms,Selector,Puppeteer,各位,我最近一直在尝试实现谷歌表单的自动化,我被这个下拉列表难住了 我只是无法从弹出式下拉列表中选择所需的值。如果我使用Puppeter在字段(即联合太空王国)中书写,则下拉列表会自动完成,它会自动完成表格,以在United之后显示第一个值,就像使用空格字符一样,它会进入表格并选择第一个值 我制作了一个虚拟谷歌表单来模拟我的场景: 提前谢谢大家 我尝试过,这就是我编写的代码 注: 我不会用鼠标点击并选择元素来编写代码,因为当元素出错时很难调试 您必须声明下拉列表的根选择器,如果有多个下拉列表,

各位,我最近一直在尝试实现谷歌表单的自动化,我被这个下拉列表难住了

我只是无法从弹出式下拉列表中选择所需的值。如果我使用Puppeter在字段(即联合太空王国)中书写,则下拉列表会自动完成,它会自动完成表格,以在United之后显示第一个值,就像使用空格字符一样,它会进入表格并选择第一个值

我制作了一个虚拟谷歌表单来模拟我的场景:


提前谢谢大家

我尝试过,这就是我编写的代码

注:

我不会用鼠标点击并选择元素来编写代码,因为当元素出错时很难调试

您必须声明下拉列表的根选择器,如果有多个下拉列表,您必须自己找到正确的选择器

别忘了在代码中选择所需选项

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\U NUMBER]

不要忘记在每个下拉代码的末尾添加wait page.waitFor1000来增加延迟,以避免快速运行的脚本导致未选择的下拉

添加了多个下拉列表的新答案:

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')

})()

我试过了,这就是我的代码

注:

我不会用鼠标点击并选择元素来编写代码,因为当元素出错时很难调试

您必须声明下拉列表的根选择器,如果有多个下拉列表,您必须自己找到正确的选择器

别忘了在代码中选择所需选项

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\U NUMBER]

不要忘记在每个下拉代码的末尾添加wait page.waitFor1000来增加延迟,以避免快速运行的脚本导致未选择的下拉

添加了多个下拉列表的新答案:

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')

})()

到目前为止您尝试了什么?到目前为止您尝试了什么?感谢您提供的此解决方案它确实非常有效,并且与我描述的场景完全一致!与这种情况相关,我通过选择根选择器元素来查看它,它可以导航并选择所需的选项。然而,我确实遇到了一个问题,那就是在同一个第2页上可能有下拉列表,这些下拉列表具有相同的根选择器,因此它无法导航第二个下拉列表?或者至少,从我的尝试中,我无法让它唯一地识别第二个下拉列表。这是用第二个下拉列表更新的表单,该下拉列表具有相同的选择。或者,如果我编辑了上面的答案,请检查它。您可以添加任意多的选择器和函数。感谢您提供的此解决方案,它运行得非常好,与我描述的场景完全一致!与这种情况相关,我通过选择根选择器元素来查看它,它可以导航并选择所需的选项。然而,我确实遇到了一个问题,那就是在同一个第2页上可能有下拉列表,这些下拉列表具有相同的根选择器,因此它无法导航第二个下拉列表?或者至少,从我的尝试中,我无法让它唯一地识别第二个下拉列表。这是用第二个下拉列表更新的表单,该下拉列表具有相同的选择。或者,如果我编辑了上面的答案,请检查它。您可以添加任意多的选择器和函数。