Skip to content

Loop over elements in Playwright

Using locator

This is the right way to do it.

links = page.locator('a')
count = await links.count()

for i in range(count):
    link = links.nth(i)

    text = await link.text_content()
    href = await link.get_attribute('href')

    print("Link text is", text)
    print("Link URL is", href)

Using query_selector_all

This is the somewhat easier way to do it.

links = await page.query_selector_all('a')

for link in links:
    text = await link.text_content()
    href = await link.get_attribute('href')

    print("Link text is", text)
    print("Link URL is", href)

It also allows you to use the "find the rows, then find the columns" pattern.

links = await page.query_selector_all('.story')

for link in links:
    title_element = await story.query_selector('h3')
    text = await title_element.text_content()
    link_element = await link.query_selector('a')
    href = await link_element.get_attribute('href')

    print("Link text is", text)
    print("Link URL is", href)

Error: Element is not attached to the DOM

Are you trying to click links and use page.go_back() but are getting the error Error: Element is not attached to the DOM? Stop using element_handles()!

When you click a link, go to a new page, and then go back to the firts page, the first page is refreshed. Because of this, the element handles that point to the links are no longer valid!

You need to use locator() to get the links again, which the nth technique below does automatically.

links = page.locator('a')

count = await links.count()
for i in range(count):
    link = links.nth(i)
    await link.click()

    # Scrape the content of the page

    await page.go_back()

print("Done")