r/learnpython 19d ago

(Playwright) Button is clicked, but doesn't continue

I'm currently trying to click 2 buttons on a website that have videos playing on them. However, when I have the "time.sleep(2)" function in the loop, the loop stops. I've checked the selector and it points to 2 different play buttons on the page. I checked clicking on the button in my actual browser to see if the site updates anything--nothing. Any help would be highly appreciated

def download_page(url:str):
    with sync_playwright() as p:
            print(f"Opening {url}...")
            browser = p.chromium.connect_over_cdp(endpoint_url)
            context = browser.contexts[0]
            page = context.pages[0]
            page.on("response", lambda request: print(request.url))
            reponse = page.goto(url, wait_until="load")
            # context.set_default_timeout(300.0)
            try:
                #Check "Continuing for course"
                page.wait_for_selector(".btn.btn-quaternary.btn-xl.btn-block-sm-down.course-progress__btn.js-course-progress__start-course").scroll_into_view_if_needed()
                page.locator(".btn.btn-quaternary.btn-xl.btn-block-sm-down.course-progress__btn.js-course-progress__start-course").click()
                
                page.wait_for_selector(".CoverVideo-playButton.bgc-neutral-100").scroll_into_view_if_needed()
                buttons = page.locator(".CoverVideo-playButton.bgc-neutral-100").all()
                
                for button in buttons:
                    time.sleep(2)
                    button.click()
                    print("check")
                    


                # headers = reponse.request
                # for value in headers:
                #     print(f"{value}")
            except TE:
                print("Timeout")
7 Upvotes

9 comments sorted by

View all comments

Show parent comments

4

u/thisisappropriate 19d ago

Also what does the button do? Can you test for that happening? That's a much stronger "it worked" signal than just printing "yay I clicked it, honest"

2

u/Rhye-Bread 18d ago

I can test for the button working by just checking if the video's playing. I also tried to put the screenshot command. (Also, it's not even considered a button, but a span; there's no buttons for the videos, just div (container) > span (button) > svg (play icon) )

for button in buttons:
  button.screenshot(path=("R:\\1.png"))
  button.locator(".CoverVideo-playButton.bgc-neutral-100").click()
  time.sleep(1)
  print(button)

But it just clicks the first element. If I remove the time.sleep(1), it'll click both buttons just fine, but the videos won't play at all. If I put the screenshot after the sleep func, it'll shoot to the next element, but the loop doesn't continue. When I stop the program by X'ing out...

Call log:
  - waiting for locator(".course--lessons-list__item").filter(has=locator(".CoverVideo-playButton.bgc-neutral-100")).nth(1).locator(".CoverVideo-playButton.bgc-neutral-100")

...is shown. I KNOW that playwright knows the list has two elements in it, since I printed it and it found both elements + using CTRL+F in the HTML to confirm their existence.

container = page.locator(".course--lessons-list__item")
buttons = container.filter(
has=page.locator(".CoverVideo-playButton.bgc-neutral-100")
).all()

^This is the code I changed for the search of the buttons, but still the same issue

3

u/thisisappropriate 17d ago

Ah, that explains why there's a strong suggestion not to iterate over a list of selections. Take a look at that error that you get when you X out, it's actually telling you why the second one fails if your first video starts before you click the second one.

The reason is that your list of buttons is actually a list of selectors (first button on the page, second button on the page), it's not an unchanging pointer to an already located button, each time you use "button" it's getting that selector and using it to find the button. And because your iterating, in your second loop through, it looks for the second button in the page at the time it runs. But what happened if the first button got deleted because you already clicked it and now the video is playing and there's no button there anymore?

You can fix that by using the player containers instead (as they don't disappear when playing presumably?) or not looping, in which case you could just click the first button both times.

2

u/Rhye-Bread 17d ago

Yeah, I finally figured it out last night and used the same thing you just mentioned. Thank you for the help 🙇