Selenium in Python

Posted by JHSN on March 17, 2017

本文大部分内容是我从 官方文档Selenium with Python(对官方文档的阅读整理) 挑选、翻译、整理的,旨在介绍如何简单快速上手 Selenium。本文不介绍服务端方向的 API 。


1 简介

Python 中的 Selenium 模块集成提供了一些方式非常直接、操作非常简单的 API 以供用户方便地使用浏览器 Driver(如 Firefox, Chrome, IE, Edge 等等)去进行网页交互。本文主要阐述 Chrome Driver 下的操作。


2 安装

  1. 安装 Selenium 库。在命令行中输入 pip install selenium
  2. 安装 Driver。Selenium 需要一个浏览器的驱动程序去渲染整个页面,你需要下载它,将它放置在 PATH 包含的路径下或将其路径加入到 PATH 中。下载链接:Chrome   Firefox   Safari   Edge


3 尝鲜

运行以下代码,查看是否会正常访问网页并做出操作。

from selenium import webdriver
# 推荐的 import webdriver 的方式

from selenium.webdriver.common.keys import Keys
# 推荐的 import 特殊按键的方式


driver = webdriver.Chrome()
# 创建一个实例

driver.get("http://blog.chrstm.com")
# 访问网页,程序会等待页面加载完毕(但是 Driver 不会知道你的 AJAX 是否加载完毕了,如果你有这方面的需求,可以使用 WebDriverWait)

elem = driver.find_element_by_class_name("subheading")
# 该处通过检索类属性寻找并定位元素(此处 driver 可视为 body),是 find_element_by_* 方法中的一种

print(elem.get_attribute("innerHTML"))
# 获取元素属性并输出

driver.get("http://www.python.org")
elem = driver.find_element_by_name("q")
# 该处通过检索名字属性寻找并定位元素(此处 driver 可视为 body),是 find_element_by_* 方法中的一种

elem.clear()
#清除元素的文本内容

elem.send_keys("pycon")
#模拟键盘输入

elem.send_keys(Keys.RETURN)
#模拟键盘特殊按键

driver.quit()
#关闭浏览器



4 定位元素

Base on object: WebElement / WebDriver

4.1 定位一个元素

  • find_element(by=’id’, value=None) (供下列函数调用的私有函数)
  • find_element_by_class_name()
  • find_element_by_css_selector()
  • find_element_by_id()
  • find_element_by_link_text()
  • find_element_by_name()
  • find_element_by_partial_link_text() (链接的某一部分)
  • find_element_by_tag_name()
  • find_element_by_xpath()

4.2 一次定位多个元素

  • find_elements(by=’id’, value=None) (供下列函数调用的私有函数)
  • find_elements_by_name()
  • find_elements_by_xpath()
  • find_elements_by_link_text()
  • find_elements_by_partial_link_text()
  • find_elements_by_tag_name()
  • find_elements_by_class_name()
  • find_elements_by_css_selector()



5 元素属性及交互

5.1 Keys class

推荐引用方式:from selenium.webdriver.common.keys import Keys
这是一个特殊按键编码的集合。

KeyBoard Keys Class
Ctrl Keys.CONTROL
Alt Keys.ALT
Shift Keys.SHIFT
Tab Keys.TAB
Space Keys.SPACE
Keys.ARROW_DOWN
Keys.ARROW_LEFT
…… ……

完整列表请参见 selenium.webdriver.common.keys

5.2 WebElement

Base on object: WebElement

  • id
    • 返回 Selenium 内部 ID(不是 DOM 的 id),主要是内部使用(比如用于判断两元素是否是同一个元素)。

  • text
    • 返回元素文本内容。

  • tag_name
    • 返回元素标签名称。

  • is_displayed()
    • 返回一个布尔值,表示元素是否显示。

  • is_selected()
    • 返回一个布尔值,表示元素是否被选中。

  • location
    • 返回一个表示元素方位的 dict,例如 {'x': 120, 'y': 272} 。

  • parent
    • 返回父元素(一个 WebElement 类或者 WebDriver 类)。

  • clear()
    • 清除元素文本内容。

  • click()
    • 点击元素。

  • get_attribute(name)
    • 获取元素的属性,优先检索 property,再检索 attribute。如果未对该属性赋值,返回空字符串。如果不存在该属性,则返回 None

  • get_property(name)
    • 获取元素的 property。如果未对该属性赋值,返回值为空。如果不存在该属性,则返回None。特别地,如果选取的是 style 属性,则返回一个 list 。

  • value_of_css_property(property_name)
    • 获取元素 CSS 中的属性。

  • submit()
    • 提交一个表单。

  • size
    • 返回一个包含长宽的 dict。例如 {'height': 16, 'width': 100} 。


5.3 Action Chains

推荐引用方式:from selenium.webdriver.common.action_chains import ActionChains
Base on object: ActionChains(driver)
Usage:

action = ActionChains(driver)
action.method()
...
action.perform()

# 或者

ActionChains(driver).method(). ... .method().perform()

API:

  • click(on_element=None)
    • 模拟点击一个元素。如果元素为空,则点击鼠标当前所在位置。

  • click_and_hold(on_element=None)
    • 模拟点击鼠标左键并且不释放。如果元素为空,则点击鼠标当前所在位置。

  • context_click(on_element=None)
    • 模拟点击鼠标右键。如果元素为空,则点击鼠标当前所在位置。

  • double_click(on_element=None)
    • 双击一个元素。如果元素为空,则点击鼠标当前所在位置。

  • drag_and_drop(source, target)
    • 点击 source 元素不释放,将其拖动至 target 元素区域后释放。

  • drag_and_drop_by_offset(source, xoffset, yoffset)
    • 点击 source 元素不释放,将其拖动至 (xoffset, yoffset) 坐标后释放。

  • key_down(value, element=None)
    • 在 element 中输入 value 键且不释放(应该只用于一些修饰键:Ctrl, Alt, Shift 等)。如果元素为空,则默认选择当前聚焦的元素。

  • key_up(value, element=None)
    • 在 element 中释放 value 键(应该只用于一些修饰键:Ctrl, Alt, Shift 等)。如果元素为空,则默认选择当前聚焦的元素。

  • move_by_offset(xoffset, yoffset)
    • 将鼠标从当前位置移向 (xoffset, yoffset) 坐标。

  • move_to_element(to_element)
    • 将鼠标移到元素中央。

  • move_to_element_with_offset(to_element, xoffset, yoffset)
    • 将鼠标移到 to_element 元素中相对左上角的 (xoffset, yoffset) 坐标。

  • perform()
    • 执行所有绑定的动作

  • release(on_element=None)
    • 释放在元素上按住的鼠标。如果元素为空,则默认在当前位置释放鼠标。

  • send_keys(*keys_to_send)
    • 在当前聚焦的元素中输入按键。

  • send_keys_to_elemet(element, *keys_to_send)
    • 向 element 中输入按键。


5.4 WebDriver

Base on object: webdriver

  • current_url
    • 返回当前标签的 URL 。

  • title
    • 返回当前标签的 title 。

  • current_window_handle
    • 返回当前标签窗口句柄。

  • window_handles
    • 返回所有的标签窗口句柄。

  • get(url)
    • 加载网页。

  • fresh()
    • 刷新当前网页。

  • back()
    • 在浏览历史中后退一步。

  • forward()
    • 在浏览历史中前进一步。

  • close()
    • 关闭当前标签页。

  • quit()
    • 关闭 webdriver 。

  • add_cookie(cookie_dict)
    • 添加 Cookie 。

  • delete_all_cookies()
    • 删除所有的 Cookie 。

  • delete_cookie(name)
    • 删除单条 Cookie 。

  • get_cookies()
    • 获取所有的 Cookie 。

  • get_cookie(name)
    • 获取单条 Cookie 。

  • execute_script(script, *args)
    • 执行 JavaScript 代码。
  • execute_async_script(script, *args)
    • 异步执行 JavaScript 代码。

  • get_screenshot_as_file(filename) / save_screenshot(filename)
    • 对当前页面进行截图并存储。




6 Request & Headers

GET 可以直接通过修改 URL 解决。
POST 可以通过设置一个模拟表单解决。
……
嫌太麻烦?有个 module 叫做 seleniumrequests 呢。可以去瞧瞧哦。

什么,还想修改你的 Http Headers?
ChromeDriver 可以这样改:

from selenium import webdriver

options = webdriver.ChromeOptions()
options.add_argument('user-agent="..."')
print(options)
browser = webdriver.Chrome(chrome_options=options)
browser.get("http://chrstm.com")
browser.quit()

Firefox 怎么改?我也不会,真的。




评论区加载中