selenium
一、原理与安装
1.1原理
Selenium 是一个 Web 应用的自动化框架。
通过它,我们可以写出自动化程序,像人一样在浏览器里操作web界面。 比如点击界面按钮,在文本框
中输入文字 等操作。(相当于真正的浏览)
而且还能从web界面获取信息。 比如获取12306票务信息,招聘网站职位信息,财经网站股票价格信息
等等,然后用程序进行分析处理。
selenium 自动化流程如下:
- 自动化程序调用Selenium 客户端库函数(比如点击按钮元素)
- 客户端库会发送Selenium 命令 给浏览器的驱动程序
- 浏览器驱动程序接收到命令后 ,驱动浏览器去执行命令
- 浏览器执行命令
- 浏览器驱动程序获取命令执行的结果,返回给我们自动化程序
- 自动化程序对返回结果进行处理
1.2安装
打开命令行程序,运行如下命令
pip install selenium
安装浏览器驱动
注意浏览器版本号一致
浏览器驱动 是和 浏览器对应的。 不同的浏览器 需要选择不同的浏览器驱动。
目前主流的浏览器中,谷歌 Chrome 浏览器对 Selenium自动化的支持更加成熟一些。强烈推荐大家使
用 Chrome浏览器。
pip install seleniumhttps://www.google.cn/chrome/
在浏览器上面输入:chrome://version/ 命令 查看自己下载的浏览器的版本
确保Chrome浏览器安装好以后,请大家打开下面的连接,访问Chrome 浏览器的驱动下载页面
https://chromedriver.storage.googleapis.com/index.html
注意浏览器驱动 必须要和浏览器版本匹配,版本号 就是和浏览器版本号对应的
安装时直接解压到python环境变量里面
1.3简单示例
下面的代码, 可以自动化的 打开edge浏览器,并且自动化打开百度网站,可以大家可以运行一下看
看。
from selenium import webdriver
# 创建 WebDriver 对象,指明使用edge浏览器驱动,r后面相当于上面的driver的解压地址,安装在python环境变量中就填空就行
wd = webdriver.Edge(r'd:\webdrivers\edgedriver.exe')
# 调用WebDriver 对象的get方法 可以让浏览器打开指定网址
wd.get('https://www.baidu.com')
二、选择元素的方法
对于百度搜索页面,如果我们想自动化输入 白月黑羽 ,怎么做呢?
这就是在网页中,操控界面元素。
web界面自动化,要操控元素,首先需要 选择 界面元素 ,或者说 定位 界面元素
就是 先告诉浏览器,你要操作 哪个 界面元素, 让它找到你要操作的界面元素。
我们必须要让浏览器 先找到元素,然后,才能操作元素。
2.1选择元素的方法
对应web自动化来说,就是要告诉浏览器,你要操作的界面元素是什么。
那么,怎么告诉浏览器呢?
方法就是:告诉浏览器,你要操作的这个 web 元素的特征。
就是告诉浏览器,这个元素它有什么与众不同的地方,可以让浏览器一下子找到它。
元素的特征怎么查看?
可以使用浏览器的开发者工具栏帮我们查看、选择 web 元素。
请大家用chrome浏览器访问百度,按F12后,点击下图箭头处的Elements标签,即可查看页面对应的
HTML 元素
对应web自动化来说,就是要告诉浏览器,你要操作的界面元素是什么。
那么,怎么告诉浏览器呢?
方法就是:告诉浏览器,你要操作的这个 web 元素的特征。
就是告诉浏览器,这个元素它有什么与众不同的地方,可以让浏览器一下子找到它。
元素的特征怎么查看?
可以使用浏览器的开发者工具栏帮我们查看、选择 web 元素。
请大家用chrome浏览器访问百度,按F12后,点击下图箭头处的Elements标签,即可查看页面对应的
HTML 元素
然后在点击左边的图标如图:
2.1.1根据元素的id属性选择元素
大家仔细看上面的 input元素内容,会发现它有一个属性叫id
我们可以把 id 想象成元素的编号,是用来在html中标记该元素的。根据规范,如果元素有id属性,这
个id 必须是当前html中唯一的。
所以如果元素有id,根据id选择元素是最简单高效的方式。
这里,百度搜索框元素的 id值为 kw
下面的代码,可以自动化在浏览器中访问百度,并且在输入框中搜索杨幂。
大家可以运行一下看看。
fromseleniumimportwebdriver
fromselenium.webdriver.common.byimportBy
#创建WebDriver对象,指明使用chrome浏览器驱动
wd=webdriver.Chrome(r'd:\webdrivers\chromedriver.exe')#调用WebDriver对象的get方法可以让浏览器打开指定网址
wd.get('https://www.baidu.com')
#根据id选择元素,返回的就是该元素对应的WebElement对象
element=wd.find_element(By.ID,'kw')
#通过该WebElement对象,就可以对页面元素进行操作了
#比如输入字符串到这个输入框里
element.send_keys('杨幂\n')
这行代码运行是,就会发起一个请求通过浏览器驱动转发给浏览器,告诉它,需要选择一个id为 kw 的
元素。
浏览器,找到id为kw的元素后,将结果通过浏览器驱动返回给自动化程序,所以 find_element 方法
会返回一个WebElement****类型的对象。
这个WebElement 对象可以看成是对应页面元素的遥控器。
我们通过这个WebElement对象,就可以操控对应的界面元素。
比如:
调用这个对象的 send_keys 方法就可以在对应的元素中输入字符串,
调用这个对象的 click 方法就可以点击该元素。
fromselenium.webdriver.common.byimportBy
#初始化代码....
wd.find_element(By.ID,'username').send_keys('byhy')
wd.find_element(By.CLASS_NAME,'password').send_keys('sdfsdf')wd.find_element(By.TAG_NAME,'input').send_keys('sdfsdf')
wd.find_element(By.CSS_SELECTOR,'button[type=submit]').click()
2.1.2 根据class属性、tag名选择元素
2.1.2.1根据class属性选择元素
web自动化的难点和重点之一,就是如何选择我们想要操作的web页面元素。
有网址html如下:
<body>
<divclass="plant"><span>土豆</span></div>
<divclass="plant"><span>洋葱</span></div>
<divclass="plant"><span>白菜</span></div>
<divclass="animal"><span>狮子</span></div>
<divclass="animal"><span>老虎</span></div>
<divclass="animal"><span>山羊</span></div>
</body>
所有的植物元素都有个class属性值为 plant。
所有的动物元素都有个class属性值为 animal。
如果我们要选择所有的动物,就像下面可以这样写,
wd.find_elements(By.CLASS_NAME,'animal')
注意element后面多了个s
注意
find_elements 返回的是找到的符合条件的所有元素 (这里有3个元素),放在一个列表中返回。
如果没有s则只返回第一个元素
2.1.2.2 根据tag名选择元素
类似的,可以通过指定的 参数By.TAG_NAME,选择所有的tag名为div的元素:
fromseleniumimportwebdriver
fromselenium.webdriver.common.byimportBy
wd=webdriver.Chrome(r'd:\webdrivers\chromedriver.exe')
wd.get('http://cdn1.python3.vip/files/selenium/sample1.html')#根据tagname选择元素,返回的是一个列表
#里面都是tag名为div的元素对应的WebElement对象
elements=wd.find_elements(By.TAG_NAME,'div')
#取出列表中的每个WebElement对象,打印出其text属性的值
#text属性就是该WebElement对象对应的元素在网页中的文本内容
for element in elements:
print(element.text)
注意:
find_element 和 find_elements 的区别
2.2 等待界面元素出现
在我们进行网页操作的时候,有的元素内容不是可以立即出现的,可能会等待一段时间。
比如百度搜索一个词语,我们点击搜索后,浏览器需要把这个搜索请求发送给百度服务器,百度服务
器进行处理后,把搜索结果返回给我们。
所以,从点击搜索到得到结果,需要一定的时间,因为我们的代码执行的速度比百度服务器响应的速度快。
百度还没有来得及返回搜索结果,我们就执行了如下代码:
from seleniumimportwebdriver
from selenium.webdriver.common.import By
from selenium.webdriver import ChromeOptions
#跳过百度的安全验证
#可以通过隐藏WebDriver提示条和自动化扩展信息来跳过验证。
option=ChromeOptions()
option.add_experimental_option('excludeSwitches',['enable-automation'])
option.add_experimental_option('useAutomationExtension',False)
wd=webdriver.Chrome(options=option)
wd.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument",
{'source':'Object.defineProperty(navigator,"webdriver",{get:()=>undefind})'})
wd.get('https://www.baidu.com')
element=wd.find_element(By.ID,'kw')
element.send_keys('杨幂\n')
import time
time.sleep(2)
elements=wd.find_elements(By.ID,'1')
print(elements[0].text)
Selenium 的 Webdriver 对象有个方法叫implicityly_wait
该方法接受一个参数,用来指定最大等待时长。
from seleniumimportwebdriver
from selenium.webdriver.common.import By
from selenium.webdriver import ChromeOptions
#跳过百度的安全验证
#可以通过隐藏WebDriver提示条和自动化扩展信息来跳过验证。
option=ChromeOptions()
option.add_experimental_option('excludeSwitches',['enable-automation'])
option.add_experimental_option('useAutomationExtension',False)
wd=webdriver.Chrome(options=option)
wd.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument",
{'source':'Object.defineProperty(navigator,"webdriver",{get:()=>undefind})'})
#设置最大等待时长为10秒
wd.implicitly_wait(10)
wd.get('https://www.baidu.com')
element=wd.find_element(By.ID,'kw')
element.send_keys('杨幂\n')
elements=wd.find_elements(By.ID,'1')
print(elements[0].text)
三、操控元素的基本方法
选择到元素之后,我们的代码会返回元素对应的 WebElement对象,通过这个对象,我们就可以操控
元素了。
操控元素通常包括:
1.点击元素
2.在元素中输入字符串,通常是对输入框这样的元素
3.获取元素包含的信息,比如文本内容,元素的属性
3.1 点击元素
点击元素非常简单,就是调用元素WebElement对象的 click方法。前面我们已经学过。
这里我们要补充讲解一点。
当我们调用 WebElement 对象的 click 方法去点击元素的时候,浏览器接收到自动化命令,点击的是该
元素的中心点位置。
from seleniumimportwebdriver
from selenium.webdriver.common.import By
from selenium.webdriver import ChromeOptions
#跳过百度的安全验证
#可以通过隐藏WebDriver提示条和自动化扩展信息来跳过验证。
option=ChromeOptions()
option.add_experimental_option('excludeSwitches',['enable-automation'])
option.add_experimental_option('useAutomationExtension',False)
wd=webdriver.Chrome(options=option)
wd.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument",
{'source':'Object.defineProperty(navigator,"webdriver",{get:()=>undefind})'})
#设置最大等待时长为10秒
wd.implicitly_wait(10)
wd.get('https://www.baidu.com')
element=wd.find_element(By.ID,'kw')
element.send_keys('杨幂\n')
wd.find_element(By.ID,'su').click()
# 现在搜索结果在百度页面上
elements=wd.find_elements(By.ID,'1')
print(elements[0].text)
3.2 输入框
输入字符串也非常简单,就是调用元素WebElement对象的send_keys方法。前面我们也已经学过。
如果我们要把输入框中已经有的内容清除掉,可以使用WebElement对象的clear方法
并且按F12,观察HTML的内容,我们要写一个自动化程序:要求在输入框中填入:杨幂,而且要做到输入框中已经有的提示字符,需要先清除掉
代码应该如下
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
wd = webdriver.Edge()
wd.get('https://www.baidu.com/')
element = wd.find_element(By.ID, 'kw')
element.clear() # 清除输入框已有的字符串
element.send_keys('杨幂')
time.sleep(100)
3.3 获取元素信息
3.3.1 获取元素的文本内容
通过WebElement对象的text属性,可以获取元素展示界面上的文本内容
比如百度:
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
wd = webdriver.Edge()
wd.get('https://www.baidu.com/')
element = wd.find_element(By.CLASS_NAME, 'title-content-title')
print(element.text)
time.sleep(100)
3.3.2 获取元素属性
通过WebElement对象的get_attribute方法来获取元素的属性值,比如药获取元素属性class的值,就可以使用**element.get_attribute(‘class’)**如下:
fromseleniumimportwebdriver
fromselenium.webdriver.common.byimportBy
fromselenium.webdriverimportChromeOptions
import time
wd=webdriver.Chrome()
wd.get('http://www.baidu.com')
element=wd.find_element(By.ID,'kw')
element.send_keys('杨幂')
wd.find_element_by_id('su').click()
time.sleep(1)
#现在搜索结果在百度页面上
element=wd.find_element(By.ID,'1')
print(element.get_attribute('srcid'))
注意:执行完自动化代码,如果想关闭浏览器窗口可以调用WebDriver对象的 quit 方法,像这样 wd.quit()
3.3.3 获取整个元素对应的HTML
要获取整个元素对应的HTML文本内容,可以使用element.get_attribute(‘outerHTML’)
如果,只是想获取某个元素内部的HTML文本内容,可以使用element.get_attribute(‘innerHTML’)
fromseleniumimportwebdriver
fromselenium.webdriver.common.byimportBy
fromselenium.webdriverimportChromeOptions importtime
wd=webdriver.Chrome()
wd.get('http://www.baidu.com')
element=wd.find_element(By.ID,'kw')
element.send_keys('杨幂')
wd.find_element_by_id('su').click()
time.sleep(1)
#现在搜索结果在百度页面上
element=wd.find_element(By.ID,'1')
print(element.get_attribute('outerHTML'))
##
fromseleniumimportwebdriver
fromselenium.webdriver.common.byimportBy
fromselenium.webdriverimportChromeOptions importtime
wd=webdriver.Chrome()
wd.get('http://www.baidu.com')
element=wd.find_element(By.ID,'kw')
element.send_keys('杨幂')
wd.find_element_by_id('su').click()
time.sleep(1)
#现在搜索结果在百度页面上
element=wd.find_element(By.ID,'1')
print(element.get_attribute('innerHTML'))
注意:两个代码的区别在于:outerHTML是整个需要分析的地方的HTML,而innerHTML是分析地方的里面的
代码,是div标签里面的HTML,不包含div本身的HTML。
3.3.4 获取输入框里面的文字
对于input输入框的元素,要获取里面的输入文本,用text属性是不行的,这时可以使用
element.get_attribute(‘value’)
例如:
from seleniumimportwebdriver
from selenium.webdriver.common.byimportBy
from selenium.webdriverimportChromeOptions
#跳过百度的安全验证
#可以通过隐藏WebDriver提示条和自动化扩展信息来跳过验证。
option=ChromeOptions()
option.add_experimental_option('excludeSwitches',['enable-automation'])
option.add_experimental_option('useAutomationExtension',False)
wd=webdriver.Chrome(options=option)
wd.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument",
{'source':'Object.defineProperty(navigator,"webdriver",{get:()=>undefind})'})
#设置最大等待时长为10秒wd.implicitly_wait(10)
wd.get('https://www.baidu.com')
element=wd.find_element(By.ID,'kw')element.send_keys('杨幂')
wd.find_element_by_id('su').click()
print(element.get_attribute("value"))
3.3.5 获取元素文本内容2
通过WebElement对象的text属性,可以获取元素展示在界面上的文本内容。
但是,有时候,元素的文本内容没有展示在界面上,或者没有完全完全展示在界面上。这时,用WebElement对象的text属性,获取文本内容,就会有问题。
出现这种情况,可以尝试使用element.get_attribute(‘innerText’),或者element.get_attribute(‘textContent’)
Property(navigator,“webdriver”,{get:()=>undefind})'})
#设置最大等待时长为10秒wd.implicitly_wait(10)
wd.get(‘https://www.baidu.com’)
element=wd.find_element(By.ID,‘kw’)element.send_keys(‘杨幂’)
wd.find_element_by_id(‘su’).click()
print(element.get_attribute(“value”))
##### 3.3.5 获取元素文本内容2
通过WebElement对象的text属性,可以获取元素展示在界面上的文本内容。
但是,有时候,元素的文本内容没有展示在界面上,或者没有完全完全展示在界面上。这时,用WebElement对象的text属性,获取文本内容,就会有问题。
出现这种情况,可以尝试使用**element.get_attribute('innerText')**,或者**element.get_attribute('textContent')**
版权归原作者 sheep55 所有, 如有侵权,请联系我们删除。