首页 > 解决方案 > 在 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']

如何修改我的代码以仅登录一次?谢谢 !

标签: pythonseleniumcsvselenium-webdriverweb-scraping

解决方案


您可以使用第一个 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)
    

提示

  1. 您可能需要考虑将登录过程和打开 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)

推荐阅读