P

Python 高级自动化技巧 | Selenium

2025-05-28

Python 高级自动化技巧 | Selenium

这篇文章与OnePublish交叉发布

DEV Network 怎么样?

在这篇文章中我想分享我目前实习期间的自动化经验。

实际上,我想在一个真实的项目上向你解释这一点,但不幸的是,我没有找到任何符合我所有要求的平台。

但是,如果您是 Python 开发人员,您将需要这些技巧来快速构建自动化程序。那么,让我们开始吧!

Web 驱动程序

正确配置 Web 驱动程序对于运行自动化至关重要。如果您想使用Chrome作为 Web 驱动程序,则应安装chromedriver。但是,如果您想选择 Firefox,则应安装geckodriver

创建一个类

通过创建类,您可以轻松处理 URL 并调用函数,这样就不必在每个函数中创建 Web 驱动程序。请看以下代码:

from selenium import webdriver

class Bot:

    def __init__(self):
        self.bot = webdriver.Firefox(executable_path='/path/to/geckodriver')

automate = Bot() 
Enter fullscreen mode Exit fullscreen mode

因此,当你需要函数中的驱动程序时,只需编写:

  def search(self):
        bot = self.bot
        bot.get('www.google.com')    
Enter fullscreen mode Exit fullscreen mode

处理登录

为了处理登录,您应该在 __init__ 函数中添加字段。请看以下代码:

import time
from selenium import webdriver
from selenium.webdriver.common.keys import Keys

class Bot:

    def __init__(self,username,password):
        self.username = username
        self.password = password
        self.bot = webdriver.Firefox(executable_path='/path/to/geckodriver')

    def login(self):
        bot = self.bot
        bot.get('https://website.com/')
        time.sleep(3)
        email = bot.find_element_by_id('userNameBox')
        password = bot.find_element_by_id('passWordBox')
        email.clear()
        password.clear()
        email.send_keys(self.username)
        password.send_keys(self.password)
        bot.find_element_by_id('LoginBtn').click()
        time.sleep(3) 

automate = Bot('your_username', 'your_password') 
automate.login()
Enter fullscreen mode Exit fullscreen mode

处理登录的非常简单的方法。

循环点击

如果要循环点击,务必使用time.sleep()。因为自动化需要时间来执行下一次点击。如果不使用 time.sleep(),则会出现 ElementClickInterceptedException 错误。

for elem in elements:
        elem.click()
        time.sleep(3)
Enter fullscreen mode Exit fullscreen mode

将数据写入 CSV

网上有很多关于如何将数据写入 CSV 的解决方案和示例。假设您有多个数组,并且希望将它们以正确的字段名称(列名)写入 CSV。

让我更清楚一点……

我的任务是抓取一些短语,并将它们翻译成所有语言,然后将这些数据写入 CSV 文件。因此,我使用了 GT API,并为每种语言创建了一个数组。

我有很多数组,所以我需要以某种方式在正确的字段名称(列名)下写下每个翻译。

以下代码演示了处理此类问题的最佳解决方案:

# zip arrays
languages_translations = zip(ar,hy,ms,bg,zh_cn_SAR,zh_cn,
zh_tw_singapore,zh_tw,hr,cs,da,nl,en_australia,en_uk,en_usa,et,fi)    

# Write to CSV
with open('translations.csv', mode='w', newline='', encoding="utf-8") as csv_file:
    fieldnames = ['Arabic', 'Armenian (Armenia)', 'Bahasa Malaysia (Malaysia)', 'Bulgarian (Bulgaria)', 'Chinese (Hong Kong SAR)', 
    'Chinese (Simplified)','Chinese (Singapore)','Chinese (Traditional)','Croatian (Croatia)', 'Czech (Czech Republic)',
    'Danish (Denmark)','Dutch (The Netherlands)','English (Australia)','English (UK)', 'English (US)','Estonian (Estonia)','Finnish (Finland)']
    writer = csv.DictWriter(csv_file, fieldnames=fieldnames)
    writer.writeheader()
    for lang in languages_translations:
        writer.writerow(dict(zip(fieldnames, lang)))  
Enter fullscreen mode Exit fullscreen mode

如您所见,您应该压缩所有数组,循环它并写入压缩字段名称和循环项的行字典。

通过这种方式,您将把所有数据正确地写入 CSV 文件。

处理弹出窗口或 iframe

另一个具有挑战性的任务是在自动化过程中处理弹出窗口或 iframe。如果需要与弹出窗口或 iframe 元素交互,则应该告诉 Selenium 将窗口从主窗口切换到弹出窗口。处理完弹出窗口后,应该切换回主窗口。


# find iframe or popup element
iframe = bot.find_element_by_tag_name('iframe')
# switch to iframe or popup window
bot.switch_to.frame(iframe)
# interact with elements
textarea = bot.find_element_by_tag_name('body')
textarea.send_keys('Some Keys Here')
# switch back to main window
bot.switch_to.default_content() 
Enter fullscreen mode Exit fullscreen mode

太棒了!我给你提供了网上那些很复杂的解决方案。

如果您必须处理警报弹出窗口,您也可以使用此方法。

将 CSV 数据发送到 Web 元素

有时您需要将 csv 数据发送到 Web 元素(例如多个文本框)。

假设您有多个面板,其中包含多个文本框,并且您必须将 CSV 行发送到这些文本框中

文本框

所以每个 CSV 行都属于不同的面板。听起来很疯狂吧?这就是训练你大脑的方法 :) 你必须以某种方式迭代每个面板文本框对应的每个 CSV 行。

在我们继续之前,如果您想查找更多类似的文章,请访问Reverse Python 。

好吧!我们先看看代码,然后我会解释:

def send_keys_textboxes(self,url):
    bot = self.bot
    # go to url
    bot.get(url)
    # reader object which will iterate over lines in the given csvfile
    with open('translations.csv', 'rt', encoding='utf8') as csvfile:
        langs = csv.reader(csvfile, delimiter=',', quotechar='"')
        # create list of langs
        langs = list(langs)
    elements = bot.find_elements_by_xpath("//a[@data-tag='globalize']")
    # Using index to handle multiple panels
    index = 0
    try:
        for elem in elements:
            class_of_element = elem.get_attribute("class")
            if class_of_element == 'cs-trans-icon':
                # Panel opens with click
                elem.click()
                time.sleep(3)
                textBoxes = bot.find_elements_by_tag_name('textarea')
                # Loop only specific index of list 
                phrases = langs[index]
                # Itearating TextBoxes
                for i in range(len(phrases)):
                    textBoxes[i].send_keys(phrases[i].title())
                time.sleep(3)
                # Increasing index for next panel
                index = index+1
                try:
                    bot.find_element_by_class_name('CsImageButton').click()
                except NoSuchElementException:
                    bot.find_element_by_class_name('cso-btn').click()
            time.sleep(3)  
    except ElementClickInterceptedException:
        pass 
Enter fullscreen mode Exit fullscreen mode

索引在此解决方案中起着重要作用。我们之前提到过,我们需要处理多个面板,因此索引可以避免循环读取每个面板中的所有行。假设您有 3 行数据,如果不使用索引,程序将继续循环,直到读取完第 3 行。因此,每个文本框将有 3 个值。但是,我们只需要将第一行的值发送到第一个面板的文本框中,将第二行的值发送到第二个面板的文本框中,依此类推。

一旦定义了索引,我们就可以迭代文本框。这样,行中的第一个值将发送到第一个文本框行中的第二个值将发送到第二个文本框,依此类推。

这些示例来自真实世界的项目,因此我建议将这篇文章加入书签。

处理下拉菜单

因此,有两种方法可以处理下拉菜单。

第一个解决方案是使用 selenium 的 Select 方法从下拉列表中选择选项。

from selenium.webdriver.support.ui import Select

bot = self.bot
bot.get("https://example.com")
select = Select(bot.find_element_by_xpath("//select"))
# select bu index of option
select.select_by_index(2)
# select by text of option
select.select_by_visible_text('Visible Text')
# select by value of option
select.select_by_value('value')
Enter fullscreen mode Exit fullscreen mode

第二种解决方案是仅使用 xpath 单击下拉项:

bot.find_element_by_xpath("//select/option[text()='Option_Text_Here']").click()
Enter fullscreen mode Exit fullscreen mode

使用 xpath 导航父元素

有时 HTML 结构可能会混乱,导致您无法选择所需的元素。在这种情况下,最好导航到父元素或使用 XPath 返回:

# elem is a web element object
# selenium will jump 2 step back to look for parent element
 parent_element = elem.find_element_by_xpath('..').find_element_by_xpath('..')
Enter fullscreen mode Exit fullscreen mode

任务完成!

就这些了!我和大家分享了我的 Python 自动化经验,希望它能帮到你,并节省你在网上搜索的时间。

请访问Reverse Python获取更多文章(您不会失望的),并在评论中告诉我我的下一篇文章应该涉及什么。

很快再见,DEVs!保持联系!

文章来源:https://dev.to/thedevtimeline/advanced-automation-tips-with-python-selenium-17j0
PREV
使用 Python 构建虚拟助手 | 自动执行任务
NEXT
JavaScript 模块入门