python⽹页⾃动化填写-⽤python-webdriver实现⾃动填表在⽇常⼯作中常常需要重复填写某些表单,如果⼈⼯完成,费时费⼒,⽽且⽹络延迟令⼈⼗分崩溃。如果能够⽤程序实现⾃动填表,效率可以提⾼⼀倍以上,并且能够移植到多台计算机,进⼀步提⾼⼯作效率。webdriver是python的selenium库中的⼀个⾃动化测试⼯具,它能完全模拟浏览器的操作,⽆需处理复杂的request、post,对爬⾍初学者⼗分友好。
⼀、环境配置
python3.6+selenium库+xlrd库+xlwt库
其中xlrd和xlwt库⽤于读写excel表中的数据。
还要下载⼀个浏览器的driver⽂件⽤于打开浏览器,注意要选择与计算机系统相符合的版本(max/windows64位/windows32位)
将下载下来的放到浏览器根⽬录和python的根⽬录
⼆、打开⽹页
以IE浏览器为例,以下两⾏代码就可以实现打开⼀个IE浏览器并且访问我们需要填表的⽹站
driver=webdriver.Ie()
<("xxxx/")
如果⽹站需要登陆(需要填表的⼀般是公司内部⽹站),再写⼀个login函数,将driver作为参数调⽤
driver = login(driver)
注意⼀定要将driver传回,这样driver才能继续接受程序的指令
三、元素定位
webdriver的⼯作原理是到⽹页中某⼀个元素,可以对其进⾏填⼊数据或点击等操作。
我主要⽤到的元素定位⽅式有
driver.find_element_by_id("someid")#通过元素的id定位
driver.find_element_by_css_selector("input[value="确定"")#查⼀个input元素,它的value属性值为"确定"
昆山市属于哪个省driver.find_element_by_xpath("//span[contains(@style,"COLOR: red")]/span[1]")#查⼀个style属性值为"COLOR:red"的span元素的第⼀个span⼦元素
(1)通过id定位
吴君如搞笑电影如果我们想在⽹页表单的某⼀个位置填某项值或者点击某个按钮,我们⾸先要⽤开发者⼯具查看这个元素的源代码,然后⾸先观察它有没有id,如果有id,直接⽤id定位该元素。然后,⽤
driver.find_element_by_id("someid").click()#点击元素
driver.find_element_by_id("someid").send_keys("somekeys")#填⼊"somekeys"
driver.find_element_by_id("someid").clear()#清空输⼊框中已有的值
实现我们想要做的操作。
(2)通过ccs selector定位
如果我们想要操作的元素没有ID,那么我们就要到它跟⽹页其他元素不同的特征,ccs selector是⼀种⼗分灵活的定位⽅式,其中⽤value定位是⼀个不错的选择。以
driver.find_element_by_css_selector("input[value="确定"")
为例,双引号中的input可以换成任何⽹页元素(div、span、input、a等),中括号中是该元素的某⼀个属性(style、id、value、class 等),等号后⾯是该属性的值。
注意,如果⽹页中有多个元素同时满⾜ccs selector的条件,如有多个value=“确定” 的input,那么find_element_by_css_selector只会定位到在html源代码中最靠前的⼀个,⽽find_elements_by_css_selector会到源代码中所有满⾜条件的元素,并以列表的形式返回这些到的元素。例如,⽹页中弹出很多个提⽰框,我们要⼀⼀去点确定,可以这样操作
list=driver.find_elements_by_css_selector("input[value=" 确定 "]")for l inlist:
l.click()
但是,如果这些提⽰框是重叠出现的,⽽最上层的提⽰框实际上在源码中更靠后的位置,那么列表中第⼀个“确定”元素就会被叠在上⾯的提⽰框遮挡,⽆法点击,这个时候倒序⼀下数组就可以了,从最后⼀个“确定”元素开始点击
query=driver.find_elements_by_css_selector("input[value=" 确定 "]")for q in query[::-1]:
q.click()
(3)通过xpath定位
xpath定位⽐较复杂但是⾮常全⾯,当这个元素的class、style属性和其他元素⼀样,实在没什么特点可以⼀步定位的时候,我们就可以⽤xpath,先到我们想要的元素的⽗⼦兄弟元素,再定位到我们想要的元素。例如
driver.find_element_by_xpath("//*[@class="submit clear"]/input[1]").click()
text=driver.find_element_by_xpath("//input[@value=" 确定 "]/../preceding-sibling::div[1]").text
driver.find_elements_by_xpath("//span[contains(@style,"COLOR: red")]/span[1]")
引号中的//表⽰相对定位,表⽰从源代码中任何地⽅开始寻。
//后可以跟任何元素,*代表任意元素,即定位符合属性筛选任何元素。
具有中国特的礼物中括号内是属性的筛选条件,@后可以加任意属性。contains(@style,"COLOR: red")表⽰的筛选条件是:style属性中包含”COLOR:red“。这⾥为什么不直接⽤@
的原因是,可能在我们审查源代码的时候这个元素的style属性只有"COLOR: red"这⼀条,但是动态界⾯的style属性经常变化,程序运⾏时直接⽤等于是定位不到这个元素的。
/.. 可以定位这个元素的⽗亲元素
/ 可以定位这个元素的⼦元素
/preceding-sibling:: 可以定位这个元素的哥哥元素
/following-sibling:: 可以定位这个元素的弟弟元素
如/input[1]表⽰⼦元素中第⼀个input、/../preceding-sibling::div[1]表⽰⽗元素的哥哥元素中的第⼀个div
(4)通过当前节点定位
有时候我们会遇到需要判断⼀下元素当前的状态(是否被选择)再决定接下来的操作的情况,这时就需要⽤⼀个变量来保存当前节点
LTE=driver.find_element_by_xpath("//input[@id="LTE"]/../span[1]"
然后再⽤get_attribute获得当前节点元素的属性,在这个例⼦⾥,如果元素为蓝⾊,就不需要点击。代码实现为:
_attribute("style")=="COLOR: blue":pass
魔兽世界盗贼开锁else:
LET.click()
需要筛选出特定⽂本的情况:
red=driver.find_elements_by_xpath("//span[contains(@style,"COLOR: red")]/span[1]")#出所有红⾊的⽂本
for r inred:if "低消" :#如果⽂本信息中包含"低消’
r.find_element_by_xpath("./../preceding-sibling::input[1]").click()#注意从当前节点定位的时候要以"./’开头
break
如果寻的元素需要滚动界⾯才能看到,这个时候可以⽤js聚焦此元素,页⾯便会滚动到该元素的位置
target=driver.find_element_by_css_selector("input[value=" 确定 "]")
target.click()
四、不确定情况处理
(1)有可能出现的弹窗渐进式延迟退休政策
在填表过程中,有些地⽅有可能出现⼀个弹框也有可能不出现,这个时候,⽆论这个弹窗是什么,⽤pt语句处理就可以解决
js触发的弹窗:
try:
driver.find_element_by_css_selector("input[value=" 确定 "]").click()exceptException as e:pass
⽹页alert弹窗:
try:
driver.switch_to.alert.dismiss()exceptException:pass
dismiss()对应的是alert弹窗的”取消“项,accept()对应的是”确定“项,driver.switch_ 可以获得弹窗的⽂本内容。
(2)数量不定的弹窗
对上⽂提到的多个提⽰框情况,除了⽤ query=driver.find_elements_by_css_selector("input[value=" 确定 "]") ⼀次性到所有元素再顺序或倒序点击之外,还可以⽤⼀个while循环解决
while(1):try:
driver.find_element_by_css_selector("input[value=" 确定 "]").click()exceptException as e:break
(3)⽹络延迟
有些⽹页在点击查询信息之后需要加载⼀段时间,加载中的页⾯是不到我们接下来想的元素的,因此程序就会报错,此时有两种解决⽅法。
⼀种是固定等待⼀段时间,等待⽹页加载完毕,这种⽅法的缺点是很难到等待的最佳时间,太短的话页⾯还没加载完,太长就影响效率
time.sleep(2)
另⼀种是⽤⼀个while循环⼀直寻下⼀个我们要的元素
while(1):try:
哪些食物养肝护肝最好driver.find_element_by_id("continueTrade").click()break
exceptException:pass
这种⽅法的前提是下⼀个要的元素必定会出现
五、frame处理
总结起来就是:frameset不⽤切,frame层层切。最好⼀系列填表操作完后都⽤ driver.switch_to.default_content() 回到原⽂档,这样不容易混乱
这⾥再补充⼀点frame没有id时的切⼊⽅法
frame= self.driver.find_element_by_xpath("/html/body/div[12]/iframe")#先定位frame位置,⽤⼀个变量储存这个节点self.driver.switch_to_frame(frame)#再切⼊这个节点
六、excel数据读写
excel数据读写⼗分简单,看代码就好了:
defread(file):
data= xlrd.open_workbook(file)#打开excel⽂件
table = data.sheets()[0]#读取第⼀个sheet的数据
phones = l_values(0)#以列表形式存储第⼀列数据
peoples = l_values(1)#以列表形式存储第⼆列数据
returnphones,peoplesdefwrite(result):
file=xlwt.Workbook()#创建⼀个excel⽂件
table = file.add_sheet("sheet1")#添加⼀个sheet
for i in range(len(result)):#写⼊数据
table.write(i,0,result[i][0])
table.write(i,1,result[i][1])
table.write(i,2,result[i][2])
file.save("result.xls")
结语:希望技术能让⼈们从⽆意义的重复劳动中解脱:D
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论