1.Selenium库的介绍:
Selenium库是用来自动化测试的工具,支持多种浏览器,爬虫中主要用来解决JavaScript渲染的问题。给浏览器发送指令,使得浏览器做出跳转,点击,下拉等动作,模拟用户(人)自然的访问网页。当我们写爬虫获取网页的时候,如果使用urllib库,Requests库无法获取信息的时候,就使用JavaScript库来解决。
2.安装Selenium库:
使用下面的命令的前提是已经安装了anaconda,并且配置好了环境变量,还需要下载浏览器驱动程序。
使用cmd命令:pip install selenium
3.Selenium库的使用详解:
基本使用
# webdriver是浏览器驱动模块
from selenium import webdriver
from selenium.webdriver.common.by import By
# 虚拟按键
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
# 构造一个浏览器对象,webdriver.浏览器名()
browser = webdriver.Chrome()
try:
# 使用浏览器对象访问指定url
browser.get('https://www.baidu.com')
# 通过id=‘kw’找到元素并赋值为一个变量代表这个元素
input = browser.find_element_by_id('kw')
# 模拟向变量(即元素,关键字输入框)输入字符串'python'
input.send_keys('Python')
# 模拟向输入框中输入回车
input.send_keys(Keys.ENTER)
# 设置一个等待对象,设置等待时长
wait = WebDriverWait(browser,10)
# 等待一个元素被加载出来,这个元素使用located通过id=content_left确定,
# 此处可能产生异常,所以用try
wait.until(EC.presence_of_element_located((By.ID,'content_left')))
# 获取当前访问后的url
print(browser.current_url)
# 获取cookies
print(browser.get_cookies)
# 获取源码
print(browser.page_source)
finally:
browser.close()
# 导入包
from selenium import webdriver
# 构造各种不同的浏览器对象
browser = webdriver.Chrome()
# 火狐浏览器
browser = webdriver.Firfox()
# 微软的Edge浏览器
browser = webdriver.Edge()
# 苹果的Safar()浏览器
browser = webdriver.Safari()
5.访问页面:
from selenium import webdriver
# 访问页面
browser = webdriver.Chrome()
browser.get('https://www.taobao.com')
print(browser.page_source)
browser.close()
6.查找元素:
查找单个元素,获取一个输入框或者一个按钮
from selenium import webdriver
# 获取浏览器对象
browser = webdriver.Chrome()
browser.get('https://www.taobao.com')
# 通过标准选择器查找
input_first = browser.find_element_by_id('q')
# 通过CSS选择器查找 id=q
input_second = browser.find_element_by_css_selector('#q')
# 通过xpath选择器
input_third = browser.find_element_by_xpath('//*[@id="q"]')
print(input_first, input_second, input_third)
browser.close()
其他的查找方式
find_element_by_name
find_element_by_xpath
find_element_by_link_text
find_element_by_partial_link_text
find_element_by_tag_name
find_element_by_class_name
find_element_by_css_selector
# 使用通用的方法find_element(查找类型,类型的值)来查找
from selenium import webdriver
from selenium.webdriver.common.by import By
# 获取浏览器对象
browser = webdriver.Chrome()
browser.get('https://www.taobao.com')
input_first=browser.find_element(By.ID,'q')
print(input_first)
browser.close()
7.查找多个元素:
from selenium import webdriver
browser=webdriver.Chrome()
browser.get('https://www.taobao.com')
# 使用find_elements_by_css_selector查找符合css选择器 条件的所有'.service-bd li'
lis = browser.find_elements_by_css_selector('.service-bd li')
print(input_first)
browser.close()
from selenium import webdriver
from selenium.webdriver.common.by import By
browser = webdriver.Chrome()
browser.get('https://taobao.com')
lis = browser.find_elements(By.CSS_SELECTOR,'.service-bd li')
print(lis)
browser.close()
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
8.元素交互操作:对获取的元素调用交互方法
from selenium import webdriver
import time
# 获取浏览器对象
browser = webdriver.Chrome()
browser.get('https://www.taobao.com')
# 定位输入框元素
input = browser.find_element_by_id('q')
# 在输入框元素中输入文本
input.send_keys('iPhone')
# 暂停一下
time.sleep(1)
# 情况输入框内容
input.clear()
# 向输入框输入内容
input.send_keys('iPad')
# 定位搜索按钮
button = browser.find_element_by_class_name('btn-search')
# 模拟点击
button.click()
更多操作:http://selenium-python.readthedocs.io/api.html#module-selenium.webdriver.remote.webelement
9.交互动作
将动作附加到动作链中串行执行
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)
# 切换到frame=iframeResult框架内
browser.switch_to.frame('iframeResult')
# 在框架内定位到要拖拽的目标元素
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()
更多操作:http://selenium-python.readthedocs.io/api.html#moudule-selenium.webdriver.common.action_chains
10.执行JavaSript
在做一些元素交互动作的时候,可能没有提供API,那么将动作用js实现,然后使用excute_sript方法执行js代码,完成交互动作。
from selenium import webdriver
browser = webdriver.Chrome()
# 访问url
browser.get('https://www.zhihu.com/explore')
# 执行js脚本,滚动条下拉
browser.execute_script('window.scrollTo(0,document.body.scrollHeight)')
# 执行js脚本,弹出弹框,弹框文本为"To Botton"
browser.execute_script('alert("To Botton")')
获取属性,在使用了find_element_by_id方法后获取到元素后还需要获取到元素中的属性
在使用get_attrbute(‘属性值’)获取属性
from selenium import webdriver
from selenium.webdriver import ActionChains
browser = webdriver.Chrome()
url = 'https://www.zhihu.com/explore'
browser.get(url)
# 获取到id='zh-top-link-togo'的元素
logo = browser.find_element_by_id('zh-top-link-logo')
print(logo)
print(logo.get_attribute('class'))
获取文本
from selenium import webdriver
browser = webdriver.Chrome()
url = 'https://www.zhihu.com/explore'
browser.get(url)
# 获取指定元素
input = browser.find_element_by_class_name('zh-top-add-question')
print(input.text)
获取ID、位置、标签名、大小
from selenium import webdriver
browser = webdriver.Chrome()
url = 'https://www.zhihu.com/explore'
browser.get(url)
# 获取指定元素
input = browser.find_element_by_class_name('Entry-body')
print(input.id)
print(input.location)
print(input.tag_name)
print(input.size)
b9f26ba9-1484-4e7c-9574-ae9cee0d1314
{'x': 0, 'y': 0}
body
{'height': 3533, 'width': 1019}
12.Frame
Frame 相当于一个独立的网页,可以嵌套,找找到Frame中的元素先要切换到对应的Frame中
才能找到对应的元素
import time
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
# 获取都浏览器对象
browser = webdriver.Chrome()
url = 'http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable'
browser.get(url)
# 切换到指定的Frame
browser.switch_to.frame('google_esf')
# 通过CSS选择器选中元素
source = browser.find_element_by_css_selector('#draggable')
print(source)
try:
# 找到指定的元素
logo = broser.find_element_by_class_name('logo')
except NoSuchElementException:
print('NO LOGO')
# 找不到子Frame的元素,切换到父级Frame
browser.switch_to.parent_frame()
# 找到指定的logo标签
logo = browser.find_element_by_class_name('logo')
print(logo)
print(logo.text)
13.等待
网页中有很多ajax请求,当访问网页的时候,有一些元素的ajax请求没有立即的获取到响应数据,
我们可以设置一个等待时间,在等待一段时间后再获取数据。
隐式等待
当使用了隐式等待执行测试的时候,如果WebDriver没有在DOM中找到元素,将继续等待,超出设定的时间后则抛出异常。也就是说,当查找元素并没有立即出现的时候,隐式等待将等待设置好的时间后再在DOM中查找指定的元素,没有找到抛出元素未找到异常,默认的等待时间是0.网速没问题的时候可以不使用。
from selenium import webdriver
# 构造浏览器对象
browser = webdriver.Chrome()
# 设置隐式等待
browser.implicitly_wait(10)
# 访问url
browser.get('https://www.zhihu.com/explore')
# 获取指定元素
input = browser.find_element_by_class_name('Entry-body')
print(input)
显示等待
设置一个最长等待时间和等待条件,如果首次没有获取到元素数据,那么再规定的时间内判断等待条件,如果条件满足就返回,超过时间就抛出异常
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
# 获取浏览器对象
browser = webdriver.Chrome()
browser.get('https://www.taobao.com/')
# 获取一个等待对象
wait = WebDriverWait(browser,10)
# 显式的设置等待条件,知道元素id=q的元素被加载
input = wait.until(EC.presence_of_element_located((By.ID,'q')))
# 设置等待条件
button = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,'.btn-search')))
# 打印出等待的元素内容
print(input,button)
其他的元素条件判断
title_is 标题是某内容
title_contains 标题包含某内容
presence_of_element_located 指定的元素加载出(传入定位元组,如(By.ID,‘p’))
visibility_of_element_located 元素可见,传入定位元组
visibility_of 可见,传入元素对象
presence_of_all_elements_located 所有元素加载出
text_to_present_in_element 某个元素中包含某文字
text_to_be_present_in_element 某个元素值包含某文件
frame_to_be_aviliable_and_switch_to_it frame加载并切换
invisibility_of_element_located 元素不可见
element_to_be_clickable 元素可以点击
staleness_of 判断一个元素是否仍然在DOM,可以判断页面是否已经刷新
element_to_be_selecte 元素可选择,传入元素对象
element_located_to_be_selected 元素可以选择,传入定位元组
element_selection_state_to_be 传入元素对象以及状态,相等返回True,否则返回False
element_located_selection_state_to_be 判断指定元组的元素的状态,相等返回True,否则返回FALSE
alert_is_present 是否出现Alert
详细内容:http://selenium-python.readthedocs.io/api.html#module-selenium.webdriver.surpport.expected_conditions
14.前进和后退
import time
from selenium import webdriver
browser = webdriver.Chrome()
browser.get('https://www.baidu.com/')
browser.get('https://www.taobao.com/')
browser.get('https://www.python.org')
# 后退,返回上一个返回的地址
browser.back()
# 睡眠1s
# 前进,向下一个网址访问
browser.forward()
# 关闭浏览器
browser.close()
from selenium import webdriver
browser = webdriver.Chrome()
browser.get('https://www.zhihu.com/explore')
# 获取cookie
print(browser.get_cookies())
# 加入cookie
browser.add_cookie({'name':'name','domain':'www.zhihu.com','value':'germey'})
# 获取cookies
print(browser.get_cookies())
# 删除cookies
browser.delete_all_cookies()
# 获取cookies
print(browser.get_cookies())
[{'domain': 'zhihu.com', 'httpOnly': False, 'name': 'Hm_lpvt_98beee57fd2ef70ccdd5ca52b9740c49', 'path': '/', 'secure': False, 'value': '1573480387'}, {'domain': 'zhihu.com', 'expiry': 1605016386, 'httpOnly': False, 'name': 'Hm_lvt_98beee57fd2ef70ccdd5ca52b9740c49', 'path': '/', 'secure': False, 'value': '1573480387'}, {'domain': 'www.zhihu.com', 'expiry': 1573481285.453171, 'httpOnly': False, 'name': 'tgw_l7_route', 'path': '/', 'secure': False, 'value': '80f350dcd7c650b07bd7b485fcab5bf7'}, {'domain': 'zhihu.com', 'expiry': 1668088385.453318, 'httpOnly': False, 'name': 'd_c0', 'path': '/', 'secure': False, 'value': '"ACAuYP7CVhCPTklkCj94f8w0j5_BAciF3Q0=|1573480385"'}, {'domain': 'zhihu.com', 'httpOnly': False, 'name': '_xsrf', 'path': '/', 'secure': False, 'value': '8a2f9223-fa7f-4c3d-9d1a-3d05e6c11543'}, {'domain': 'zhihu.com', 'expiry': 1636552385.453258, 'httpOnly': False, 'name': '_zap', 'path': '/', 'secure': False, 'value': 'e2f199bf-c180-409b-a9f4-572632edf328'}]
[{'domain': 'www.zhihu.com', 'httpOnly': False, 'name': 'name', 'path': '/', 'secure': True, 'value': 'germey'}, {'domain': 'zhihu.com', 'httpOnly': False, 'name': 'Hm_lpvt_98beee57fd2ef70ccdd5ca52b9740c49', 'path': '/', 'secure': False, 'value': '1573480387'}, {'domain': 'zhihu.com', 'expiry': 1605016386, 'httpOnly': False, 'name': 'Hm_lvt_98beee57fd2ef70ccdd5ca52b9740c49', 'path': '/', 'secure': False, 'value': '1573480387'}, {'domain': 'www.zhihu.com', 'expiry': 1573481285.453171, 'httpOnly': False, 'name': 'tgw_l7_route', 'path': '/', 'secure': False, 'value': '80f350dcd7c650b07bd7b485fcab5bf7'}, {'domain': 'zhihu.com', 'expiry': 1668088385.453318, 'httpOnly': False, 'name': 'd_c0', 'path': '/', 'secure': False, 'value': '"ACAuYP7CVhCPTklkCj94f8w0j5_BAciF3Q0=|1573480385"'}, {'domain': 'zhihu.com', 'httpOnly': False, 'name': '_xsrf', 'path': '/', 'secure': False, 'value': '8a2f9223-fa7f-4c3d-9d1a-3d05e6c11543'}, {'domain': 'zhihu.com', 'expiry': 1636552385.453258, 'httpOnly': False, 'name': '_zap', 'path': '/', 'secure': False, 'value': 'e2f199bf-c180-409b-a9f4-572632edf328'}]
[]
16.选项卡管理
使用js代码打开选项卡
import time
from selenium import webdriver
# 构造一个浏览器对象
browser = webdriver.Chrome()
# 访问url
browser.get('https://www.baidu.com')
# 执行js,打开一个空选项卡
browser.execute_script('window.open()')
# 打印所有的选项卡对象
print(browser.window_handles)
# 切换到第二个选项卡
browser.switch_to_window(browser.window_handles[1])
# 访问url
browser.get('https://www.taobao.com')
# 休眠
time.sleep(1)
# 切换到第一个选项卡
browser.switch_to_window(browser.window_handles[0])
# 第一个选项卡访问url
browser.get('https://python.org')
['CDwindow-BC4327024BBE2556928278A648D41F54', 'CDwindow-4426854BE347916F87A0D359F5171F46']
C:\Users\bsm\Anaconda3\lib\site-packages\ipykernel\__main__.py:13: DeprecationWarning: use driver.switch_to.window instead
C:\Users\bsm\Anaconda3\lib\site-packages\ipykernel\__main__.py:19: DeprecationWarning: use driver.switch_to.window instead
17.异常处理
from selenium import webdriver
# 构造浏览器对象
browser = webdriver.Chrome()
# 访问url
browser.get('https://www.baidu.com')
# 查找一个不存在的元素,抛出元素未找到异常
browser.find_element_by_id('hello')
# 给异常添加对应的异常处理
from selenium import webdriver
from selenium.common.exceptions import TimeoutException,NoSuchElementException
#构造浏览器对象
browser = webdriver.Chrome()
# 对可能出现的异常使用try...except处理
try:
broser.get('https://www.baidu.com')
except TimeoutException:
print('Time Out')
try:
browser.find_element_by_id('hello')
except NoSuchElementException:
print('No Element')
finally:
browser.close()
更多异常信息:http://selenium-python.readthedocs.io/api.html#module-selenium.common.exceptions
-------------------------------------------------------------------------------------ps:内容为爬虫学习笔记,来源于崔庆才的《python3 网络爬虫实战》