python - 如何使用 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,抓取该页面上的信息,然后单击返回搜索结果,然后单击列表中的下一项?
解决方案
这是我对这个问题的逻辑。
1.首先使用switchTo进入iframe。
2. 使用 driver.findElements 将 xpath "//a" 的 webelements 获取到变量 "billLinks" 中,因为此框架只有账单的链接。
3. 现在遍历 billLinks 并执行所需的操作。
我希望这个解决方案有所帮助。
推荐阅读
- javascript - 谁能解释一下 Vue/Javascript 中的“代理”或“代理”是什么意思?
- node.js - mongoDB有没有办法在特定时间后自己创建一个文档,比如一天?
- php - 使用文件夹名称保存到数据库的干预图像上传
- python - 在 Python 中使用变量更新 Kivy 标签
- angular - 在路由中传递对象作为参数返回 [Object object]
- c++ - 如何从给定的一组点计算同心多边形的最大数量?
- mysql - 验证 Innodb 表的数据库备份
- c# - 通过更改属性值提取最后一个元素并将其添加到列表的末尾
- c++ - 以向量为参数的映射
- angular - Ngrx独立商店