双for循环后刷新页面,selenium与python

问题描述 投票:0回答:1

每次运行这个双 for 循环时,我都会遇到陈旧的元素引用,并且在单击后退元素后页面会刷新。我尝试在 for 循环中再次调用驱动程序并从 DOM 中提取元素,但这仅调用第一个元素,并且不会迭代 for 循环。

代码在这里:

import time
from selenium import webdriver

driver =webdriver.Chrome()
time.sleep(3)
driver.get("https://www.elizabethnj.org/Directory.aspx")
driver.maximize_window()
while True:
    driver.get("https://www.elizabethnj.org/Directory.aspx")
    driver.maximize_window()
    divs = driver.find_elements('xpath', '//div[@class="topmenu"]/div')
    for div in divs:
        # div = driver.find_element('xpath', 
        '//div[@class="topmenu"]/div')
        time.sleep(2)
        div.click()
        time.sleep(2)
        contacts = driver.find_elements('xpath', '//* 
        [@id="cityDirectoryDepartmentDetails"]/tbody/tr')
        for contact in contacts:
            print(contact.text)
        back = driver.find_element('xpath', '//* 
            [@id="CityDirectoryLeftMargin"]/div[3]/span')
        back.click()
python for-loop selenium-webdriver nested-for-loop
1个回答
0
投票

Selenium
提供对浏览器内存中元素的引用,当您
click()
加载新页面时,它会从内存中删除元素,之后很难找到它们 - 即使您返回页面,因为元素可能位于不同的位置记忆中。

有时类似的问题可能发生在

click()
更改页面上的某些内容(即折叠或展开某些列表)时,因为它也可以移动内存中的元素

有两种方法:

  • 更难:在开始时计算所有元素
    divs
    ,然后在每个循环中再次获取所有
    divs
    并使用
    index
    获取下一个元素 -
    div = divs[index]
divs = driver.find_elements('xpath', '//div[@class="topmenu"]/div')
print('len(divs):', len(divs))

for index in range(len(divs)):

    divs = driver.find_elements('xpath', '//div[@class="topmenu"]/div')
    div = divs[index]
  • 更简单:这个
    clicks
    加载新页面,因此首先您可以将所有
    href
    作为字符串获取,稍后您可以使用
    .get(url)
    加载包含联系人的页面。而且不需要返回主页

顺便说一句:还有另外两个问题。

  • 一些
    div
    是空的 - 没有文本,也没有页面链接 - 所以你必须跳过它(即,你可以检查它是否有空文本)。
  • 某些页面没有包含联系人的表格,主页的链接是
    [2]
    而不是
    [3]
    。使用
    driver.back()
    返回上一页更简单。或者您只需再次运行
    driver.get(url)
    即可获取主页。

更难版本的工作代码:

import time
from selenium import webdriver

driver = webdriver.Chrome()
driver.maximize_window()

driver.get("https://www.elizabethnj.org/Directory.aspx")
time.sleep(3)

divs = driver.find_elements('xpath', '//div[@class="topmenu"]/div')
print('len(divs):', len(divs))

#for index, div in enumerate(divs):
#    print(f'{index} >>>', div.text)
    
for index in range(len(divs)):

    divs = driver.find_elements('xpath', '//div[@class="topmenu"]/div')
    div = divs[index]
    
    text = div.text.strip()
    
    if not text:
        print(f'{index} >>>  --- empty ---')
        continue
        
    print(f'{index} >>>', div.text)
    div.click()
    time.sleep(2)
    
    contacts = driver.find_elements('xpath', '//*[@id="cityDirectoryDepartmentDetails"]/tbody/tr')        
    for contact in contacts:
        print('  contact:', contact.text)

    print('<<< back')
    # ... some pages don't have contacts and link is in `[2]` instead of `[3]`        
    #back = driver.find_element('xpath', '//*[@id="CityDirectoryLeftMargin"]/div[3]/span')
    #back.click()
    # ... or ...    
    driver.back()
    # ... or ...
    #driver.get("https://www.elizabethnj.org/Directory.aspx")

    time.sleep(2)

input('Press ENTER to close')
© www.soinside.com 2019 - 2024. All rights reserved.