Home > Enterprise >  python selenium checkbox nested label and input
python selenium checkbox nested label and input

Time:09-22

I'm trying to get a checkmark on "Minutes (1993-Present)" from the federal reserve's document filter page with selenium.

https://www.federalreserve.gov/monetarypolicy/materials/

This is my code. I have tried the following ways, I keep get "Message: no such element: Unable to locate element: Unable to locate element"

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver import ActionChains
import time

PATH = "C:\Program Files (x86)\chromedriver.exe"
driver = webdriver.Chrome(PATH)

driver.get("https://www.federalreserve.gov/monetarypolicy/materials/")

link = driver.find_element_by_xpath('//*[@id="article"]/app-root/div/ng-component/div[1]/div/div/form/app-doc-types/div[2]/div/div/div[7]/label/input').click()
link = driver.find_element_by_xpath("//div[@class='form-group']/div/div[7]/label/input[contains(text(), 'Minutes (1993-Present)')]").click()
link = driver.find_element_by_css_selector('div.form-group div:nth-child(7) label input').click()

I sliced some parts of the HTML below.

<app-doc-types><div class="eventSearch__label">
  <p class="form-control-static">
    <strong><legend class="ng-binding">Type:</legend></strong>
  </p>
</div>
<div class="eventSearch__inputs">
  <div class="form-group">
    <div class="row">
      <div class="col-lg-6">
        <label>
          <input type="checkbox" class="ng-untouched ng-pristine ng-valid">
          Agendas
        </label>
      </div><div class="col-lg-6">
        <label>
          <input type="checkbox" class="ng-untouched ng-pristine ng-valid">
          Beige Books/Redbooks
        </label>
      </div><div class="col-lg-6">
        <label>
          <input type="checkbox" class="ng-untouched ng-pristine ng-valid">
          Bluebooks
        </label>
      </div><div class="col-lg-6">
        <label>
          <input type="checkbox" class="ng-untouched ng-pristine ng-valid">
          Chairman's FOMC Press Conferences
        </label>
      </div><div class="col-lg-6">
        <label>
          <input type="checkbox" class="ng-untouched ng-pristine ng-valid">
          Greenbooks
        </label>
      </div><div class="col-lg-6">
        <label>
          <input type="checkbox" class="ng-untouched ng-pristine ng-valid">
          Memos
        </label>
      </div><div class="col-lg-6">
        <label>
          <input type="checkbox" class="ng-valid ng-dirty ng-touched">
          Minutes (1993-Present)
        </label>
      </div><!---->
    </div>
  </div>
</div>


</app-doc-types>

CodePudding user response:

It takes some time for website to load. I added time.sleep(2) after opening the webpage with driver.
Your first XPath should work, however it's extremely dependent on the structure of the page, therefore it may not work due to a little modification in the HTML structure of the page.
Second XPath won't work, and actually you do not need to add text() check to the end of your path. This should work:
//div[@class='form-group']/div/div[7]/label/input
CSS Selector path should work, however your css path can be easily simplified. Check my solution below:

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver import ActionChains
import time

driver = webdriver.Chrome()

driver.get("https://www.federalreserve.gov/monetarypolicy/materials/")
time.sleep(2)
link = driver.find_element_by_css_selector('.col-lg-6:nth-of-type(7) input').click()

Alternatively, you can use an explicit wait.

driver.get("https://www.federalreserve.gov/monetarypolicy/materials/")
element = WebDriverWait(driver , 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR , '.col-lg-6:nth-of-type(7) input')))
element.click()

CodePudding user response:

you can use playwright

import asyncio
from playwright.async_api import async_playwright

async def run(playwright):
    chromium = playwright.chromium # or "firefox" or "webkit".
    browser = await chromium.launch()
    page = await browser.new_page()
    await page.goto("https://www.federalreserve.gov/monetarypolicy/materials/")
    await page.click('xpath=/html/body/div[3]/div[2]/div[2]/app-root/div/ng-component/div[1]/div/div/form/app-doc-types/div[2]/div/div/div[7]/label/input')
    await browser.close()
    
async def main():
    async with async_playwright() as playwright:
        await run(playwright)
asyncio.run(main())
  • Related