总览
我为Envato Tuts +写了很多教程。 这些教程的标题需要遵循某些大写规则。 Tuts +为我们的作者提供了一个基于Web的工具,该工具获取标题文本并返回适当的大写标题。 在编写教程时,我试图进入流程,而切换到大写工具会中断流程。 我曾经只给它加翅膀,然后自己大写。
事实证明,我经常犯错误,这给必须更正错误的Tuts +编辑者带来了额外的工作。 作为一名程序员,我决定以自己的方式解决问题。 我仍然写自己的标题,但完成后,我运行一个Python小程序,该程序解析我的文章,检测所有标题,然后通过Tuts +大写工具运行它们,并适当地将所有标题大写。
由于大写工具是基于Web的应用程序,而不是API,因此我必须使浏览器自动化才能调用它并提取大写的标题。 在本教程中,您将学习如何通过Selenium在Python中控制浏览器并使之发挥作用。
如何大写标题
标题大写不是火箭科学,但也不是一件容易的事。 有几种样式,有些重叠并且有些变化。 这或多或少是共识:
- 用四个或更多字母大写所有单词。
- 始终大写首尾两个字。
- 不要大写文章:a,an,the。
- 不要大写短的连词:和,或者,或者,不是,但是,所以。
然后是一堆例外情况和特殊情况(例如,标题流向下一行)。 但这一切都没有意义。 即使我决定编写自己的大写代码,Tuts +也已经选择了它们的风格,并且我需要遵循他们选择的样式。
在线案例转换器
Tuts +大写工具是仅供Tuts +讲师使用的内部工具,因此我不能将其用作演示。 但是,我发现了一个名为Title Case Converter的类似工具。 这是一个具有较大文本区域的Web应用程序,您可以在其中键入标题(或标题),单击以提交表单的转换按钮,出现带有正确大写标题的输出区域,最后是复制按钮的复制按钮。将标题转换为剪贴板。
资本化工具自动化计划
好。 我将使用在线案例转换器,但是没有API。 这不是大问题。 我可以使浏览器自动化,并模拟用户在输入字段中输入标题,单击转换按钮,等待输出显示,单击复制按钮,最后从剪贴板粘贴正确大写的标题。
第一步是选择浏览器自动化。 我选择了Selenium WebDriver,我之前已经成功使用过。 该计划的其余部分是:
- 启动浏览器。
- 导航到在线案例转换器URL。
- 找到所有必要的元素。
- 填充输入字段。
- 提交表格。
- 等待输出。
- 单击复制按钮。
- 从剪贴板中读取大写的标题。
完整的源代码可以在GitLab上找到。
Selenium简介
自2004年以来,Selenium就一直实现浏览器的自动化。2008年,它与WebDriver项目合并,该项目解决了原始Selenium的某些局限性(例如,在JavaScript沙箱中运行)。
Selenium仍然提供Selenium的原始风味,即SeleniumRC(远程控制)。 它还具有一个用于编写自动化测试套件的IDE和一个名为Selenium Grid的工具,该工具可将Selenium RC扩展为必须在多个环境中运行的大型测试套件。 我们将限制自己通过WebDriver API(又名Selenium 2)以编程方式访问浏览器。
安装Selenium和Web驱动程序
安装Selenium就像pipenv selenium
一样简单。 如果您不熟悉Pipenv,请查看“ 使用Pipenv重新访问Python打包” 。 您还需要特定的Web驱动程序。 有用于不同浏览器和后端的Web驱动程序。 您可以在Selenium网站上找到完整列表。
我选择了本教程的Chrome网络驱动程序。 这是最新版本 。
它是一个zip文件,其中包含一个可执行文件(有Windows,macOS和Linux版本)。 下载后,将其解压缩并放入路径。
恭喜你! 现在您可以使用Python的Selenium WebDriver。
启动浏览器
Selenium使启动浏览器变得非常容易。 只要您的路径中有正确的Web驱动程序,就只需导入selenium.webdriver
模块并调用适当的方法来启动您选择的浏览器:
from selenium import webdriver
driver = webdriver.Chrome()
导航到URL
一旦有了驱动程序对象,就可以调用get()
方法导航到任何网页。 这是导航到标题案例转换器的方法:
driver.get('https://titlecaseconverter.com')
寻找元素
我们需要一种方法来找到您要与之交互的页面上的元素。 最简单的方法是在浏览器中检查网页并找到目标元素的ID。 在以下屏幕截图中,您可以看到输入字段的ID为“ title”:
转换按钮没有ID,但这不是问题,您很快就会看到。 这是通过id查找表单和文本字段的代码:
input_field = driver.find_element_by_id('title')
如果要与之交互的元素没有ID,则可以使用其他各种方法(例如名称,类名或CSS选择器)找到它。 请参阅本Selenium指南中的所有选项。
例如,要找到转换按钮,我使用了它的类名:
convertButton = \
driver.find_element_by_class_name('convertButton')
填充文本字段
要填充输入字段,我们可以使用输入字段元素的send_keys()
方法。 但是请确保先清除它。 否则,您将仅追加到现有文本。
input_field.clear()
input_field.send_keys(heading)
那很容易。
单击按钮并提交表单
现在,该提交表单了。 您可以通过两种方式进行操作:
- 在页面上找到表单元素,然后调用其
submit()
方法。 - 找到转换按钮,然后单击它。
我最初直接提交表单:
form = driver.find_element_by_css_selector('body > form')
form.submit()
由于某种原因,它不起作用。 没有错误,但是什么也没有发生。 我没有花太多时间进行调查,因为Selenium和本教程的重点是模拟一个人。 因此,我使用了另一种方法,只是单击了我之前发现的按钮:
convertButton.click()
等待表格提交
在线案例转换器有点花哨。 最初不存在输出字段。 单击转换按钮并提交表单后,输出与复制按钮一起显示。 这意味着我们必须等到表单提交完成后,复制按钮才会出现,我们可以单击它以将输出复制到剪贴板。
Selenium让您受够了。 它支持等待任意条件,如果没有实现,则可以超时。 这是等待复制按钮的代码。 它创建一个具有五秒钟超时的WebDriverWait
对象。 然后,它为类名称为copyButton
的元素的存在创建条件,然后使用该条件调用等待对象的until()
方法。
wait = WebDriverWait(driver, 5)
buttonPresent = presence_of_element_located((By.CLASS_NAME, 'copyButton'))
copyButton = wait.until(buttonPresent)
结果是,单击转换按钮后,它将等到复制按钮出现或五秒钟后超时。 如果一切顺利,它将返回copyButton
元素。
阅读大写标题
您可以使用field.get_attribute('value')
读取文本字段的内容。 但是,正如我之前提到的,在线案例转换器有点花哨。 它的输出是span和div的嵌套结构,当您将鼠标悬停在输出的每个部分上时,它会告诉您为什么将其大写。
我可以深入研究这个迷宫并解析实际的标题,但是有一种更简单的方法。 复制按钮将大写的标题复制到剪贴板。 我们只需单击按钮,然后从剪贴板中读取标题即可。 我使用了剪贴板模块,您可以使用pipenv install clipboard
。 下面的代码通过将一个空字符串复制到剪贴板中来清除剪贴板,单击“复制”按钮,并反复读取剪贴板,直到剪贴板不为空。
clipboard.copy('')
copyButton.click()
result = clipboard.paste()
while not result:
time.sleep(0.1)
result = clipboard.paste()
大写整个Markdown文档
好。 我们可以将一个标题大写。 我将所有这些代码放在一个函数中:
def capitalize_heading(heading):
input_field = driver.find_element_by_id('title')
input_field.clear()
input_field.send_keys(heading)
# form = driver.find_element_by_css_selector('body > form')
# form.submit()
convertButton = \
driver.find_element_by_class_name('convertButton')
convertButton.click()
# Wait for copy button to appear
wait = WebDriverWait(driver, 5)
buttonPresent = presence_of_element_located((By.CLASS_NAME,
'copyButton'))
copyButton = wait.until(buttonPresent)
clipboard.copy('')
copyButton.click()
result = clipboard.paste()
while not result:
time.sleep(0.1)
result = clipboard.paste()
return result
现在,有了这项功能,我们就可以分析整篇文章并将所有标题都大写。 我用Markdown写教程。 我所有的标题都以一个或多个哈希(#)开头。
我定义了一个辅助函数,该函数接受一行,如果包含标题,则使用capitalize_heading()
函数正确将其capitalize_heading()
并返回结果。 最主要的是剥离所有主要的哈希和空格,并在以后还原它们。 我们无法将标题放在前导空格,因为它会使在线大小写转换器引起混淆:
def capitalize_line(line):
tokens = line.split('#')
heading = tokens[-1]
space_count = len(heading) - len(heading.lstrip())
spacing = heading[:space_count]
tokens[-1] = spacing + capitalize_heading(heading.lstrip())
result = '#'.join(tokens)
return result
此时,我们可以大写Markdown标题。 现在该大写整个Markdown文档了。 这段代码非常简单-遍历所有行,大写以哈希开头的每一行,然后返回正确大写的文本:
def capitalize_all_headings(markdown)
:
capitalized = []
lines = markdown.split('\n')
for line in lines:
if line.startswith('#'):
line = capitalize_line(line)
print(line)
capitalized.append(line)
return '\n'.join(capitalized)
主要功能采用输入的Markdown文档,将其大写,然后将结果保存为“ capitalized.md”,您可以检查和使用。 唯一要注意的是Markdown文档是否包含以哈希开头的非标题行。 如果您处理包含Python或bash注释的代码块,则会发生这种情况。
有趣的事实-您正在阅读的教程已使用此程序大写。
结论
自动化浏览器可让您以编程方式控制不提供API的Web应用程序。 这主要用于表单填写和其他交互式Web活动(在长EULA上单击“下一步”?)。
Selenium最初是为测试Web应用程序而设计的,但是它在自动化任何基于浏览器的交互方面非常出色。 如果您稍作考虑,您可能会发现许多可以自动化的Web应用程序,并使您的生活更轻松。
翻译自: https://code.tutsplus.com/tutorials/how-i-learned-to-stop-worrying-and-love-the-capitalization-tool--cms-30299