Selenium 是一套 Web网站 的程序自动化操作 解决方案。通过它,我们可以写出自动化程序,像人一样在浏览器里操作web界面。 比如点击界面按钮,在文本框中输入文字 等操作。而且还能从web界面获取信息。 比如获取火车、汽车票务信息、招聘网站职位信息,财经网站股票价格信息等等,然后用程序进行分析处理。
写的自动化程序 需要使用 客户端库。我们程序的自动化请求都是通过这个库里面的编程接口发送给浏览器。比如,我们要模拟用户点击界面按钮, 自动化程序里面就应该 调用客户端库相应的函数, 就会发送 点击元素 的请求给 下方的 浏览器驱动。然后,浏览器驱动再转发这个请求给浏览器。这个自动化程序发送给浏览器驱动的请求 是HTTP请求。
客户端库从哪里来的? 是Selenium组织提供的。Selenium组织提供了多种 编程语言的Selenium客户端库, 包括 java,python,js, ruby等,方便不同编程语言的开发者使用。我们只需要安装好客户端库,调用这些库,就可以发出自动化请求给浏览器。
总结一下,selenium 自动化流程如下:
-
自动化程序调用Selenium 客户端库函数(比如点击按钮元素)
-
客户端库会发送Selenium 命令 给浏览器的驱动程序
-
浏览器驱动程序接收到命令后 ,驱动浏览器去执行命令
-
浏览器执行命令
-
浏览器驱动程序获取命令执行的结果,返回给我们自动化程序
-
自动化程序对返回结果进行处理
选择元素的方法(控制界面元素):
主要流程:选择界面元素(定位界面元素),操作定位到的元素。
选择定位元素的方法:
1、id属性,选择元素。
element = driver.find_element_by_id('kw').send_keys('通讯\n')
2、class属性,选择元素。
elements = driver.find_elements_by_class_name('animal')
for element in elements:
print(element.text)
3、Tag名称,选择元素
# 根据 tag name 选择元素,返回的是一个列表
# 里面 都是 tag 名为 div 的元素对应的 WebElement对象
elements = wd.find_elements(By.TAG_NAME, 'div')
# 取出列表中的每个 WebElement对象,打印出其text属性的值
# text属性就是该 WebElement对象对应的元素在网页中的文本内容
for element in elements:
print(element.text)
driver.find_element(By.LINK_TEXT,'新房'),一般用在a标签,link_text定位的是超链接的全部文本内容,所以匹配条件为绝对匹配。
driver.find_element(By.PARTIAL_LINK_TEXT,''),partial_link_text为link_text的补充,partial_link_text定位的是超链接的局部文本内容,所以匹配条件为部分匹配就满足条件
driver.find_element(By.XPATH,''),路径定位,xpath定位(全路径、根据属性值定位、逻辑和属性值定位、标签类型和属性值定位)
4、等待界面元素出现
进行网页操作的时候, 有的元素内容不是可以立即出现的, 可能会等待一段时间。因为我们的代码执行的速度比网站相应的速度要快。在短暂的瞬间, 网页上是没有用 id为1的元素的 ,还没有搜索结果,自然就会报告错误 id为1 的元素不存在了。 点击搜索后,可以用sleep 来等待几秒钟, 等服务器返回结果后,再去选择 id的元素。
Selenium提供了一个更合理的解决方案,当发现元素没有找到的时候,并不立即返回 找不到元素的错误。而是周期性(每隔半秒钟)重新寻找该元素,直到该元素找到,或者超出指定最大等待时长,这时才抛出异常。Selenium 的 Webdriver 对象 有个方法叫 implicitly_wait
,可以称之为 隐式等待
,或者 全局等待
。
显式等待:
设置一个超时时间,每个一段时间就去检测一次该元素是否存在,如果存在则执行后续内容,如果超过最大时间(超时时间)则抛出超时异常。
隐式等待:
隐式等待也是指定一个超时时间,如果超出这个时间指定元素还没有被加载出来,会抛出异常。隐式等待是全局性的,即运行过程中,如果元素可以定位到,它不会影响代码运行,但如果定位不到,则它会以轮询的方式不断地访问元素直到元素被找到,若超过指定时间,则抛出异常。使用implicitly_wait实现隐式等待。driver.implicitly_wait(5)
强制等待:
使用 time.sleep() 强制等待,设置固定的休眠时间,对于代码的运行效率会有影响。
5、浏览器的控制及常见操作
# 设置浏览器浏览器的宽高为:600x800
driver.set_window_size(600, 800)
#设置实现浏览器全屏显示
driver.maximize_window()
#返回(后退)到页面
driver.back()
#前进页面
driver.forward()
#新标签中打开
js = "window.open('https://blog.csdn.net/qq_43965708')"
driver.execute_script(js)
# 刷新页面
driver.refresh()
# 获取打开的多个窗口句柄
windows = driver.window_handles
# 切换到当前最新打开的窗口
driver.switch_to.window(windows[-1])
#模拟输入指定内容
send_keys()
#清除文本内容
clear()
#判断元素是否可见
is_displayed()
#获取标签属性值
get_attribute()
#返回元素的尺寸
size
#返回元素文本
text
# 点击左键
click()
# 点击右键
context_click()
# 双击
double_click()
# 模拟回车键进行跳转(输入内容后)
driver.find_element_by_id('xxx').send_keys(Keys.ENTER)
# 使用 Backspace 来删除一个字符
driver.find_element_by_id('xxx').send_keys(Keys.BACK_SPACE)
# Ctrl + A 全选输入框中内容
driver.find_element_by_id('xxx').send_keys(Keys.CONTROL, 'a')
# Ctrl + C 复制输入框中内容
driver.find_element_by_id('xxx').send_keys(Keys.CONTROL, 'c')
# Ctrl + V 粘贴输入框中内容
driver.find_element_by_id('xxx').send_keys(Keys.CONTROL, 'v')
#关闭所有窗口
driver.quit()
#关闭当前页面
driver.close()
弹窗处理:
有三种弹窗alter(确认)、confirm(确认、取消)、prompt(文本框、确认、取消)。
处理方式:先定位(switch_to.alter,自动获取当前弹窗),在使用text、accept、dismiss、send_keys等方法进行操作。
#获取弹窗中的文字
text
#接受(确认)弹窗内容
accept
#解除(取消)弹窗
dismiss
#发送文本至警告框
send_keys
selenium消除启动特征避免被反爬 , selenium启动的Chrome中有几十个特征可以被识别,常见的配置如下:
设置请求头的user-agent
chrome_options.add_argument('user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36')
设置正常浏览器
chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
设置为无头模式
chrome_options.add_argument('--headless')
谷歌浏览器高版本强化隐藏,防止发现
chrome_options.add_argument("--disable-blink-features=AutomationControlled")
取消浏览器顶部的自动软件控制,屏蔽webdriver特征
chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
chrome_options.add_experimental_option('useAutomationExtension', False)
常见的报错原因:
1.NoSuchElementException:没有找到元素
2.NoSuchFrameException:没有找到iframe
3.NoSuchWindowException:没找到窗口句柄handle
4.NoSuchAttributeException:属性错误
5.NoAlertPresentException:没找到alert弹出框
6.lementNotVisibleException:元素不可见
7.ElementNotSelectableException:元素没有被选中
8.TimeoutException:查找元素超时
normalize-space(//div[contains(text(),'装修情况')]/following-sibling::div[1])