前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >为什么Selenium点不到元素

为什么Selenium点不到元素

作者头像
小歪
发布2018-08-08 17:13:52
2.1K0
发布2018-08-08 17:13:52
举报

最近做了许多登陆项目,我会优先选择使用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

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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-07-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python爬虫与算法进阶 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 等待
  • 鼠标事件
  • 触摸操作 (TouchAction)
  • 使用js
  • 实用方法
相关产品与服务
验证码
腾讯云新一代行为验证码(Captcha),基于十道安全栅栏, 为网页、App、小程序开发者打造立体、全面的人机验证。最大程度保护注册登录、活动秒杀、点赞发帖、数据保护等各大场景下业务安全的同时,提供更精细化的用户体验。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档