首页 > 解决方案 > 如何使用 Selenium 自动点击 iframe 中的多个链接?

问题描述

我正在尝试从以下网站收集秘鲁国会发起的几项法案的数据:http: //www.congreso.gob.pe/pley-2016-2021

基本上,我想点击搜索结果中的每个链接,抓取账单的相关信息,返回搜索结果然后点击下一个账单的下一个链接并重复该过程。显然,在国会会议上有如此多的法案,如果我能将其自动化,那就太好了。

到目前为止,我已经能够完成所有事情,直到点击下一个账单。我已经能够使用 Selenium 启动一个显示搜索结果的 Web 浏览器,使用 iframe 中嵌入的 xpath 单击第一个链接,然后使用 beautifulsoup 抓取内容,然后导航回搜索结果。我遇到的问题是能够单击搜索结果中的下一个账单,因为我不确定如何迭代 xpath(或如何迭代将我带到每个后续账单的东西)。我希望能够抓取每一页上所有账单的信息,然后能够导航到搜索结果的下一页。

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
from bs4 import BeautifulSoup
import requests

driver = webdriver.Chrome('C:\\Users\\km13\\chromedriver.exe')
driver.get("http://www.congreso.gob.pe/pley-2016-2021")


WebDriverWait(driver, 50).until(EC.frame_to_be_available_and_switch_to_it((By.NAME, 'ventana02')))

elem = WebDriverWait(driver, 10).until(EC.element_to_be_clickable(
(By.XPATH, "//a[@href='/Sicr/TraDocEstProc/CLProLey2016.nsf/641842f7e5d631bd052578e20058a231/243a65573d33ecc905258449007d20cc?OpenDocument']")))
elem.click()

soup = BeautifulSoup(driver.page_source, 'lxml')
table = soup.find('table', {'bordercolor' : '#6583A0'})
table_items = table.findAll('font')
table_authors = table.findAll('a')
for item in table_items:
content = item.contents[0]
print(content)
for author in table_authors:
authors = author.contents[0]
print(authors)
driver.back()

到目前为止,这是我启动 Web 浏览器的代码,单击搜索结果的第一个链接,抓取必要的数据,然后返回到搜索结果。

以下代码将导航到搜索结果中的不同页面:

elem = WebDriverWait(driver, 10).until(EC.element_to_be_clickable(
(By.XPATH, "//a[contains(@onclick,'D32')]/img[contains(@src,'Sicr/TraDocEstProc/CLProLey')]")))
elem.click()

我想我的具体问题是能够弄清楚如何自动点击 iframe 中的后续账单,因为一旦我能够做到这一点,我假设我可以循环遍历每个页面上的账单,然后嵌套该循环在循环搜索结果页面的函数中。

更新:在下面的答案的帮助下,我应用了逻辑,但使用 beautifulsoup 来抓取 iframe 中的 href 链接,并将它们存储在一个列表中,将必要的字符串元素连接起来,为所有账单创建一个 xpath 列表页:

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
from bs4 import BeautifulSoup
import requests

driver = webdriver.Chrome('C:\\Users\\km13\\chromedriver.exe')
driver.get("http://www.congreso.gob.pe/pley-2016-2021")


WebDriverWait(driver, 50).until(EC.frame_to_be_available_and_switch_to_it((By.NAME, 'ventana02')))

soup = BeautifulSoup(driver.page_source, 'lxml')
table = soup.find('table', {'cellpadding' : '2'})
table_items = table.find_all('a')
for item in table_items:
    elem = WebDriverWait(driver, 10).until(EC.element_to_be_clickable(
    (By.XPATH, "//a[@href='" + item.get('href') + "']")))
    elem.click()
    driver.back()

现在我的问题是它将单击循环中第一项的链接并单击返回搜索结果,但不会继续单击循环中的下一项(代码只是超时)。我对在 Python 中编写循环也很陌生,所以我想知道是否有办法让我遍历 xpath 的项目,以便我可以单击 xpath,抓取该页面上的信息,然后单击返回搜索结果,然后单击列表中的下一项?

标签: pythonseleniumweb-scrapingbeautifulsoup

解决方案


这是我对这个问题的逻辑。

1.首先使用switchTo进入iframe。

2. 使用 driver.findElements 将 xpath "//a" 的 webelements 获取到变量 "billLinks" 中,因为此框架只有账单的链接。

3. 现在遍历 billLinks 并执行所需的操作。

我希望这个解决方案有所帮助。


推荐阅读