python+selenium对元素进行截图以及截图产生偏差问题

佐手、 提交于 2020-03-04 18:11:07
原理:
1.截图(整个窗口)
2.获取此元素坐标
element = driver.find_element_by_id("xx")
element.location)
3.获取此元素大小
element = driver.find_element_by_id("xx")
element.size
4.根据元素坐标和元素大小确定此元素四个角坐标
5.依赖pillow,根据四角坐标crop((left, top, right, bottom)裁剪图片并保存

#! /usr/local/bin/python3
#coding=utf-8
import os,execjs
from PIL import Image
from time import sleep
from io import BytesIO
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.select import Select # 引入下拉框操作的类模块
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
def save_image(path,xpath):
try:
img=WebDriverWait(driver,20).until(EC.visibility_of_element_located((By.XPATH,xpath)))
sleep(2)
location = img.location
size = img.size
top, bottom, left, right = location['y'], location['y']+ size['height'], location['x'], location['x'] + size['width']
screenshot = driver.get_screenshot_as_png()
screenshot = Image.open(BytesIO(screenshot))
screenshot = screenshot.crop((left, top, right, bottom))
screenshot.save(path)
except:
pass
kw=input("输入要搜索的图片类型:")
driver = webdriver.Firefox()
browersize=driver.get_window_size()
browerH=browersize['height']
driver.get("http://www.baidu.com")
element = WebDriverWait(driver,2).until(EC.visibility_of_element_located((By.XPATH,'//div[@id="u1"]//a[@name="tj_settingicon"]')))
ActionChains(driver).move_to_element(element).perform()#鼠标调用滑向元素element显示新窗口元素div[@class="bdpfmenu"]//a[@target="_blank"]
WebDriverWait(driver,2).until(EC.visibility_of_element_located((By.XPATH,'//div[@class="bdpfmenu"]//a[@target="_blank"]')))
WebDriverWait(driver,2).until(EC.visibility_of_element_located((By.XPATH,"//a[contains(text(),'高级搜索')]"))).click()
WebDriverWait(driver,10).until(EC.visibility_of_element_located((By.XPATH,'//select[@name="ft"]')))
WebDriverWait(driver,2).until(EC.visibility_of_element_located((By.XPATH,'//input[@name="q1"]'))).send_keys(kw)
WebDriverWait(driver,2).until(EC.visibility_of_element_located((By.XPATH,'//option[text()="最近一年"]'))).click()
WebDriverWait(driver,2).until(EC.visibility_of_element_located((By.XPATH,'//input[@id="q5_0"]'))).click()
WebDriverWait(driver,2).until(EC.visibility_of_element_located((By.XPATH,'//input[@value="高级搜索"]'))).click()
windows=driver.window_handles# 页面跳转代码...打开新的窗口,句柄1
driver.switch_to.window(windows[-1])#原网页为句柄0,新网页为句柄加1
WebDriverWait(driver,2).until(EC.visibility_of_element_located((By.XPATH,'//a[text()="图片"]'))).click()
WebDriverWait(driver,2).until(EC.visibility_of_element_located((By.XPATH,'/html/body/div[1]/div[4]/div[2]/a[2]'))).click()
WebDriverWait(driver,4).until(EC.visibility_of_element_located((By.XPATH,'//a[@name="pn1"]'))).click()
windows=driver.window_handles
driver.switch_to.window(windows[-1])
xpath='//img[@id="currentImg"]'
if not os.path.exists('images/'+str(kw)+'/'):
os.makedirs('images/'+str(kw)+'/')
for i in range(1,200):
path=r'images/'+str(kw)+'/'+str(kw)+str(i)+".png"
print(i,end=' ')
save_image(path,xpath)
WebDriverWait(driver,12).until(EC.visibility_of_element_located((By.XPATH,"/html/body/div[1]/div[2]/div/span[2]/span"))).click()
if i % 10 == 0:
print()
driver.delete_all_cookies()
driver.quit()

如果该在网页中元素不可见,需拖动滚动条才能显示,截图就会产生偏差
解决方法1:
1.浏览器全屏显示 driver.fullscreen_window()
2.滚动条移动使元素element底端与页面底端对齐 driver.execute_script("arguments[0].scrollIntoView(false);",element)
3.由element = driver.find_element_by_id("xx") location=element.location top=location['y'],而crop()是由截的整个窗口图再进行裁剪的‘,
所以有一个偏差offset(如图2)
3.计算偏移量 offset=top+ elementH - browertH
解决方法2:
如果不是全屏,
1.计算浏览器工具栏的高度topH(js:topH=window.outerHeight - window.innerHeight)
2.得到偏移量方法1的基础上再加topH:即offset=top + elementH - browerH + topH

#! /usr/local/bin/python3
#coding=utf-8
import os
from PIL import Image
from time import sleep
from io import BytesIO
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.select import Select # 引入下拉框操作的类模块
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
def save_image(offset,path,xpath):
try:
img=WebDriverWait(driver,20).until(EC.visibility_of_element_located((By.XPATH,xpath)))#driver.find_element_by_xpath(xpath)
sleep(2)
location = img.location
size = img.size
top, bottom, left, right = location['y']-offset, location['y']-offset+ size['height'], location['x'], location['x'] + size['width']
screenshot = driver.get_screenshot_as_png()
screenshot = Image.open(BytesIO(screenshot))
screenshot = screenshot.crop((left, top, right, bottom))
screenshot.save(path)
except:
pass
kw=input("输入要搜索的图片类型:")
driver = webdriver.Firefox()
driver.maximize_window()
#driver.fullscreen_window()
driver.execute_script("""function gettopH()
{var topH=window.outerHeight - window.innerHeight;
alert("浏览器工具栏高度 ="+topH);
return topH;
}
gettopH()""")
sleep(4)
browersize=driver.get_window_size()
browerH=browersize['height']
driver.get("http://www.baidu.com")
element = WebDriverWait(driver,2).until(EC.visibility_of_element_located((By.XPATH,'//div[@id="u1"]//a[@name="tj_settingicon"]')))
#实例化ActionChains类 ,鼠标调用滑向元素element最后一定要用perform()才会有执行效果。
ActionChains(driver).move_to_element(element).perform()
#鼠标调用滑向元素element显示新窗口元素div[@class="bdpfmenu"]//a[@target="_blank"]
WebDriverWait(driver,2).until(EC.visibility_of_element_located((By.XPATH,'//div[@class="bdpfmenu"]//a[@target="_blank"]')))
WebDriverWait(driver,2).until(EC.visibility_of_element_located((By.XPATH,"//a[contains(text(),'高级搜索')]"))).click()
#等待新窗口元素select[@name="ft"]打开
WebDriverWait(driver,10).until(EC.visibility_of_element_located((By.XPATH,'//select[@name="ft"]')))
#1通过元素的方式进行定位点击选择下拉选项
WebDriverWait(driver,2).until(EC.visibility_of_element_located((By.XPATH,'//input[@name="q1"]'))).send_keys(kw)
#driver.find_element_by_xpath('//input[@name="q1"]').send_keys('兰花')
WebDriverWait(driver,2).until(EC.visibility_of_element_located((By.XPATH,'//option[text()="最近一年"]'))).click()
#driver.find_element_by_xpath('//select//option[@value="doc"]').click()
WebDriverWait(driver,2).until(EC.visibility_of_element_located((By.XPATH,'//input[@id="q5_0"]'))).click()
WebDriverWait(driver,2).until(EC.visibility_of_element_located((By.XPATH,'//input[@value="高级搜索"]'))).click()
# 页面跳转代码...
windows=driver.window_handles#打开新的第二个窗口,句柄1
driver.switch_to.window(windows[-1])#原网页为句柄0,新网页为句柄加1,多个类推
sreach_window=driver.current_window_handle
WebDriverWait(driver,2).until(EC.visibility_of_element_located((By.XPATH,'//a[text()="图片"]'))).click()
driver.find_element_by_xpath('//a[@name="pn1"]').click()
sleep(2)
windows=driver.window_handles
driver.switch_to.window(windows[-1])
sreach_window=driver.current_window_handle
xpath='//img[@id="currentImg"]'
if not os.path.exists('images/'+str(kw)+'/'):
os.makedirs('images/'+str(kw)+'/')
for i in range(1,20):
path='images/'+str(kw)+'/'+str(i)+".png"
print(i,end=" ")
save_image(0,path,xpath)
WebDriverWait(driver,12).until(EC.visibility_of_element_located((By.XPATH,"/html/body/div[1]/div[2]/div/span[2]/span"))).click()
if i % 10 == 0:
driver.delete_all_cookies()
WebDriverWait(driver,2).until(EC.visibility_of_element_located((By.XPATH,xpath))).click()
WebDriverWait(driver,2).until(EC.visibility_of_element_located((By.XPATH,xpath))).click()
windows=driver.window_handles#打开新的窗口
driver.switch_to.window(windows[-1])#原网页为句柄0,新网页为句柄1,多个类推
sreach_window=driver.current_window_handle
print(sreach_window,windows)
driver.get("http://blog.sina.com.cn/s/blog_a0e25fd70102x8mp.html")
sleep(2)
#driver.execute_script("var q=document.documentElement.scrollTop=100000")#滚动条横向不动,纵向移动到底部位置
driver.execute_script("window.scrollTo(0,928)") #滚动条横向不动,纵向移动高度为928位置
sleep(4)
element=WebDriverWait(driver,2).until(EC.visibility_of_element_located((By.XPATH,'//img[@src="http://p3.pstatp.com/large/8a000e10a540f5bf50"]')))
driver.execute_script("arguments[0].scrollIntoView(false);",element) #滚动条移动使元素底端与页面底端对齐
sleep(4)
ActionChains(driver).move_to_element(element).perform()#鼠标移动到此元素
sleep(2)
driver.switch_to.window(windows[0])
driver.close()
sleep(2)
driver.switch_to.window(windows[1])
driver.close()
sleep(2)
driver.switch_to.window(windows[2])
driver.close()
driver.switch_to.window(windows[-1])
sleep(2)
sreach_window=driver.current_window_handle
print(sreach_window,windows)
location=element.location
size=element.size
top,elementH=location['y'], size['height']
offset=top + elementH - browerH + 112
xpath='//img[@src="http://p3.pstatp.com/large/8a000e10a540f5bf50"]'
save_image(offset,'pic.png',xpath)
WebDriverWait(driver,2).until(EC.visibility_of_element_located((By.XPATH,'//img[@src="http://p3.pstatp.com/large/8a000e10a540f5bf50"]'))).click()
xpath='//img[@action-type="show-large-layer"]'
for i in range(1,95):
path=r'images/'+str(kw)+'/极品兰花'+str(i)+".png"
save_image(offset,path,xpath)
WebDriverWait(driver,10).until(EC.visibility_of_element_located((By.XPATH,'//a[@class="btn_next" ]'))).click()
driver.find_element_by_xpath('//a[text()="<<上一篇"]').click()
WebDriverWait(driver,10).until(EC.visibility_of_element_located((By.XPATH,'//a[@action-type="show-next-slide"]'))).click()
for i in range(1,25):
path=r'images/'+str(kw)+'/张家界'+str(i)+".png"
save_image(offset,path,xpath)
WebDriverWait(driver,10).until(EC.visibility_of_element_located((By.XPATH,'//a[@class="btn_next" ]'))).click()
driver.quit()

 driver.set_window_size(1920,1080)
driver.set_window_position(0,0)

river.execute_script("window.scrollTo(0, document.body.scrollHeight);")

 driver.execute_script('arguments[0].scrollIntoView(true);', total)

driver.execute_script("arguments[0].scrollIntoView(false);",element)

driver.execute_script("window.scrollTo(0,928)")

driver.execute_script("var q=document.documentElement.scrollTop=100000")

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!