爬虫系列总目录
本章节介绍数据存储相关内容。Mysql、MongoDB、redis 等基础内容。动态页面的数据获取。
第三章 数据库简介与使用
第三章 MongoDB及Redis使用
第三章 Selenium和Ajax使用
Selenium和AJAX 使用
一、 Selenium 使用
1.1 Selenium简介
Selenium是一个用于Web应用程序自动化测试工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。支持的浏览器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera等。
-
主要功能包括:测试与浏览器的兼容性——测试你的应用程序看是否能够很好得工作在不同浏览器和操作系统之上。
-
测试系统功能——创建回归测试检验软件功能和用户需
求。支持自动录制动作和自动生成 .Net、Java、Perl等
不同语言的测试脚本。(上述来自百度百科) -
Selenium框架由多个工具组成,包括: Selenium IDE,Selenium RC,Selenium WebDriver等。我们所使用的是其中的Selenium WebDriver。
1.2 Selenium 库里的WebDriver
WebDriver 是基于web的测试工具,可以直接调用web浏览器,并且以这种方式进行测试。WebDriver的使用需要安装对应的浏览器驱动,并且该驱动必须根据浏览器版本来进行安装。
win电脑解压后直接将chromedriver文件剪切到对应的python虚拟环境中的Scripts目录下,如果不行就放置到同级目录的Lib\site-packages。 可不设置环境变量。
1 页面操作
from selenium import webdriver
# 创建浏览器对象
driver = webdriver.Chrome()
# 使用浏览器访问百度
driver.get('https://www.baidu.com')
# 获取当前页面的网页源码
# print(driver.page_source)
# 获取当前页面的url
print(driver.current_url)
# 关闭当前窗口 .
driver.close()
# 关闭所有关联窗口 #
driver.quit()
1 查找单个元素
方法一
- find_element_by_id(id) 通过 id 匹配
- find_element_by_name(name) 通过 name匹配
- find_element_by_class_name(name) 通过class_name匹配
- find_element_by_tag_name(name) 通过tag_name匹配
- find_element_by_css_selector(css_selector) 通过css_selector 匹配
- find_element_by_xpath(xpath) 通过 xpath 匹配
方法二
- By.ID 通过id匹配
- By.NAME 通过name匹配
- By.CLASS_NAME 通过class_name匹配
- By.TAG_NAME 通过tag_name匹配
- By.CSS_SELECTOR 通过css_selector匹配
- By.XPATH 通过xpath匹配
注意:对于两种方法来说,若成功找到则返回WebElement 对象,若没有找到则抛出NoSuchElementException 异常如果需要查找多个元素时,只需要把方法中的 element改成 elements 即可,elements返回的是匹配结果的列表。
from selenium import webdriver
import time
# 创建浏览器对象
driver = webdriver.Chrome()
# 使用浏览器对象访问百度
driver.get('https://www.baidu.com')
# 通过ID获取
# i_id = driver.find_element_by_id('su')
# print(i_id.get_attribute('value'))
# 通过name属性获取
# f_name = driver.find_element_by_name('f')
# print(f_name.get_attribute('class'))
# 通过类名获取
# class_name = driver.find_element_by_class_name('bg s_btn')
# 如果class对应是多个值 如果使用空格隔开就会报错,
# 解决办法: 将空格更换为.
# class_name = driver.find_element_by_class_name('bg.s_btn')
# print(class_name.get_attribute('value'))
# css选择器
css_selector = driver.find_element_by_css_selector('#su')
print(css_selector.get_attribute('value'))
# 通过xpath
xpath = driver.find_element_by_xpath("//input[@class='bg s_btn']")
print(xpath.get_attribute('value'))
driver.close()
2 文本框写入操作
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
import time
# 创建浏览器对象
driver = webdriver.Chrome()
# 访问百度
driver.get('https://www.baidu.com')
# 获取输入框
search_bar = driver.find_element(By.ID, 'kw')
# 获取提交按钮
button = driver.find_element(By.ID, 'su')
# 往输入框输入内容
search_bar.send_keys(u'Python爬虫')
# 清除输入框
time.sleep(2)
# search_bar.clear()
# 输入enter键
# search_bar.send_keys(Keys.ENTER)
# 执行交互动作, 鼠标左键点击提交按钮提交输入框的内容
button.click()
# driver.close()
3 执行交互动作
用selenium做自动化,有时候会遇到需要模拟鼠标操作才能进行的情况,比如单击、双击、点击鼠标右键、拖拽等等。而selenium给我们提供了一个类来处理这类事件——ActionChains。
首先需要了解ActionChains的执行原理,当你调用ActionChains的方法时,不会立即执行,而是会将所有的操作按顺序存放在一个队列里,当你调用perform()方法时,队列中的时间会依次执行。
- click(on_element=None) 鼠标左键点击元素
- double_click(on_element=None) 鼠标左键双击元素
- context_click(on_element=None) 鼠标右键点击元素
- click_and_hold(on_element=None) 按下鼠标
- release(on_element=None) 松开鼠标
- move_to_element(to_element) 移动鼠标到指定元素中央
- drag_and_drop(source,target) 拖拽元素
- key_down(value,element=None) 按下键盘,一般只用在Ctrl、Alt和Shift
- key_up(value,element=None) 松开键盘
from selenium import webdriver
from
selenium.webdriver.common.action_chains import ActionChains driver = webdriver.Chrome()
driver.get('https://tieba.baidu.com/f? ie=utf-8&kw=%E7%88%AC%E8%99%AB&fr=search')
# 获取下一页的按钮
target = driver.find_element_by_class_name('next.pag
ination-item ')
# 滚动到下一页按钮所在位置并点击下一页按钮翻页
ActionChains(driver).move_to_element(target ).click(target).perform()
# driver.close()
2 填充表单
下拉菜单操作
from selenium import webdriver from selenium.webdriver.support.ui import Select
driver = webdriver.Chrome()
1.5 页面切换
driver.get('http://www.ccgp- hebei.gov.cn/csqh/')
select = Select(driver.find_element_by_id('province'))
# 根据index选择 index是从0开始的
# 选择第4个选项
# select.select_by_index(3) # 根据对应的value选择 # select.select_by_value('../sjz/sjz/')
# 根据option标签中文本值选择,即点击下拉菜单出现的值
select.select_by_visible_text('唐山市')
# 取消全部选择
select.deselect_all()
driver.close()
3 页面切换
在浏览器操作中,通常会需要打开多个浏览器界面,如果不使用switch_to.window,程序会每次还去程序打开的最初始的那个界面寻找元素,这样就导致新界面中的元素找不到。
这个时候,就需要通过switch_to.window(windowhandles)方法来对浏览器页面进行切换,其中参数windowhandles为网页的窗口句柄。
from selenium import webdriver
import time
# 创建浏览器对象
driver = webdriver.Chrome()
# 使用浏览器对象访问百度
driver.get('https://www.baidu.com')
time.sleep(3)
# u'登录' 中文转义
driver.find_element_by_link_text(u'登录').click()
time.sleep(3)
# 点击立即注册
driver.find_element_by_link_text(u'立即注册').click()
# 获取url
# print(driver.current_url)
# 获取当前窗口 第一次打开的窗口
first_win = driver.current_window_handle
# 获取全部的窗口
all_win = driver.window_handles
# 获取每一个窗口
for win in all_win:
if win != first_win:
driver.switch_to.window(win)
print('切换成功')
driver.find_element_by_id('TANGRAM__PSP_4__userName').send_keys('hello spider!')
time.sleep(3)
# 切换到第一个窗口
driver.switch_to.window(first_win)
driver.find_element_by_id('TANGRAM__PSP_11__userName').send_keys('hello python!')
driver.find_element_by_link_text(u'立即注册').click()
# 关闭当前窗口
driver.close()
time.sleep(3)
# 关闭所有窗口
driver.quit()
4 弹窗处理
弹窗一般在第一次访问时会出现,那么处理的办法可以为: 获取该弹窗上的具体某个元素,点击。
from selenium import webdriver
import time
# 创建浏览器对象
driver = webdriver.Chrome()
# 使用浏览器对象访问百度
driver.get('https://www.baidu.com')
time.sleep(3)
# u'登录' 中文转义
driver.find_element_by_link_text(u'登录').click()
time.sleep(3)
driver.find_element_by_id('TANGRAM__PSP_4__closeBtn').click()
# alter
# alter = driver.switch_to.alert
driver.close()
5 Headerless Browser
Headerless Browser(无头的浏览器)是浏览器的无界面状态,可以在不打开浏览器GUI的情况下,使用浏览器支持的性能。
好处: 可以加快UI自动化测试的执行时间,对于UI自动化测试,少了真实浏览器加载css,js以及渲染页面的工作。
无头测试要比真实浏览器快的多。
from selenium import webdriver
import time
# 设置为无头模式
chrome_headeless = webdriver.ChromeOptions()
chrome_headeless.add_argument('headless')
# 创建浏览器对象 并且开启无头模式
driver = webdriver.Chrome(options=chrome_headeless)
driver.get('https://www.baidu.com')
# 通过ID获取
i_id = driver.find_element_by_id('su')
print(i_id.get_attribute('value'))
driver.close()
6 页面等待
1. 强制等待
import time
time.sleep(num)
2. 隐式等待
- 隐式等待针对元素定位。设置等待时间,如在规定时间内元素定位成功,则执行下一步。如果未成功,报超时异常。
- 隐性等待对整个driver的周期都起作用,只需要设置一次。
from selenium import webdriver
# 创建浏览器对象
driver = webdriver.Chrome()
# 设置隐时等待
driver.implicitly_wait(10)
# # 使用浏览器对象访问百度
driver.get('https://www.baidu.com')
i_id = driver.find_element_by_id('su')
print(i_id.get_attribute('value'))
3. 显示等待
明确等待某一个元素根据判断条件进行灵活等待,程序每隔一段时间检测一次,如果检测结果与条件成立,则执行下一步,否则继续等待,直到超过设置的最长时间为止,然后抛出TimeoutException异常。
显式等待涉及到多个模块:By、expected_conditions和WebDriverWait。 expected_conditions:验证网页元素是否存在,提供了多种验证方式。
WebDriverWait参数说明如下
- driver:浏览器对象driver。
- timeout:超时时间,等待的最长时间。
- poll_frequency:检测的间隔步长,默认为0.5s。
- ignored_exceptions:超时后的抛出的异常信息,默认抛出NoSuchElementExeception异常。
- until:条件判断。
- until not:与until逻辑相反。
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By
# 一般会将expected_conditions 重命名为EC
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome()
# # 使用浏览器对象访问百度
driver.get('https://www.baidu.com')
# visibility_of_element_located检查网页元素是否可见
condition = EC.visibility_of_element_located((By.ID, 'su'))
"""
driver:WebDriver 的驱动程序
timeout:最长超时时间,默认以秒为单位 poll_frequency:休眠时间的间隔(步长)时间,默认为
0.5 秒
"""
"""
WebDriverWait 一般是配合until() 使用
作用: 程序每隔固定时间查看一下, 如果成立了就执行下一
步,否则继续等待还没有满足要求,超过最长时间会抛出 TimeoutException异常
"""
WebDriverWait(driver=driver, timeout=10, poll_frequency=0.5).until(condition)
i_id = driver.find_element_by_id('su')
print(i_id.get_attribute('value'))
driver.close()
二、Ajax
AJAX全称:异步的JavaScript和XML。
Ajax 不是一种新的编程语言,而是一种在无需重新加载整个页面情况下能够更新部分网页的技术。就是一种用js发送请求的技术。
Ajax工作原理
- Step1.JavaScrpit发送异步请求
- Step2.服务端查询数据库,返回数据
- Step3.服务端返回Response
- Step4.客户端根据返回的Response,来用JavaScript操作DOM。