python - 在 Selenium 中循环浏览 CSV 文件时,如何只登录一次?
问题描述
我是 Selenium 的初学者,我正在尝试构建一个自动化,该自动化循环遍历 csv 文件中的不同 URL,并在页面上执行多个操作。
它几乎可以工作,但我只是不知道如何让 selenium bot 仅登录第一个 URL。
这是我的代码:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import csv
from itertools import islice
driver = webdriver.Chrome(executable_path='./chromedriver.exe')
with open('C:/Users/Monica/projects/myfile.csv') as csv_file:
csv_reader = csv.reader(csv_file, delimiter=',')
for row in islice(csv_reader,1,None):
driver.get(row[0])
login_btn = driver.find_element_by_xpath("//a[@class='login-trigger']")
login_btn.click()
wait = WebDriverWait(driver, 20)
email_input = driver.find_element_by_id("login_email")
email_input.send_keys("myemail@gmail.com")
wait = WebDriverWait(driver, 20)
password_input = driver.find_element_by_id("login_password")
password_input.send_keys("XXXXXXXXXX")
wait = WebDriverWait(driver, 10)
connect_btn = driver.find_element_by_id("login_submit")
connect_btn.click()
wait = WebDriverWait(driver, 60)
element = wait.until(EC.element_to_be_clickable((By.XPATH, "// [@id='content']/div[1]/div/ul[1]/li/a/span")))
wait = WebDriverWait(driver, 60)
sendmessage_btn = driver.find_element_by_xpath("//*[@id='content']/div[1]/div/ul[1]/li/a/span")
sendmessage_btn.click()
wait = WebDriverWait(driver, 60)
textbox_input = driver.find_element_by_xpath("//*[@id='message_text']")
textbox_input.send_keys("Hey ")
textbox_input.send_keys(row[1])
wait = WebDriverWait(driver, 60)
finalmessage_btn = driver.find_element_by_xpath("//*[@id='message_submit']/span")
finalmessage_btn.click()
wait = WebDriverWait(driver, 120)
driver.close()
实际上,流程的登录部分只需要第一个 URL(login_btn、email_input 和 password_input),然后,对于 CSV 文件中的其余 URL,我只需要单击一个按钮并发送消息(之后connect_btn 按钮到流程的末尾)。
因为我当前的流程没有考虑到这一点,所以在尝试打开文件的第二个 URL 时收到以下错误消息。
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//a[@class='login-trigger']
如何修改我的代码以仅登录一次?谢谢 !
解决方案
您可以使用第一个 url 分离登录过程,然后打开其余的 CSV 文件。也就是说,如果您只需要登录一次。那是确保在您的 CSV 文件中没有第一个 url。
再次不知道您的 CSV 文件中的内容/您使用 selenium 的 URL 限制了我提出进一步建议的一些内容。
代码示例
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import csv
from itertools import islice
driver = webdriver.Chrome(executable_path='./chromedriver.exe')
first_url = 'XXX'
driver.get(first_url)
login_btn = driver.find_element_by_xpath("//a[@class='login-trigger']")
login_btn.click()
wait = WebDriverWait(driver, 20)
email_input = driver.find_element_by_id("login_email")
email_input.send_keys("myemail@gmail.com")
wait = WebDriverWait(driver, 20)
password_input = driver.find_element_by_id("login_password")
password_input.send_keys("XXXXXXXXXX")
wait = WebDriverWait(driver, 10)
connect_btn = driver.find_element_by_id("login_submit")
connect_btn.click()
with open('C:/Users/Monica/projects/myfile.csv') as csv_file:
csv_reader = csv.reader(csv_file, delimiter=',')
for row in islice(csv_reader,1,None):
wait = WebDriverWait(driver, 60)
element = wait.until(EC.element_to_be_clickable((By.XPATH, "// [@id='content']/div[1]/div/ul[1]/li/a/span")))
wait = WebDriverWait(driver, 60)
sendmessage_btn = driver.find_element_by_xpath("//*[@id='content']/div[1]/div/ul[1]/li/a/span")
sendmessage_btn.click()
wait = WebDriverWait(driver, 60)
textbox_input = driver.find_element_by_xpath("//*[@id='message_text']")
textbox_input.send_keys("Hey ")
textbox_input.send_keys(row[1])
wait = WebDriverWait(driver, 60)
finalmessage_btn = driver.find_element_by_xpath("//*[@id='message_submit']/span")
finalmessage_btn.click()
wait = WebDriverWait(driver, 120)
driver.close()
选择
另一种选择是您可以在代码的登录部分使用 try 和 except 块。你需要导入from selenium.common.exceptions import NoSuchElementException
在你的下面添加这个driver.get[0]
try:
login_btn = driver.find_element_by_xpath("//a[@class='login-trigger']")
login_btn.click()
wait = WebDriverWait(driver, 20)
email_input = driver.find_element_by_id("login_email")
email_input.send_keys("myemail@gmail.com")
wait = WebDriverWait(driver, 20)
password_input = driver.find_element_by_id("login_password")
password_input.send_keys("XXXXXXXXXX")
wait = WebDriverWait(driver, 10)
connect_btn = driver.find_element_by_id("login_submit")
connect_btn.click()
wait = WebDriverWait(driver, 60)
element = wait.until(EC.element_to_be_clickable((By.XPATH, "// [@id='content']/div[1]/div/ul[1]/li/a/span")))
wait = WebDriverWait(driver, 60)
sendmessage_btn = driver.find_element_by_xpath("//*[@id='content']/div[1]/div/ul[1]/li/a/span")
sendmessage_btn.click()
except NoSuchElementsException:
wait = WebDriverWait(driver, 60)
element = wait.until(EC.element_to_be_clickable((By.XPATH, "// [@id='content']/div[1]/div/ul[1]/li/a/span")))
wait = WebDriverWait(driver, 60)
sendmessage_btn = driver.find_element_by_xpath("//*[@id='content']/div[1]/div/ul[1]/li/a/span")
sendmessage_btn.click()
wait = WebDriverWait(driver, 60)
textbox_input = driver.find_element_by_xpath("//*[@id='message_text']")
textbox_input.send_keys("Hey ")
textbox_input.send_keys(row[1])
wait = WebDriverWait(driver, 60)
finalmessage_btn = driver.find_element_by_xpath("//*[@id='message_submit']/span")
finalmessage_btn.click()
wait = WebDriverWait(driver, 120)
提示
- 您可能需要考虑将登录过程和打开 CSV 文件放入单独的函数中。特别是如果您将有额外的代码。
根据评论更新
因此,根据评论听起来您需要更多帮助才能首先登录,然后使用 CSV 分隔 URL。这是非常容易遵循的登录过程。它是在一个函数中分离出程序的不同部分,这是我们应该做的。
from selenium import webdriver
def login(driver):
driver.get('https://erasmusu.com/en/login/do#login_popup')
driver.find_element_by_id('login_email').send_keys('xxxxx')
driver.find_element_by_id('login_password').send_keys('xxxxx')
driver.find_element_by_id('login_submit').click()
if __name__ == "__main__":
driver = webdriver.Chrome(executable_path=r'c:\users\aaron\chromedriver.exe')
login(driver)
推荐阅读
- java - 无法使用 Intellij IDEA 运行 Java 代码(通过打开项目)
- matplotlib - 左上角的 Matplotlib 值并将其删除
- django - Django 模型中的继承与模板的使用
- bash - Bash 移动文件,如果源文件较大,则覆盖
- android - Dagger 2 自定义范围声明中的保留策略
- javascript - “Site Wide” cookie 实际上最终只适用于某些页面
- algorithm - 实现一个记住先前访问过的节点的链表在理论上是否有益?
- java - .properties 文件必须在 java 9 之前以 ISO-8859-1 编码,这真的是真的吗?
- python - fitting step function with variation in the step location with scipy optimize curve_fit
- scala - 在scala中裁剪带有选定页码的pdf文件