selenium相关:通过location 和 size 获取元素所在像素位置和尺寸,截取图片ROI

1.实验

    #https://captcha.luosimao.com/demo/
    chrome
        default:
                location 不滚动,直接返回相对整个html的坐标  {'x': 15.0, 'y': 129.0}
                location_once_scrolled_into_view 返回相对可视区域的坐标(改变浏览器高度,可以观察到底部元素底部对齐后y的变化)
                                                        顶部/底部元素 完全可见不滚动,{u'x': 15, u'y': 60}
                                                        顶部元素部分可见或完全不可见都会滚动到 顶部对齐  {u'x': 15, u'y': 0}  account-wall
                                                        底部元素部分可见或完全不可见都会滚动到 底部对齐  {u'x': 15, u'y': 594} theme-list
        frame:
            location 不滚动,直接返回相对frame即当前相应内层html的坐标{'x': 255.0, 'y': 167.0}  captcha_frame 的 lc-refresh
            location_once_scrolled_into_view 返回相对可视区域的坐标
                                                        完全可见不滚动{u'x': 273, u'y': 105}
                                                        部分可见或完全不可见滚动到 顶部对齐  {u'x': 273, u'y': 0}
            
    firefox
        default:
            顶部元素 底部元素
                location 不滚动,直接返回相对整个html的坐标 {'x': 15.0, 'y': 130.0}  {'x': 15.0, 'y': 707.0}
                location_once_scrolled_into_view 返回相对可视区域的坐标(y=1足以说明)
                                    可见不可见 都滚动到顶部对齐 {'x': 15.0, 'y': 1.0} {'x': 15.0, 'y': 1.0}
                                        如果下拉条直到底部,底部元素仍然无法顶部对齐 {'x': 15.0, 'y': 82.0}
        frame:
            location 不滚动,都是相对frame即当前相应html的坐标{'x': 255.0, 'y': 166.0}
            location_once_scrolled_into_view 可见不可见都会滚动到顶部对齐,('y'依旧是166.0)
                                                结果也是相对frame即当前相应html的坐标{'x': 255.0, 'y': 166.0}

2.总结

location
    始终不滚动,返回相对整个html或者对应frame的坐标
location_once_scrolled_into_view
    chrome完全可见不滚动,firefox始终会滚动;而且chrome底部元素会底部对齐,其余情况两者都是顶部对齐。
    一般返回相对可视区域坐标,但是firefox的frame依旧返回相对frame的坐标

3.应用

对浏览器可视区域截图后,截取某一frame的pic roi

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait

from PIL import Image
import numpy as np

WebDriverWait(driver, 5).until(lambda x: x.find_element_by_id('captcha_frame')) driver.switch_to.frame('captcha_frame') WebDriverWait(driver, 5).until(lambda x: x.find_element_by_xpath('//div[@class="captcha-list"]/div[last()]').is_displayed()) # 通过拼图的最后一块确认图片roi加载完毕 driver.switch_to.default_content() #处于frame截图,chrome为可视区域,firefox为当前frame,所以统一到default driver.execute_script("window.scrollTo(0,0)") driver.save_screenshot(pic1_path)

# 无论元素是否在可视区域,滚动条始终不动,返回相对整个html或者对应frame的坐标 {u'y': 225, u'x': 13} captcha_frame_abs_xy
= driver.find_element_by_id('captcha_frame').location

# 通过size确认roi的尺寸 {'height': 160, 'width': 300} 
elem_roi_full = driver.find_element_by_class_name('captcha-list')
roi_size_wh = elem_roi_full.size 

# 读取图形,灰度处理,转为numpy array
pic = Image.open(pic1_path)
pic_gray = pic.convert('L')   
pic_array = np.array(pic_gray)
# 截取pic roi,注意pic_array.shape为(h,w),firefox取得的location和size为小数 
pic_array = pic_array[int(captcha_frame_abs_xy['y']) : int(captcha_frame_abs_xy['y']+roi_size_wh['height']),
                            int(captcha_frame_abs_xy['x']) : int(captcha_frame_abs_xy['x']+roi_size_wh['width'])]
# 通过阈值二值化
pic_array = np.where(pic_array==255,255,0)
Image.fromarray(pic_array).save(pic_bilevel_path)

 

posted @ 2017-07-23 17:58  my8100  阅读(16943)  评论(0编辑  收藏  举报