0

I'm working on Nytimes mini crossword puzzle (https://www.nytimes.com/crosswords/game/mini) .

First I need to click the "OK" button when the page loads (I did this)

then "Reveal" then "Puzzle" from the menu at the right but the buttons has not specific ids itselves as you can see below.

<div class="Toolbar-expandedMenu--2s4M4"> <li class="Tool-button--39W4J Tool-tool--Fiz94 Tool-texty--2w4Br"><button>clear</button> <ul class="HelpMenu-menu--1Z_OA"> <li class="HelpMenu-item--1xl0_" style="display:list-item" title="Won’t clear letters that are part of completed crossing words"><a>Incomplete</a></li> <li class="HelpMenu-item--1xl0_" style="display:list-item"><a>Word</a></li> <li class="HelpMenu-item--1xl0_" style="display:list-item"><a>Puzzle</a></li> <li class="HelpMenu-item--1xl0_" style="display:list-item"><a>Puzzle &amp; Timer</a></li> </ul> </li> <li class="Tool-button--39W4J Tool-tool--Fiz94 Tool-texty--2w4Br Tool-open--1Moaq"><button>reveal</button> <ul class="HelpMenu-menu--1Z_OA"> <li class="HelpMenu-item--1xl0_" style="display:list-item"><a>Square</a></li> <li class="HelpMenu-item--1xl0_" style="display:list-item"><a>Word</a></li> <li class="HelpMenu-item--1xl0_" style="display:list-item"><a>Puzzle</a></li> </ul> </li> <li class="Tool-button--39W4J Tool-tool--Fiz94 Tool-texty--2w4Br"><button>check</button> <ul class="HelpMenu-menu--1Z_OA"> <li class="HelpMenu-item--1xl0_" style="display:list-item"><a>Autocheck</a></li> <li class="HelpMenu-item--1xl0_" style="display:list-item"><a>Square</a></li> <li class="HelpMenu-item--1xl0_" style="display:list-item"><a>Word</a></li> <li class="HelpMenu-item--1xl0_" style="display:list-item"><a>Puzzle</a></li> </ul> </li> </div>

Here is my python script

from selenium import webdriver import time driver_path = "/home/xperia/PycharmProjects/cs461-getinput/chromedriver" browser = webdriver.Chrome(executable_path=driver_path) browser.get("https://www.nytimes.com/crosswords/game/mini") time.sleep(5) browser.find_element_by_class_name("buttons-modalButton--1REsR").click() time.sleep(5) browser.find_element_by_class_name("Tool-button--39W4J Tool-tool--Fiz94 Tool-texty--2w4Br").click() 
1
  • I found that in chrome dev tools you right click an element then copy its path as xpath then we can use the method "browser.find_element_by_xpath" easierCommentedSep 30, 2019 at 19:44

3 Answers 3

2

You can click on an element using its text, rather than ID. In your case, this may help, since the elements do not have ID.

To click the reveal button:

# wait for reveal button to exist WebDriverWait(browser,10).until(EC.element_to_be_clickable((By.XPATH,'//button[contains(text(), 'reveal')]'))).click() # click reveal button browser.find_element_by_xpath("//button[contains(text(), 'reveal')]").click() 

To click Puzzle, you can use this path:

# wait for puzzle button to exist WebDriverWait(browser,10).until(EC.element_to_be_clickable((By.XPATH,'//li[button[contains(text(), 'reveal')]]/ul/li/a[text()='Puzzle']'))).click() # click the reveal button browser.find_element_by_xpath("//li[button[contains(text(), 'reveal')]]/ul/li/a[text()='Puzzle']").click() 
    1

    To click on puzzle under reveal menu induce WebDriverWait And element_to_be_clickable()

    from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC driver_path = "/home/xperia/PycharmProjects/cs461-getinput/chromedriver" browser = webdriver.Chrome(executable_path=driver_path) browser.get("https://www.nytimes.com/crosswords/game/mini") WebDriverWait(browser,10).until(EC.element_to_be_clickable((By.XPATH,'//span[text()="ACCEPT AND CLOSE"]'))).click() WebDriverWait(browser,10).until(EC.element_to_be_clickable((By.CLASS_NAME,'buttons-modalButton--1REsR'))).click() WebDriverWait(browser,10).until(EC.element_to_be_clickable((By.XPATH,'//div[@class="Toolbar-expandedMenu--2s4M4"]//li/button[text()="reveal"]'))).click() WebDriverWait(browser,10).until(EC.element_to_be_clickable((By.XPATH,'//button[text()="reveal"]/following::ul[1]//li/a[text()="Puzzle"]'))).click() 
      1

      I edited your script a little bit. I tested this on my end and it works up to the point of pressing the 'Puzzle' button. I recommend using xpath as well. You can get the xpath element by clicking inspect until the location of the element pops up, then right click and copy by xpath. This is what the code looks like

      from selenium import webdriver import time driver_path = "/home/xperia/PycharmProjects/cs461-getinput/chromedriver" browser = webdriver.Chrome(executable_path=driver_path) time.sleep(3) browser.find_element_by_class_name("buttons-modalButton--1REsR").click() time.sleep(2) browser.find_element_by_xpath('//*[@id="root"]/div/div/div[4]/div/main/div[2]/div/div/ul/div[2]/li[2]/button').click() browser.find_element_by_xpath('//*[@id="root"]/div/div/div[4]/div/main/div[2]/div/div/ul/div[2]/li[2]/ul/li[3]/a').click() 

      Also important to note that if you get an error, it might be because there is another element blocking the button you want clicked.

      3
      • This is a good solution, but the XPaths are a little lengthy, and indices such as [4] make them more brittle. You can accomplish the same result with relative XPath that does not rely on indices, and shorter in length.
        – CEH
        CommentedSep 30, 2019 at 19:09
      • Ah! Thanks for the tip, I will definitely try to incorporate this more.
        – Entroyp
        CommentedSep 30, 2019 at 19:10
      • Thank you very much for your answer.CommentedSep 30, 2019 at 19:44

      Start asking to get answers

      Find the answer to your question by asking.

      Ask question

      Explore related questions

      See similar questions with these tags.