- 内容提要
- 作者简介
- 技术评审者简介
- 致谢
- 译者序 会编程的人不一样
- 前言
- 本书的读者对象
- 编码规范
- 什么是编程
- 本书简介
- 下载和安装 Python
- 启动 IDLE
- 如何寻求帮助
- 聪明地提出编程问题
- 小结
- 第一部分 Python 编程基础
- 第1章 Python 基础
- 第2章 控制流
- 第3章 函数
- 第4章 列表
- 第5章 字典和结构化数据
- 第6章 字符串操作
- 第二部分 自动化任务
- 第7章 模式匹配与正则表达式
- 第8章 读写文件
- 第9章 组织文件
- 第10章 调试
- 第11章 从 Web 抓取信息
- 第12章 处理 Excel 电子表格
- 第13章 处理 PDF 和 Word 文档
- 第14章 处理 CSV 文件和 JSON 数据
- 第15章 保持时间、计划任务和启动程序
- 第16章 发送电子邮件和短信
- 第17章 操作图像
- 第18章 用 GUI 自动化控制键盘和鼠标
- 附录A 安装第三方模块
- 附录B 运行程序
- 附录C 习题答案
11.8 用 selenium 模块控制浏览器
selenium模块让Python直接控制浏览器,实际点击链接,填写登录信息,几乎就像是有一个人类用户在与页面交互。与Requests和Beautiful Soup相比,Selenium允许你用高级得多的方式与网页交互。但因为它启动了Web浏览器,假如你只是想从网络上下载一些文件,会有点慢,并且难以在后台运行。
附录A有安装第三方模块的详细步骤。
11.8.1 启动selenium控制的浏览器
对于这些例子,你需要FireFox浏览器。它将成为你控制的浏览器。如果你还没有FireFox,可以从http://getfirefox.com/免费下载它。
导入selenium的模块需要一点技巧。不是import selenium,而是要运行from selenium import webdriver(为什么selenium模块要使用这种方式设置?答案超出了本书的范围)。之后,你可以用selenium启动FireFox浏览器。在交互式环境中输入以下代码:
>>> from selenium import webdriver >>> browser = webdriver.Firefox() >>> type(browser) < class 'selenium.webdriver.firefox.webdriver.WebDriver'> >>> browser.get('http://inventwithpython.com')
你会注意到,当 webdriver.Firefox()被调用时,FireFox 浏览器启动了。对值webdriver.Firefox()调用 type(),揭示它具有 WebDriver 数据类型。调用 browser. get('http://inventwithpython.com')将浏览器指向http://inventwithpython.com/。浏览器应该看起来如图11-7所示。
图11-7 在IDLE中调用webdriver.Firefox()和get()后,FireFox浏览器出现了
11.8.2 在页面中寻找元素
WebDriver对象有好几种方法,用于在页面中寻找元素。它们被分成findelement和findelements方法。findelement方法返回一个WebElement对象,代表页面中匹配查询的第一个元素。findelements方法返回WebElement_*对象的列表,包含页面中所有匹配的元素。
表11-3展示了findelement和findelements方法的几个例子,它们在变量browser中保存的WebDriver对象上调用。
表11-3 selenium的WebDriver方法,用于寻找元素
方法名
返回的WebElement对象/列表
browser.find_element_by_class_name(name) browser.find_elements_by_class_name(name)
使用CSS类name的元素
browser.find_element_by_css_selector(selector) browser.find_elements_by_css_selector(selector)
匹配CSS selector的元素
browser.find_element_by_id(id) browser.find_elements_by_id(id)
匹配id属性值的元素
browser.find_element_by_link_text(text) browser.find_elements_by_link_text(text)
完全匹配提供的text的< a>元素
browser.find_element_by_partial_link_text(text) browser.find_elements_by_partial_link_text(text)
包含提供的text的< a>元素
browser.find_element_by_name(name) browser.find_elements_by_name(name)
匹配name属性值的元素
browser.find_element_by_tag_name(name) browser.find_elements_by_tag_name(name)
匹配标签name的元素 (大小写无关,< a>元素匹配'a'和'A')
除了*_by_tag_name()方法,所有方法的参数都是区分大小写的。如果页面上没有元素匹配该方法要查找的元素,selenium模块就会抛出NoSuchElement异常。如果你不希望这个异常让程序崩溃,就在代码中添加try和except语句。
一旦有了WebElement对象,就可以读取表11-4中的属性,或调用其中的方法,了解它的更多功能。
表11-4 WebElement的属性和方法
属性或方法
描述
tag_name
标签名,例如 'a'表示< a>元素
get_attribute(name)
该元素name属性的值
text
该元素内的文本,例如< span>hello< /span>中的'hello'
clear()
对于文本字段或文本区域元素,清除其中输入的文本
is_displayed()
如果该元素可见,返回True,否则返回False
is_enabled()
对于输入元素,如果该元素启用,返回True,否则返回False
is_selected()
对于复选框或单选框元素,如果该元素被选中,选择True,否则返回False
location
一个字典,包含键'x'和'y',表示该元素在页面上的位置
例如,打开一个新的文件编辑器,输入以下程序:
from selenium import webdriver browser = webdriver.Firefox() browser.get('http://inventwithpython.com') try: elem = browser.find_element_by_class_name('bookcover') print('Found < %s> element with that class name!' % (elem.tag_name)) except: print('Was not able to find an element with that name.')
这里我们打开FireFox,让它指向一个URL。在这个页面上,我们试图找到带有类名'bookcover'的元素。如果找到这样的元素,我们就用tag_name属性将它的标签名打印出来。如果没有找到这样的元素,就打印不同的信息。
这个程序的输出如下:
Found < img> element with that class name!
我们发现了一个元素带有类名'bookcover',它的标签名是'img'。
11.8.3 点击页面
findelement和findelements方法返回的WebElement对象有一个click()方法,模拟鼠标在该元素上点击。这个方法可以用于链接跳转,选择单选按钮,点击提交按钮,或者触发该元素被鼠标点击时发生的任何事情。例如,在交互式环境中输入以下代码:
>>> from selenium import webdriver >>> browser = webdriver.Firefox() >>> browser.get('http://inventwithpython.com') >>> linkElem = browser.find_element_by_link_text('Read It Online') >>> type(linkElem) < class 'selenium.webdriver.remote.webelement.WebElement'> >>> linkElem.click() # follows the "Read It Online" link
这段程序打开FireFox,指向http://inventwithpython.com/,取得< a>元素的WebElement对象,它的文本是“Read It Online”,然后模拟点击这个元素。就像你自己点击这个链接一样,浏览器将跳转到这个链接。
11.8.4 填写并提交表单
向Web页面的文本字段发送击键,只要找到那个文本字段的< input>或< textarea>元素,然后调用send_keys()方法。例如,在交互式环境中输入以下代码:
<code>>>> from selenium import webdriver >>> browser = webdriver.Firefox() >>> browser.get('http://gmail.com') >>> emailElem = browser.find_element_by_id('Email') >>> emailElem.send_keys('not_my_real_email@gmail.com') >>> passwordElem = browser.find_element_by_id('Passwd') >>> passwordElem.send_keys('12345') >>> passwordElem.submit()
只要Gmail没有在本书出版后改变Username和Password文本字段的id,上面的代码就会用提供的文本填写这些文本字段(你总是可以用浏览器的开发者工具验证id)。在任何元素上调用submit()方法,都等同于点击该元素所在表单的Submit按钮(你可以很容易地调用emailElem.submit(),代码所做的事情一样)。
11.8.5 发送特殊键
selenium有一个模块,针对不能用字符串值输入的键盘击键。它的功能非常类似于转义字符。这些值保存在selenium.webdriver.common.keys模块的属性中。由于这个模块名非常长,所以在程序顶部运行from selenium.webdriver. common.keys import Keys就比较容易。如果这么做,原来需要写from selenium. webdriver.common.keys的地方,就只要写Keys。表11-5列出了常用的Keys变量。
表11-5 selenium.webdriver.common.keys模块中常用的变量
属性
含义
Keys.DOWN, Keys.UP, Keys.LEFT,Keys.RIGHT
键盘箭头键
Keys.ENTER, Keys.RETURN
回车和换行键
Keys.HOME, Keys.END, Keys.PAGE_DOWN,Keys.PAGE_UP
Home键、End键、PageUp键和Page Down键
Keys.ESCAPE, Keys.BACK_SPACE,Keys.DELETE
Esc、Backspace和字母键
Keys.F1, Keys.F2, . . . , Keys.F12
键盘顶部的F1到F12键
Keys.TAB
Tab键
例如,如果光标当前不在文本字段中,按下home和end键,将使浏览器滚动到页面的顶部或底部。在交互式环境中输入以下代码,注意send_keys()调用是如何滚动页面的:
>>> from selenium import webdriver >>> from selenium.webdriver.common.keys import Keys >>> browser = webdriver.Firefox() >>> browser.get('http://nostarch.com') >>> htmlElem = browser.find_element_by_tag_name('html') >>> htmlElem.send_keys(Keys.END) # scrolls to bottom >>> htmlElem.send_keys(Keys.HOME) # scrolls to top
< html>标签是HTML文件中的基本标签:HTML文件的完整内容包含在< html>和< /html>标签之内。调用browser.find_element_by_tag_name('html')是像一般Web页面发送按键的好地方。当你滚动到该页的底部,新的内容就会加载,这可能会有用。
11.8.6 点击浏览器按钮
利用以下的方法,selenium也可以模拟点击各种浏览器按钮:
browser.back()点击“返回”按钮。
browser.forward()点击“前进”按钮。
browser.refresh()点击“刷新”按钮。
browser.quit()点击“关闭窗口”按钮。
11.8.7 关于selenium的更多信息
selenium能做的事远远超出了这里描述的功能。它可以修改浏览器的cookie,截取页面快照,运行定制的JavaScript。要了解这些功能的更多信息,请参考文档:http://selenium-python.readthedocs.org/。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论