selenium3+python自动化8-JS处理滚动条 (2020-02-14 17:35)

一、前言

这几天学习了JS(JavaScript)在selenium自动化应用方面的一些小技巧,有些特殊的操作selenium+python无法直接完成,比如控制滚动条,JS又刚好是这方面的强项,所以算是一个很好的补充。JS还有很多神操作,后期遇到就一边学习一边总结。这次主要是总结JS处理滚动条的内容,包含浏览器滚动条内嵌div滚动条

selenium提供了一个操作js的方法:execute_script(),可以直接执行js的脚本。

二、浏览器滚动条

1.浏览器滚动条

浏览器滚动条就是我们常见的打开一个窗口,窗口右侧纵向滚动条和窗口底部的横向滚动条。

 

2.纵向移动(scrollTop)

Firefox浏览器和Chrome浏览器用的语法不一样,下面区分列出来。

js = "var q=document.documentElement.scrollTop=10000"    # Firefox浏览器滚动到底部

js = "var q=document.documentElement.scrollTop=0"            # Firefox浏览器滚动到顶部 

js = "var q=document.body.scrollTop=10000"                         # Chrome浏览器滚动到底部

js = "var q=document.body.scrollTop=0"                                # Chrome浏览器滚动到顶部

我自己用谷歌79版本,但是后面2个代码未成功。网上给出解释如下:

3.横向移动(scrollTo)

有时候浏览器页面需要左右滚动(一般屏幕最大化后,左右滚动的情况已经很少见了),为了效果,在自动化脚本中设置窗口大小。

js = "window.scrollTo(x,y);"                      #  x为横向距离 y为纵向距离

4.不存在兼容问题的scrollTo函数

--scrollHeight 获取对象的滚动高度。 
--scrollLeft 设置或获取位于对象左边界和窗口中目前可见内容的最左端之间的距离。 
--scrollTop 设置或获取位于对象最顶端和窗口中可见内容的最顶端之间的距离。 
--scrollWidth 获取对象的滚动宽度。

js = "window.scrollTo(0,document.body.scrollHeight)"     # 滚动到底部

js = "window.scrollTo(0,0)"                                               # 滚动到顶部

js = "window.scrollTo(x,y)"                                               # 滚动到横向距离为X纵向距离为Y的位置

5.实际应用

执行js脚本用driver.execute_script(js),以百度搜索为例,代码如下:

from time import sleep
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://www.baidu.com/")
driver.find_element_by_id("kw").send_keys("selenium")
driver.find_element_by_id("su").click()
driver.set_window_size(800,700)#方便观察
driver.implicitly_wait(10)
#滚动条移动
js="var q=document.documentElement.scrollTop=100"
driver.execute_script(js)
sleep(2)
js="var q=document.body.scrollTop=0;"#无效果
driver.execute_script(js)
sleep(2)
js='window.scrollTo(0,document.body.scrollHeight)'
driver.execute_script(js)
sleep(2)
js="window.scrollTo(400,0)"
driver.execute_script(js)
sleep(2)
js="var q=document.body.scrollTop=10000"#无效果
driver.execute_script(js)
sleep(2)
driver.quit()

6.元素聚焦

虽然用上面的方法可以解决拖动滚动条的位置问题,但是有时候无法确定我需要操作的元素在什么位置,有可能每次打开的页面不一样,元素所在的位置也不一样,怎么办呢?这个时候我们可以先让页面直接跳到元素出现的位置,然后就可以操作了。同样需要借助JS去实现。

元素聚焦:

target = driver.find_element_by_xxxx()
driver.execute_script("arguments[0].scrollIntoView();", target)

以百度搜索页最下边聚焦第二页的“2”为例,代码如下:在这里需要注意,查询结果出来后再进行窗口大小设置,避免提前设置窗口太小,导致“百度一下”按钮被遮挡,定位不到。

from time import sleep
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://www.baidu.com/")
driver.find_element_by_id("kw").send_keys("selenium")
driver.find_element_by_id("su").click()
# driver.set_window_size(600,700)#方便观察
driver.implicitly_wait(10)
# 元素聚焦
target=driver.find_element_by_xpath('//*[@id="page"]/a[1]/span[2]')#元素聚焦到第二页
driver.execute_script("arguments[0].scrollIntoView();",target)
sleep(5)
driver.quit()

三、内嵌div滚动条

1.内嵌滚动条

页面源码如下:(老规矩:copy下来,用文本保存下来,后缀改成.html,用浏览器打开)

<!DOCTYPE html>
<html>
<head>
<style type="text/css">
div.scroll
{
background-color:#afafaf;
width:300px;
height:100px;
overflow:auto;
}
 
</style>
</head>
 
<body>
 
<p>这是一个内嵌的div滚动条</p>
<div id="ann1" name="ann" class="scroll">这是一个内嵌div:民国年间,九大家族镇守长沙,被称为“九门提督”。这九门势力庞大,外八行的无人不知,无人不晓,几乎所有冥器,流出长沙必然经过其中一家。
1933年秋,一辆神秘鬼车缓缓驶入长沙火车站,九门之首“张大佛爷”张启山身为布防官,奉命调查始末。张启山与八爷齐铁嘴一路探访,发现长沙城外有一座疑点重重的矿山,一直被日本人窥伺。
为破解矿山之谜,张启山求助同为九门上三门的戏曲名伶二月红,无奈二月红虽出身考古世家,却心系重病的妻子丫头,早已金盆洗手。张启山为了国家大义和手足之情,北上去往新月饭店为二月红爱妻求药。在北平,张启山邂逅了新月饭店的大小姐尹新月,并为尹新月连点三盏天灯,散尽家财。尹新月帮助张启山等人顺利返回长沙,二人暗生情愫。二月红爱妻病入膏肓,服药后不见好转,最终故去。
二月红悲伤之余却意外发现家族祖辈与矿山亦有重大关联,于是振作精神,决定与张启山联手,解开矿山之谜zhegedancihenchanghenchangchangchangchangchanchanchanchangchangchangchancg</div>
 
</body>
</html>

2.纵向移动(scrollTop)

思路:通过id或者class定位到滚动条,即div属性。再通过控制scrollTop的值来控制滚动条高度。

注意:js用class属性定位,返回的是一个list对象,中间是elements。

以上面内嵌滚动来练习,代码如下:

#内嵌滚动条
from time import sleep
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("file:///C:/Users/%E5%BC%A0%E5%85%A8/Desktop/divgundongtiao.html")
sleep(1)
#通过ID定位 js1='document.getElementById("ann1").scrollTop=10000'#纵向底部 driver.execute_script(js1) sleep(2) js1='document.getElementById("ann1").scrollTop=0'#纵向顶部 driver.execute_script(js1) sleep(2) #通过class定位,返回是list对象,取第一个就可以,中间是elements js1='document.getElementsByClassName("scroll")[0].scrollTop=10000'#纵向底部 driver.execute_script(js1) sleep(2) js1='document.getElementsByClassName("scroll")[0].scrollTop=0'#纵向顶部 driver.execute_script(js1) sleep(2) driver.quit()

3.横向移动(scrollLeft)

跟纵向移动的区别是:通过scrollLeft的值来控制滚动条高度。直接上代码:

from time import sleep
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("file:///C:/Users/%E5%BC%A0%E5%85%A8/Desktop/divgundongtiao.html")
sleep(1)
#横向移动scrollLeft
#通过ID定位
js2='document.getElementById("ann1").scrollLeft=10000'#纵向底部
driver.execute_script(js2)
sleep(2)
js2='document.getElementById("ann1").scrollLeft=0'#纵向顶部
driver.execute_script(js2)
sleep(2)
#通过class定位,返回是list对象,取第一个就可以
js2='document.getElementsByClassName("scroll")[0].scrollLeft=10000'#纵向底部
driver.execute_script(js2)
sleep(2)
js2='document.getElementsByClassName("scroll")[0].scrollLeft=0'#纵向顶部
driver.execute_script(js2)
sleep(2)
driver.quit()

参考博客:https://blog.csdn.net/weixin_43507959/article/details/85263982   https://www.cnblogs.com/yoyoketang/p/6188582.html

原文地址:https://www.cnblogs.com/xiaobeibi/p/12323733.html