文章目录
什么是selenium
Selenium是一个Web的自动化测试工具,最初是为网站自动化测试而开发的,Selenium 可以直接运行在浏览器上,它支持所有主流的浏览器(包括PhantomJS这些无界面的浏览器),可以接收指令,让浏览器自动加载页面,获取需要的数据,甚至页面截屏等等。
Chromedriver的下载
查看自己的谷歌浏览器版本:
根据自己谷歌浏览器的版本下载相应的浏览器驱动,如果没有的可以尝试选择最接近的版本。
下载地址:https://npm.taobao.org/mirrors/chromedriver
把chromedriver.exe放到与你的python解释器同一路径即可,我这里使用的anaconda的python解释器就和它放一块儿。
一般的python解释器安装路径应该是下面这样的,直接放进去就行了
selenium基本使用
selenium的导包:from selenium import webdriver
selenium创建driver对象:webdriver.Chrome()
selenium请求数据:driver.get(“http://www.baidu.com/”)
selenium查看数据: driver.page_source
关闭浏览器当前页面:driver.close()
关闭浏览器: driver.quit()
import time
from selenium import webdriver # 导包selenium
if __name__ == '__main__':
# 利用python代码来驱动浏览器操作
#1. 创建一个浏览器对象
driver_ = webdriver.Chrome() # 运行可直接调用出谷歌浏览器
# 表面上chromedriver的作用没有体现出来,原因是我们已经把chromedriver跟我们的python解释器放在了同一路径之中
#如果不是同一路径,,就需要手动的去指定chromedriver路径,如下
# driver_ = webdriver.Chrome(executable_path=r'C:/chrome/chromedriver.exe')
time.sleep(3) # 若网络不太稳定可适当增加延时
#2.打开一个空的浏览器后向目标url发送请求只能发送get请求,得到响应数据
driver_.get('https://www.baidu.com/')
#3.拿到他的页面响应数据,浏览器此时此刻已经是处于百度首页状态
data_ = driver_.page_source # 拿到当前页面的响应数据(网页源代码)
print(type(data_)) # <class 'str'>
#获取网页源代码并储存到本地
with open('baidu.html','w',encoding='utf-8') as f:
f.write(data_)
time.sleep(3)
# 想要截取全部
driver_.maximize_window()
# 网页截屏 此时此刻是存在于百度首页 默认是只截屏一部分
driver_.save_screenshot('baidu_.png')
# 如果不手动关闭浏览器,会占用内存
# 有两种方式关闭
# 第一个是关闭当前页面,
driver_.close()
# 第二个是关闭浏览器
time.sleep(3)
driver_.quit()
无头模式的设置
肉眼去看到浏览器的打开 关闭 执行 等操作会降低我们的效率,而屏蔽掉浏览器的肉眼所见的打开,关闭这些操作可设置成无界面模式 “无头模式”,可以提高一丢丢效率…
使用示例:
import time
from selenium import webdriver
# 设置"无头模式"
from selenium.webdriver.chrome.options import Options
if __name__ == '__main__':
# 实例化 创建一个新的的对象 option对象
option_ = Options()
# 添加参数设置'无头模式',
option_.add_argument('--headless')
"""
第二种:option_.set_headless()
第三种:option_.headless = True
"""
driver_ = webdriver.Chrome(options=option_) # 1. 创建浏览器对象,打开对应浏览器
driver_.get('https://www.baidu.com/') # 2.get向url输入框输入网址
data_ = driver_.page_source # 3. 此时此刻
print(type(data_))
time.sleep(1)
driver_.close() # 关闭浏览器页面
time.sleep(1)
driver_.quit() # 关闭浏览器
selenium元素定位的方法
定位元素语法:
find_element_by_id (返回一个元素)
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_element和find_elements的区别 by_link_text和by_partial_link_tex的区别:全部文本和包含某个文本。
这几种定位元素方法没必要都掌握,掌握一两种即可,能达到定位目的就行
百度搜索小案例
1.定位百度输入框
2.定位百度按钮
3.编写代码
import time
from selenium import webdriver
if __name__ == '__main__':
# 1.创建浏览器对象,效果:打开一个对应的浏览器
driver_ = webdriver.Chrome()
time.sleep(2)
# 2.要url输入框输入一个url 效果:进入到百度首页
driver_.get('https://www.baidu.com/')
time.sleep(2)
# 3.在(1)搜索框输入关键字 (2)进行搜索
# (1) 找到输入框
input_obj = driver_.find_element_by_id('kw') # 会返回一个对象
# (2) 输入数据 效果就是往输入框对象发送数据
input_obj.send_keys('美女')
# (3) 进行搜索 达到指定页面
bai_du = driver_.find_element_by_xpath('//*[@id="su"]') # class类容易出现多个,没有id的情况下,,推荐使用xpath
# (4) 点击触发
bai_du.click()
# 此时此刻 浏览器对象是处于 搜索页面
# data_ = driver_.page_source
# print(data_)
# 得到当前时刻的cookie
cookie_ = driver_.get_cookies()
print(cookie_)
# 当前页面的url url地址栏里面的
url_ = driver_.current_url
print(url_)
time.sleep(5)
driver_.quit() # 关闭浏览器
效果:
百度搜索进入豆瓣电影官网小案例
import time
from selenium import webdriver
if __name__ == '__main__':
# 1.创建浏览器对象,效果:打开一个对应的浏览器
driver_ = webdriver.Chrome()
time.sleep(2)
# 2.要url输入框输入一个url 效果:进入到百度首页
driver_.get('https://www.baidu.com/')
time.sleep(2)
# 3.在(1)搜索框输入关键字 (2)进行搜索
# (1) 找到输入框
input_obj = driver_.find_element_by_id('kw') # 会返回一个对象
# (2) 输入数据 效果就是往输入框对象发送数据
input_obj.send_keys('豆瓣电影')
# (3) 进行搜索 达到指定页面 bg s_btn_wr
bai_du = driver_.find_element_by_xpath('//*[@id="form"]/span[2]') # class类容易出现多个,,没有id的情况下,,推荐使用xpath
# (4) 点击触发,,,,
bai_du.click()
time.sleep(2)
#进入豆瓣电影官方网站的两种方式
# 1.找到豆瓣电影官方的节点
# douban_ = driver_.find_element_by_xpath('//*[@id="1"]/h3/a[1]')
# douban_.click()
# time.sleep(2)
# 2.找到他的href url连接的属性值
douban_ = driver_.find_element_by_xpath('//*[@id="1"]/h3/a[1]')
url_ = douban_.get_attribute('href') # 得到当前节点对象的属性值
driver_.get(url_)
time.sleep(5)
driver_.quit() # 关闭浏览器
可能就有人问了,直接get目标网址不省事儿吗?这里说明一下这只是演示元素定位操作,具体看你怎么玩了,你也可以直接get目标网址然后在目标网站根据自己的需求进行定位操作提取数据。
异步加载问题解决之页面等待
有一些网站页面会采用异步加载AJAX技术,鼠标往下滚动才会触发下面的内容(就像个人微博动态一样往下翻会显示正在加载中等然后等一会儿就会显示下面的内容),这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。传统的网页(不使用 AJAX)如果需要更新内容,必需重载整个网页面。使用 AJAX 的应用程序案例:新浪微博、Google 地图、开心网等等。
那么问题就来了,动态数据需要异步加载,而加载出来就需要时间,那如果数据还没有加载出来的时候,你就去定位元素,就会出现定位不到类似的错误…
即如果网站采用了动态html技术,那么页面上的部分元素出现时间便不能确定,这个时候就可以设置一个等待时间,强制要求在时间内出现,否则报错。
使用time.sleep()把时间调大一些当然可以解决 ,但容易造成时间上的浪费,这里简单介绍两种等待方式:
显式等待
显式的waits等待一个确定的条件触发然后才进行更深一步的执行。 这里提供一些便利的方法让你编写的代码只等待需要的时间,WebDriverWait结合ExpectedCondition是一种实现的方法。
代码示例:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# 显式等待的办法
driver = webdriver.Chrome()
driver.get("http://somedomain/url_that_delay_loading")
try:
element = WebDriverWait(driver,10).until(
EC.presence_of_element_located((By.ID,"myDynamicElement"))
)
finally:
driver.quit()
这段代码会等待10秒,如果10秒内找到元素则立即返回,否则会抛出TimeoutException异常,WebDriverWait默认每500毫秒调用一下ExpectedCondition直到它返回成功为止。ExpectedCondition类型是布尔的,成功的返回值就是true,其他类型的ExpectedCondition成功的返回值就是 not null
类似retrying的隐式等待
当我们要找一个或者一些不能立即可用的元素的时候,隐式waits会告诉WebDriver轮询DOM指定的次数,默认设置是0次。一旦设定,WebDriver对象实例的整个生命周期的隐式调用也就设定好了。
代码示例:
from selenium import webdriver
driver = webdriver.Chrome()
driver.implicitly_wait(10) # 十秒之内 固定频率轮询访问,不停的访问
driver.get("http://somedomain/url_that_delays_loading")
myDynamicElement = driver.find_element_by_id('myDynamicElement')
两个代码示例都做同样的事情。找到某个元素,如果10秒后找不到,则放弃。隐式等待只能做到这一点。它只能尝试找到具有超时的元素。显式等待的优势在于它可以等待各种条件,还可以自定义超时并忽略某些异常。
显示waits: 明确的行为表现 ,在本地的selenium运行(你选择的编程语言) 可以在任何你能想到的条件下工作 返回成功或者超时 可以定义元素的缺失为条件 可以定制重试间隔,可以忽略某些异常。
隐式waits: 不明确的行为表现,同一个问题依赖于不同的操作系统,不同的浏览器,不同的selenium版本会有各种不同的表现 。在远程的selenium上运行(控制浏览器的那部分). 只能在寻找元素的函数上工作 返回找到元素或者(在超时以后)没有找到 如果检查元素缺失那么总是会等待到超时 除了时间啥都不能指定。
其他方法
selenium 处理cookie
通过driver.get_cookies()能够获取所有的cookie:
# 把cookie转化为字典
{cookie[‘name’]: cookie[‘value’] for cookie in driver.get_cookies()}
#删除一条cookie
driver.delete_cookie("CookieName")
# 删除所有的cookie
driver.delete_all_cookies()
switch方法切换的操作
一个浏览器肯定会有很多窗口,所以我们肯定要有方法来实现窗口的切换。可以使用 window_handles 方法来获取每个窗口的操作对象。例如:
# 1. 获取当前所有的窗口
current_windows = driver.window_handles
# 2. 根据窗口索引进行切换
driver.switch_to.window(current_windows[1])
iframe问题
iframe是html中常用的一种技术,即一个页面中嵌套了另一个网页,selenium默认是访问不了frame中的内容的,对应的解决思路是:
driver.switch_to.frame()
动手:模拟登陆qq邮箱
在使用selenium登录qq邮箱的过程中,我们会发现,无法在邮箱的登录input标签中输入内容,通过观察源码可以发现,form表单在一个frame中,所以需要切换到frame中。
处理弹窗提示
当你触发了某个事件之后,页面出现了弹窗提示,处理这个提示或者获取提示信息方法如下:
alert = driver.switch_to_alert()
页面的前进和后退
driver.forward() #前进
driver.back() # 后退
小结selenium的优缺点
selenium能够执行页面上的js,对于js渲染的数据和模拟登陆处理起来非常容易。
selenium由于在获取页面的过程中会发送很多请求,所以效率非常低,所以在很多时候需要酌情使用。
感谢各位小伙伴的阅读,如有任何问题可在评论区留言或者csdn app发私信给我,看到了一定知无不言言无不尽。后面会讲一些selenium的案例,敬请期待。。。
最后送出一些福利,感兴趣的自取:C++及Python人工智能500G+学习资源