Selenium 的使用
文章预览:
前言:
Selenium 是一个自动化测试工具,可以简单的理解为模拟真人操作。在爬虫中起到了很重要的作用,因为很多网站数据是来自于接口,且对接口做了加密再者有一些 页面经过了JavaScript 动态渲染,而selenium自动化非常有效解决这个问题。不仅桡过了这些反爬虫,而且直接获取到浏览器当前页面的源代码。
如果有想了解selenium原理的读者可以参考 Selenium的实现原理,一篇文章讲透彻!
selenium文档: https://selenium-python-zh.readthedocs.io/en/latest/
1. 准备工作
文章以 Chrome 为例来讲解 Selenium 的用法。在开始之前,必须先配置好环境和驱动。接下来给大家讲解如何安装
请确保已经正确安装好了 Chrome 浏览器并配置好了 ChromeDriver
。另外,还需要安装好 Python 的 Selenium
库(在终端中输入pip install selenium下载)
1.1 环境安装
谷歌下载:http://chorm.sdswrj.cn/browser.html
在python安装selenium库:在终端中输入pip install selenium
1.2 安装驱动(先看注意点)
官网:http://chromedriver.storage.googleapis.com/index.html
1.3 驱动放置
下载完之后,解压缩文件,打开之后会出现
复制exe文件,然后粘贴在python目录中:
这是作者的目录,请读者根据自己的目录放
注意:
- 驱动要对应浏览器版本,否者会无法启动
- 有一点点不同没关系,驱动版本尽量靠近浏览器版本就可以了
- 禁止浏览器更新 打开
cmd
输入services.msc
打开后台服务,把浏览器自动更新给禁止 因为selenium`据驱动打开浏览器进行功能操作 - 如果关闭不了,谷歌更新需要及时下载对应版本的驱动,其实网络上有禁止更新的版本
2. 声明浏览器对象
Selenium 支持多种浏览器,如 Chrome、Firefox、Edge 等,还有 Android、BlackBerry 等手机端的浏览器。另外,也支持无界面浏览器 PhantomJS。
2.1 我们可以用如下方式初始化:
from selenium import webdriver
browser = webdriver.Chrome() #如果使用的是Chrome浏览器,输入这一行
browser = webdriver.Firefox() #如果使用的是Firefox浏览器,输入这一行
browser = webdriver.Edge() #如果使用的是edge浏览器,输入这一行
browser = webdriver.PhantomJS() #如果使用的是phantomjs浏览器,输入这一行
browser = webdriver.Safari()
这样就完成了浏览器对象的初始化并将其赋值为 browser 对象。接下来,我们要做的就是调用 browser 对象,让其执行各个动作以模拟浏览器操作。
3. 基本使用
3.1、加载指定页面并关闭
from selenium import webdriver
import time
from selenium.webdriver.common.by import By
# 打开指定(chrome)浏览器
browser = webdriver.Chrome()
# 指定加载页面
browser.get("http://www.baidu.com/")
# 方法弃用
# browser.find_element_by_id('kw').send_keys('python')
# 通过name属性选择文本框元素,并设置内容
browser.find_element(By.NAME,'wd').send_keys("selenium")
# 通过通过ID属性获取“百度一下”按钮,并执行点击操作
browser.find_element(By.ID,"su").click()
# 提取页面
print(browser.page_source.encode('utf-8'))
# 提取cookie
print(browser.get_cookies())
# 获取当前页面截屏
print(browser.get_screenshot_as_file('123.png'))
# 提取当前请求地址
print(browser.current_url)
# 设置五秒后执行下一步
time.sleep(5)
# 关闭浏览器
browser.quit()
运行代码后发现,会自动弹出一个 Chrome 浏览器。浏览器首先会跳转到百度,然后在搜索框中输入 Python,接着跳转到搜索结果页
**selenium4新特性:**https://www.dilatoit.com/zh/2020/02/02/selenium-4-xintexingqianzhan.html
4. 初始化配置
from selenium import webdriver
options = webdriver.ChromeOptions()
# 禁止图片
prefs = {"profile.managed_default_content_settings.images": 2}
options.add_experimental_option("prefs", prefs)
# 无头模式 在后台运行
# options.add_argument("-headless")
# 通过设置user-agent
user_ag='MQQBrowser/26 Mozilla/5.0 (Linux; U; Android 2.3.7; zh-cn; MB200 Build/GRJ22;CyanogenMod-7) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1'
options.add_argument('user-agent=%s'% user_ag)
#隐藏"Chrome正在受到自动软件的控制"
options.add_experimental_option('useAutomationExtension', False) # 去掉开发者警告
options.add_experimental_option('excludeSwitches', ['enable-automation'])
#设置代理
# options.add_argument("--proxy-server=http://58.20.184.187:9091")
# 初始化配置
browser = webdriver.Chrome(chrome_options=options)
#将浏览器最大化显示
browser.maximize_window()
# 设置宽高
browser.set_window_size(480, 800)
# 通过js新打开一个窗口
browser.execute_script('window.open("http://httpbin.org/ip");')
5. 查找节点
Selenium 可以驱动浏览器完成各种操作,比如填充表单、模拟点击等。比如,我们想要完成向某个输入框输入文字的操作或者抓取数据,而 Selenium 提供了一系列查找节点的方法,我们可以用这些方法来获取想要的节点,以便下一步执行一些动作或者提取信息。
selenium提供了2种方法
find_element()
系列:用于定位单个的页面元素。find_elements()
系列:用于定位一组页面元素,获取到的是一组列表。
5.1 单个节点
我们用代码实现一下:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys # 模拟键盘操作
from selenium.webdriver.common.by import By
# 启动并打开指定页面
browser = webdriver.Chrome()
browser.get("http://www.baidu.com")
# 通过name属性选择文本框元素,并设置内容
s = browser.find_element(By.NAME,'wd')
s.send_keys('衣服')
s.send_keys(Keys.ENTER) # 回车 确定的意思
各种节点提取演示
browser.get("http://www.baidu.com")
# ID选折起定位
input_text = browser.find_element(By.ID, "kw")
input_text.send_keys("selenium")
# CSS 选择器定位
s =browser.find_element(By.CSS_SELECTOR,'input.s_ipt')
s.send_keys('衣服')
# xpath 选择器定位
s = browser.find_element(By.XPATH,'//input[@id="kw"]')
s.send_keys('衣服')
5.2 多个节点
如果要查找所有满足条件的节点,需要用 find_elements() 这样的方法。注意,在这个方法的名称中,element 多了一个 s,注意区分。
就可以这样来实现:
from selenium import webdriver
browser = webdriver.Chrome()
browser.get('https://www.icswb.com/channel-list-channel-161.html')
lis = browser.find_elements(By.CSS_SELECTOR,'#NewsListContainer li')
print(lis)
可以看到,得到的内容变成了列表类型,列表中的每个节点都是 WebElement 类型。
6. 节点交互
Selenium 可以驱动浏览器来执行一些操作,也就是说可以让浏览器模拟执行一些动作。比较常见的用法有:输入文字时用 send_keys 方法,清空文字时用 clear 方法,点击按钮时用 click 方法。示例如下:
from selenium import webdriver
import time
browser = webdriver.Chrome()
browser.get('https://www.baidu.com')
input = browser.find_element(By.ID,'kw')
input.send_keys('iPhone')
time.sleep(1)
input.clear()
input.send_keys('iPad')
button = browser.find_element(By.ID,'su')
button.click()
通过上面的方法,我们就完成了一些常见节点的动作操作,更多的操作可以参见官方文档的交互动作介绍
:http://selenium-python.readthedocs.io/api.html#module-selenium.webdriver.remote.webelement。
7. 切换 IFrame(一般选不上节点就是这个问题)
我们知道网页中有一种节点叫作 iframe,也就是子 Frame,相当于页面的子页面,它的结构和外部网页的结构完全一致。Selenium 打开页面后,它默认是在父级 Frame 里面操作,而此时如果页面中还有子 Frame,它是不能获取到子 Frame 里面的节点的。这时就需要使用 switch_to.frame() 方法来切换 Frame。示例如下:
browser.get('https://www.douban.com/')
login_iframe=browser.find_element(By.XPATH,'//div[@class="login"]/iframe')
browser.switch_to.frame(login_iframe)
browser.find_element(By.CLASS_NAME,'account-tab-account').click()
browser.find_element(By.ID,'username').send_keys('123123123')
**注意:**对于iframe 网页 一定要切换进去才能够定位、
8. 动作链
在上面的实例中,一些交互动作都是针对某个节点执行的。比如,对于输入框,我们就调用它的输入文字和清空文字方法;对于按钮,就调用它的点击方法。其实,还有另外一些操作,它们没有特定的执行对象,比如鼠标拖曳、键盘按键等,这些动作用另一种方式来执行,那就是动作链。
比如,现在实现一个节点的拖曳操作,将某个节点从一处拖曳到另外一处,可以这样实现:
from selenium import webdriver
from selenium.webdriver import ActionChains
browser = webdriver.Chrome()
url = 'http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable'
browser.get(url)
log = browser.find_element(By.XPATH, '//div[@id="iframewrapper"]/iframe')
browser.switch_to.frame(log)
source = browser.find_element(By.CSS_SELECTOR,'#draggable')
target = browser.find_element(By.CSS_SELECTOR,'#droppable')
actions = ActionChains(browser)
actions.drag_and_drop(source, target)
actions.perform()
drag_and_drop()
方法涉及到参数传递,一个是要拖拽元素的起点,一个是要拖拽元素的终点
首先,打开网页中的一个拖曳实例,然后依次选中要拖曳的节点和拖曳到的目标节点,接着声明 ActionChains 对象并将其赋值为 actions 变量,然后通过调用 actions 变量的 drag_and_drop() 方法,再调用 perform() 方法执行动作,此时就完成了拖曳操作
9. 页面滚动
地址:https://36kr.com/
# 浏览器滚动到底部 10000位置
document.documentElement.scrollTop=10000
# 滚动到顶部
document.documentElement.scrollTop=0
# 移动到页面最底部
browser.execute_script("window.scrollTo(0, document.body.scrollHeight)")
# 移动到指定的坐标(相对当前的坐标移动)
driver.execute_script("window.scrollBy(0, 700)")
# 结合上面的scrollBy语句,相当于移动到700+800=1600像素位置
driver.execute_script("window.scrollBy(0, 800)")
# 移动到窗口绝对位置坐标,如下移动到纵坐标1600像素位置
driver.execute_script("window.scrollTo(0, 1600)")
# 结合上面的scrollTo语句,仍然移动到纵坐标1200像素位置
driver.execute_script("window.scrollTo(0, 1200)")
总结:
对于selenium自动化工具,博主个人感觉是个很有趣的工具,比如:在超星学习通无法直接开倍速,或者调进度条的情况下,就可以选择使用selenium自动化工具,仔细想一想,晚上在睡大觉,selenium在模拟真人刷课也是一件很爽的事,不过读者们还是要更注意用法,学会了就好,不要做坏事哦!