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)