使用Selenium使用get_elements_by_xpath在循环中单击每个按钮后获取页面源

时间:2019-12-27 12:44:33

标签: python selenium

我想为FINRA网站上的ATS块下载部分自动下载文本文件。问题是当我能够单击图标并在浏览器中打开文件时,单击后无法获取页面源。 driver.page_source返回“ ATS块下载”部分页面(单击之前的页面)的页面源。

这是我正在尝试的一段代码:

from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
import time 


driver = webdriver.Chrome(ChromeDriverManager().install())
URL = 'https://otctransparency.finra.org/otctransparency/'
driver.get(URL)

# Agree to the general terms
driver.find_element_by_xpath('//*[@class="btn btn-warning"]').click()

#go to ATS Blocks Download section
driver.find_element_by_xpath('//*[@href="/otctransparency/AtsBlocksDownload"]').click()

#wait for the page to fully load
time.sleep(5)

#click on each download icon
for element in driver.find_elements_by_xpath('//*[@src="./assets/icon_download.png"]'):
    element.click()
    print(driver.page_source)

如何在每element.click()之后获得页面源?

3 个答案:

答案 0 :(得分:1)

获取所有页面的page_source。 你需要 得出WebDriverWaitelement_to_be_clickable() 得出WebDriverWaitvisibility_of_all_elements_located() 得出WebDriverWaitnumber_of_windows_to_be()

代码

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
import time

driver = webdriver.Chrome()
URL = 'https://otctransparency.finra.org/otctransparency/'
driver.get(URL)
driver.maximize_window()
# Agree to the general terms
WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,'//*[@class="btn btn-warning"]'))).click()

#go to ATS Blocks Download section
WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,'//a[@href="/otctransparency/AtsBlocksDownload"]'))).click()

#click on each download icon
elements=WebDriverWait(driver,10).until(EC.visibility_of_all_elements_located((By.XPATH,'//img[@src="./assets/icon_download.png"]')))

for link in range(len(elements)):
    elements = WebDriverWait(driver, 10).until(EC.visibility_of_all_elements_located((By.XPATH, '//img[@src="./assets/icon_download.png"]')))
    elements[link].click()
    WebDriverWait(driver,10).until(EC.number_of_windows_to_be(2))
    windowhandles=driver.window_handles
    driver.switch_to.window(windowhandles[-1])
    WebDriverWait(driver,10).until(EC.visibility_of_element_located((By.TAG_NAME,"pre")))
    print(driver.page_source)
    driver.close()
    driver.switch_to.window(windowhandles[0])

答案 1 :(得分:0)

每次单击元素下载后,都会打开另一个浏览器选项卡,为了从另一个选项卡获取页面源,请使用:

for element in driver.find_elements_by_xpath('//[@src="./assets/icon_download.png"]'):
element.click()
driver.switch_to.window(driver.window_handles[1])
driver.set_page_load_timeout(120)
print(driver.page_source)
driver.switch_to.window(driver.window_handles[0])
driver.set_page_load_timeout(120)

PS。而不是:

time.sleep(5)

您可以这样做:

driver.set_page_load_timeout(120)

答案 2 :(得分:0)

请确保不要混用各种“等待”机制,因为这会导致意外行为(请参阅StackOverflow post以了解“为什么”)。

使用设置隐式等待时间时要小心,因为一旦设置了隐式等待时间,它就会在驱动程序实例的生命周期内设置(source,尽管在网络上的各个地方都曾提到过)。< / p>

如果打算让驱动程序等待多页,则应使用WebDriverWait。如其他答复所示,WebDriverWait(driver, timeout)接受一个WebDriver实例以及一个整数,该整数表示抛出TimeoutException之前要等待的时间,换句话说,它接受超时。

每次尝试查找元素时,您都可以创建一个新的WebDriverWait实例,而不必使用新的隐式等待时间来创建新的WebDriver实例。由于每个元素可能需要等待不同的持续时间,因此这是理想的。您可能会创建一个包装函数来封装WebDriverWait的使用:

def PatientlyClick(by, path, driver, timeout):
    WebDriverWait(driver,timeout).until(EC.element_to_be_clickable((by, path))).click()

如果您设计了一个封装了WebDriver实例的类,那么上面的代码片段可能会更漂亮,但是对于您的目的来说可能是不必要的(请参阅Page Object Model Design Pattern)。