selenium 是一个自动化测试工具,可以运行浏览器并且像人手工一样进行操作,能够做到 RPA 的功能。程序员可以从 selenium 上直接提取网页上的各种信息。
pip install selenium
安装 selenium 库selenium.webdriver.Chrome()
实例化一个driver时,通过Service对象指明驱动器所在路径,例:from selenium.webdriver import Chrome
from selenium.webdriver.chrome.service import Service # 引入 Service 对象
import time
url = 'https://www.baidu.com'
path = Service('e:\\chromedriver.exe') # 将路径实例化为一个Service对象
chrome = webdriver.Chrome(service=path) # 实例化浏览器对象,打开浏览器
chrome.get(url) # 浏览地址页面
chrome.quit() # 关闭浏览器
使用 from selenium.webdriver import Chrome
可以引入 chrome 操作的库,如果浏览器不一样,可以将 Chrome 换成使用的浏览器
搭建好环境后,可以测试使用 selenium 了。
import time
from selenium.webdriver import Chrome
from selenium.webdriver.chrome.service import Service
path = Service('D:\\360极速浏览器X下载\\chromedriver.exe') # 获取浏览器驱动的路径
chrome = Chrome(service=path) # 实例化浏览器对象
chrome.get('https://www.baidu.com') # 跳转到页面
chrome.maximize_window() # 窗口最大化
print(chrome.title) # 输出一下页面 title
chrome.find_element('id', 'kw').send_keys('python') # 找到 id = 'kw' 的元素,输入 'python'
chrome.find_element('id', 'su').click() # 找到 id = 'su' 的元素,点击
time.sleep(2)
chrome.close()
使用 .find_element(by=By.ID,value=None)->WebElement
方法来定位单一元素,使用 .find_elements(by=By.ID,value=None)->list of WebElement
来定位若干元素
chrome.find_element('id', 'kw')
可以引入 By 来获取更多的定位方式 from selenium.webdriver.common.by import By
,例如:
from selenium.webdriver.common.by import By
chrome.find_element(by=By.CLASS_NAME, value='logo') # 根据 class 定位
chrome.find_element('id', 'changeCity_btn') # 根据 ID 定位,等同于 chrome.find_element(by=By.ID, value='changeCity_btn')
chrome.find_element(by=By.XPATH, value='//*[@id="changeCityBox"]') # 根据 xpath 定位
也可以使用分级的方式进行定位
chrome.find_element('id', 'changeCity_btn').find_element(by=By.TAG_NAME, value='span')
定位方式 | 说明 |
---|---|
By.ID | 按照元素 id 属性定位 |
By.CLASS_NAME | 按照 class 属性定位 |
By.TAG_NAME | 按照标签名称定位 |
By.Name | 按照 name 属性定位 |
By.XPATH | 按照XPATH语法定位 |
By.LINK_TEXT | 按照链接(a标签)的文本属性(text)定位 |
By.PARTIAL_LINK_TEXT | 按照链接(a标签)的部分文本属性(text)定位 |
By.CSS_SELECTOR | 按照 CSS 选择器定位 |
需要注意的是,使用 xpath 方式定位时,按照标签内文本定位标签语法如下例:
chrome.find_element(by=By.XPATH, value='//a[contains(text(),"全国")]') # 等同于 chrome.find_element(by=By.LINK_TEXT, value='全国')
定位获取到元素后,就可以进行一些需要的操作了,比如点击、输入文本等。
chrome.find_element(by=By.XPATH, value='//a[contains(text(),"全国")]').click() # 点击定位的元素
text = chrome.find_element(by=By.TAG_NAME, value='span').text # 获取元素的文本
chrome.find_element('id', 'kw').send_keys('python') # 输入文本
url = chrome.find_element(by=By.CLASS_NAME, value='logo').get_attribute('href') # 获取元素的属性
元素的方法 | 说明 |
---|---|
tag_name | 获取标签名称 |
text | 获取标签文本(包含所有子元素中的文本内容) |
click() | 点击标签 |
submit() | 提交一个 Form |
clear() | 如果是一个能够输入文本的元素,清空文本 |
get_attribute(name) | 获取元素的属性,参数 name 是属性名称 |
is_selected() | 返回元素是否被选中(checkbox) |
is_enable() | 返回元素是否可用 |
send_keys(*value) | 模拟输入文本,可以连续输入,例:send_keys('python',' pycharm') |
is_displayed() | 返回元素是否可见 |
size | 返回元素的大小(宽、高) |
location | 返回元素的位置(x,y) |
screenshot(filename) | 截图,保存到绝对路径的文件 filename 中(png格式) |
screenshot_as_png | 返回二进制 png 格式的截图 |
parent | 返回父元素 |
id | 返回 id 属性 |
需要注意的是,使用 send_keys(*value)
模拟输入特殊按键,例如回车,需要引入类 Keys。使用 from selenium.webdriver.common.keys import Keys
。然后特殊的按键可以从 Keys 类中查找。
chrome.find_element('id', 'kw').send_keys('python', Keys.ENTER)
模拟事件需要引入事件链 ActionChains 类 from selenium.webdriver.common.action_chains import ActionChains
。
action = ActionChains(chrome) # 绑定事件到浏览器对象
action.move_to_element_with_offset(img, x, y) # 带着偏移量移动到元素 img 的某个位置(坐标为 x,y),定义元素的左上角坐标为 0, 0
action.click() # 点击操作
action.perform() # 提交事件并执行
action.drag_and_drop_by_offset(btn, 300, 0) # 将 btn 元素拖拽到相对位置 x,y 的地方,然后释放
action.perform() # 提交事件并执行
注意使用事件时,不要手动操作,否则容易出错。
由 selenium 新打开的窗口,在 selenium 看来是后台窗口,所以要使用的时候需要进行窗口切换。使用 chrome.switch_to.window()
来切换窗口。例如:
chrome.switch_to.window(chrome.window_handles[-1]) # 切换窗口到浏览器所有窗口的最后一个
操作完成后,可以关闭当前窗口:
chrome.close() # 关闭子窗口
chrome.switch_to.window(chrome.window_handles[0]) # 回到第一个窗口
有些页面使用了页面嵌套,比如 iframe 标签,就必须切换 selenium 视角到 iframe ,然后才能拿到数据
iframe = chrome.find_element(by=By.XPATH, value='//*[@id="player_ifram"]') # 定位到 iframe
chrome.switch_to.frame(iframe) # 切换到 iframe 框架内部
chrome.switch_to.default_content() # 切换回原页面
sel_el = chrome.find_element(by=By.XPATH, value='//*[@id="OpthonDate"]') # 获取下拉列表元素(select 标签)
from selenium.webdriver.support.select import Select # 引入下拉列表支持
sel = Select(sel_el) # 对元素进行包装,包装成下拉菜单
# sel.options 能够获取下拉菜单有多少个选项
for i in range(len(sel.options)): # i 是每个下拉选项的索引位置
sel.select_by_index(i) # 按照索引进行切换
使用 selenium 时,是模仿手工进行操作。但是浏览器不需要在前台显示,在后台运行然后返回需要的数据就可以了。
from selenium.webdriver.chrome.options import Options # 引入设置
opt = Options() # 创建设置对象
opt.add_argument('--headless') # 无头,即后台运行
opt.add_argumnet('--disable-gpu') # 不显示
chrome = Chrome(options=opt) # 创建实例时启用设置
可用的设置参数有
参数 | 说明 |
---|---|
user-agent= | 设置请求头的 user-agent |
–start-maximized | 最大化运行(全屏窗口) |
–incognito | 隐身模式(无痕模式) |
–hide-scrollbars | 隐藏滚动条 |
–disable-javascript | 禁用 js |
blink-settings=imagesEnabled=false | 不加载图片,提升速度 |
–disable-blink-features=AutomationControlled | 关闭自动化控制标记(防止navigator检查) |
–headless | 不提供可视化页面 |
–ignore-certificate-errors | 禁用扩展插件并实现窗口最大化 |
–disable-gpu | 禁用GPU加速 |
–proxy-server= | 使用代理 |
可以通过 selenium 获取浏览器加载并运行 js 处理过的页面代码。
chrome.page_source # 返回经过浏览器和 js 处理过的页面代码