为什么Selenium点不到元素

最近做了许多登陆项目,我会优先选择使用requests来模拟请求,但是有些参数实在是很难获取,这个时候我会使用Selenium,也还是遇到了各种坑,也算是见识到了很多的验证措施。

今天说说如何解决selenium点选不到数据的问题。

等待

这还是最常见的一种情况,推荐最多的是使用显示等待:

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

driver = webdriver.Firefox()
driver.get("http://somedomain/url_that_delay_loading")
try:
    element = WebDriverWait(driver,10).until(
        EC.presence_of_element_located((By.ID,"myDynamicElement"))
    )
finally:
    driver.quit()

这段代码会等待10秒,如果10秒内找到元素则立即返回,否则会抛出TimeoutException异常。

但是我比较懒,因为time.sleep()可以达到同样效果。

鼠标事件

官方把它叫做“行为链”。ActionChains可以完成简单的交互行为,例如鼠标移动,鼠标点击事件,键盘输入,以及内容菜单交互。

click(on_element=None) ——单击鼠标左键

click_and_hold(on_element=None) ——点击鼠标左键,不松开

context_click(on_element=None) ——点击鼠标右键

double_click(on_element=None) ——双击鼠标左键

drag_and_drop(source, target) ——拖拽到某个元素然后松开

drag_and_drop_by_offset(source, xoffset, yoffset) ——拖拽到某个坐标然后松开

key_down(value, element=None) ——按下某个键盘上的键

key_up(value, element=None) ——松开某个键

move_by_offset(xoffset, yoffset) ——鼠标从当前位置移动到某个坐标

move_to_element(to_element) ——鼠标移动到某个元素

move_to_element_with_offset(to_element, xoffset, yoffset) ——移动到距某个元素(左上角坐标)多少距离的位置

perform() ——执行链中的所有动作

release(on_element=None) ——在某个元素位置松开鼠标左键

send_keys(*keys_to_send) ——发送某个键到当前焦点的元素

send_keys_to_element(element, *keys_to_send) ——发送某个键到指定元素

深入了解可以参考 https://blog.csdn.net/huilan_same/article/details/52305176

move_to_element_with_offsetclick_and_hold会经常用到破解验证码中。

触摸操作 (TouchAction)

该事件仅仅针对移动端、触屏版

flick_element(on_element, xoffset, yoffset, speed) # 以元素为起点以一定速度向下滑动

scroll_from_element(on_element xoffset yoffset) #以元素为起点向下滑动

double_tap(on_element)                                     #双击   

flick_element(on_element, xoffset, yoffset, speed)         #从元素开始以指定的速度移动

long_press(on_element)                                            #长按不释放

move(xcoord, ycoord)                                                #移动到指定的位置

perform()                                                                    #执行链中的所有动作

release(xcoord, ycoord)                                             #在某个位置松开操作

scroll(xoffset, yoffset)                                                      #滚动到某个位置

scroll_from_element(on_element, xoffset, yoffset)         #从某元素开始滚动到某个位置

tap(on_element)                                                             #单击

tap_and_hold(xcoord, ycoord)                                        #某点按住

为什么要说到移动端,在做登陆时,移动端往往会更加简单,但是触屏版的点击和PC端时完全不同的,点击与按住时不同的。

在某个项目我换成TouchAction后,神奇的发现,注册不再需要处理验证码了,真是太棒了。

使用js

当你使用浏览器已经找到该元素,使用click()方法但是不起作用时,这个时候建议尝试js,例如在我的主页 https://www.zhihu.com/people/cuishite/activities,点击 “查看详细资料”

python js = 'document.getElementsByClassName("Button ProfileHeader-expandButton Button--plain")[0].click();' driver.execute_script(js)

你可以先在控制台调试

js通常可以解决绝大多是问题,如果还是解决不了,那你可能和我遇到了同样的问题,比如说,我在处理某移动端网站登陆,处理如下验证码时,我会使用到move_to_element_with_offset,该方法是“移动到距某个元素(左上角坐标)多少距离的位置”。

计算出坐标后,会调用该方法,如action.move_to_element_with_offset(element, width, height).click().perform(),然而实际上问题并没有这么简单,多次点击失效。具体的有时间再说。

实用方法

提取selenium的cookies

介绍把selenium的cookies船体给requests使用的方法:

cookies = driver.get_cookies()

s = requests.Session()
for cookie in cookies:
    s.cookies.set(cookie['name'], cookie['value'])

How do I load session and cookies from Selenium browser to requests library in Python?

元素截图方法

from selenium import webdriver
from PIL import Image

fox = webdriver.Firefox()
fox.get('https://stackoverflow.com/')

# now that we have the preliminary stuff out of the way time to get that image :D
element = fox.find_element_by_id('hlogo') # find part of the page you want image of
location = element.location
size = element.size
fox.save_screenshot('screenshot.png') # saves screenshot of entire page
fox.quit()

im = Image.open('screenshot.png') # uses PIL library to open image in memory

left = location['x']
top = location['y']
right = location['x'] + size['width']
bottom = location['y'] + size['height']


im = im.crop((left, top, right, bottom)) # defines crop points
im.save('screenshot.png') # saves new cropped image

selenium cannot screenshot a web element

最后推荐一个神器 appium/python-client

至于验证码部分,现在主要还是靠第三方工具,并没有自己尝试机器学习等方法处理。

原文发布于微信公众号 - Python爬虫与算法进阶(zhangslob)

原文发表时间:2018-07-24

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏web开发

VUE路由去除#问题

最近自己在写一个vue的小型管理系统,在浏览器中看到的路由都是带有#的,很是不好看。为了解决此问题,大家一般都会想到:mode: 'history'。可是在开发...

2494
来自专栏守望轩

Visual Studio 2008 每日提示(六)

#051、循环使用剪贴薄里粘贴的不同内容 原文地址:http://blogs.msdn.com/saraford/archive/2007/10/01/did...

34110
来自专栏React Native开发圈

React Native 图片查看组件

npm i react-native-image-zoom-viewer--save

1062
来自专栏编程之路

羊皮书APP(Android版)开发系列(二十七)一分钟轻松修改CheckBox、RadioButton、RatingBar、SeekBar样式

总结:通过一个简单的样式定义,即可完成对android原生控件样式的修改,省时省力省资源。赶紧试试吧!

1153
来自专栏前端架构与工程

解决transition动画与display冲突的几种方法

如demo(如果没有显示,请查看源地址http://jsfiddle.net/ihardcoder/HNduT/2/)所示,基本的效果是在点击“Translat...

1976
来自专栏前端知识分享

第142天:Size Marks下载安装和使用方法

1、下载Size marks:链接: https://pan.baidu.com/s/1breyMf1 密码: fjsn

983
来自专栏IT开发技术与工作效率

IntelliJ IDEA 教程 技巧篇本篇概要

1132
来自专栏cnblogs

关于HTML面试题汇总之H5

一、H5有哪些新特性,移除了哪些元素?如何处理h5新标签的浏览器兼容性问题,如何区分html和html5 1. html5不在是SGL(通用标记语言)的一个子集...

2555
来自专栏无所事事者爱嘲笑

Vue中scoped css和css module比较

3672
来自专栏前端侠2.0

表格内,设置许多元素的大小时,js的速度慢的办法

思路1:设置td为relative,input为absolute,然后设置input大小为td的大小。

1282

扫码关注云+社区