使用 Selenium Python 单击 table 的所有链接

Click all links of table using Selenium Python

在我的项目中,我通过单击每个 link 写为“日期”来下载所有报告。下面是table的图片。

我必须提取 table 列“付款日期”中提到的每个日期的报告。每个日期都是一个 link 的报告。因此,我将逐一单击所有日期以下载报告。

for dt in driver.find_elements_by_xpath('//*[@id="tr-undefined"]/td[1]/span'):
    dt.click()
    time.sleep(random.randint(5, 10))

所以,这里进行的过程是当我单击一个日期时,它将下载该日期的报告。然后,我将单击下一个日期以获取该日期的报告。所以,我做了一个 for 循环来遍历所有 links 并获得所有日期的报告。

但它给了我 陈旧元素 异常。单击第一个日期后,无法单击下一个日期。我遇到错误,代码停止。

我该如何解决这个问题?

解决它的最简单方法是在点击它之前每次都得到一个特定的link。

links = driver.find_elements_by_xpath('//*[@id="tr-undefined"]/td[1]/span')
for i in range(len(links)):
    element = driver.find_elements_by_xpath('(//*[@id="tr-undefined"]/td[1]/span)[i+1]')
    element.click()
    time.sleep(random.randint(5, 10))

您收到陈旧元素异常,因为 DOM 会在每次点击时更新您选择的元素。

An example: on-click, a tag "clicked" is appended to an element's class. Since the list you've selected contains elements which have changed (1st element has a new class), it throws an error.

一个快速而肮脏的解决方案是在每次迭代后重新执行查询。如果值列表随着点击而增大或缩小,这将特别有用。

# Create an anonymous function to re-use
# This function can contain any selector
get_elements = lambda: driver.find_elements_by_xpath('//*[@id="tr-undefined"]/td[1]/span')

i = 0
while True:
    elements = get_elements()

    # Exit if you're finished iterating
    if not elements or i>len(elements):
        break
    
    # This should always work
    element[i].click()

    # sleep
    time.sleep(random.randint(5, 10))

    # Update your counter
    i+=1