Webdriver中实现区域截图的方式以及如何截取frame中的图片

本文介绍了一种使用Java实现的针对特定网页元素进行截图的方法。通过定位元素的位置和尺寸,结合浏览器截图功能,精确裁剪出所需元素的图像,并保存到指定路径。

import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.Point;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
public class ScreenShot {
    public  void screenShotForElement(WebDriver driver,WebElement element, String path,int x,int y) throws InterruptedException {
        //截取整个页面的图片
        File scrFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
        try {
            //获取元素在所处frame中位置对象
            Point p = element.getLocation();
            //获取元素的宽与高
            int width = element.getSize().getWidth();
            int height = element.getSize().getHeight();
            //矩形图像对象
            Rectangle rect = new Rectangle(width, height);
            BufferedImage img = ImageIO.read(scrFile);
            //x、y表示加上当前frame的左边距,上边距
            BufferedImage dest = img.getSubimage(p.getX()+x, p.getY()+y,rect.width, rect.height);
            ImageIO.write(dest, "png", scrFile);
            FileUtils.copyFile(scrFile, new File(path));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

转载于:https://www.cnblogs.com/zw520ly/p/5875546.html

import os import sys import time import threading import tkinter as tk from tkinter import filedialog, messagebox, ttk from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.chrome.options import Options from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By from selenium.webdriver.common.keys import Keys import winreg import subprocess # ===== 辅助函数 ===== def find_chromedriver(): """自动查找ChromeDriver""" # 检查当前目录 if os.path.exists("chromedriver.exe"): return os.path.abspath("chromedriver.exe") # 检查PATH环境变量 for path in os.environ["PATH"].split(os.pathsep): driver_path = os.path.join(path, "chromedriver.exe") if os.path.exists(driver_path): return driver_path # 检查Chrome安装路径 try: key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\chrome.exe") chrome_path = winreg.QueryValue(key, None) chrome_dir = os.path.dirname(chrome_path) driver_path = os.path.join(chrome_dir, "chromedriver.exe") if os.path.exists(driver_path): return driver_path except: pass # 检查默认安装位置 paths = [ r"C:\Program Files\Google\Chrome\Application\chromedriver.exe", r"C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe", os.path.expanduser(r"~\AppData\Local\Google\Chrome\Application\chromedriver.exe") ] for path in paths: if os.path.exists(path): return path return None # ===== 增强版截图类 ===== class EnhancedScreenshot: def __init__(self, driver_path): self.driver_path = driver_path self.options = self._configure_options() self.cookies = {} def _configure_options(self): """配置浏览器选项""" options = Options() options.add_argument("--headless=new") options.add_argument("--disable-gpu") options.add_argument("--no-sandbox") options.add_argument("--disable-dev-shm-usage") options.add_argument("--window-size=1920,1080") options.add_argument("--force-device-scale-factor=1") options.add_argument("--disable-blink-features=AutomationControlled") options.add_argument("--lang=zh-CN") options.add_experimental_option("excludeSwitches", ["enable-automation"]) options.add_experimental_option('useAutomationExtension', False) # 禁用图片加载加速截图 prefs = {"profile.managed_default_content_settings.images": 2} options.add_experimental_option("prefs", prefs) return options def perform_login(self, driver, username, password, login_url): """执行登录操作""" try: driver.get(login_url) # 等待登录表单出现 WebDriverWait(driver, 15).until( EC.presence_of_element_located((By.CSS_SELECTOR, "input[type='password'], input[name='password']")) ) # 查找用户名和密码输入框 username_fields = driver.find_elements( By.CSS_SELECTOR, "input[type='text'], input[type='email'], input[name='username'], input[name='user'], input[name='email']" ) password_fields = driver.find_elements( By.CSS_SELECTOR, "input[type='password'], input[name='password'], input[name='pass']" ) if username_fields and password_fields: # 输入凭据 username_fields[0].clear() username_fields[0].send_keys(username) password_fields[0].clear() password_fields[0].send_keys(password) # 查找并点击登录按钮 login_buttons = driver.find_elements( By.CSS_SELECTOR, "button[type='submit'], input[type='submit'], .login-btn, .submit-btn" ) if login_buttons: login_buttons[0].click() else: # 如果没有按钮,尝试回车登录 password_fields[0].send_keys(Keys.RETURN) # 等待登录完成 WebDriverWait(driver, 10).until( lambda d: d.current_url != login_url or "登录成功" in d.page_source ) # 保存cookies self.cookies = driver.get_cookies() return True, "登录成功" else: return False, "未找到登录表单" except Exception as e: return False, f"登录失败: {str(e)}" def perform_search(self, driver, search_term): """在页面执行搜索操作""" try: # 尝试查找搜索框 search_selectors = [ "input[type='search']", "input[name='q']", "input[title='搜索']", ".search-input", "#search", "#searchbox", "#searchInput" ] for selector in search_selectors: search_boxes = driver.find_elements(By.CSS_SELECTOR, selector) if search_boxes: search_box = search_boxes[0] search_box.clear() search_box.send_keys(search_term) search_box.send_keys(Keys.RETURN) # 等待搜索结果加载 WebDriverWait(driver, 15).until( EC.presence_of_element_located(( By.CSS_SELECTOR, ".search-results, .result, .s-result-item, .srp, .g" )) ) time.sleep(1.5) # 额外等待 return True, "搜索成功" return False, "未找到搜索框" except Exception as e: return False, f"搜索失败: {str(e)}" def capture(self, url, username=None, password=None, login_url=None, search_term=None): """执行截图操作(支持登录和搜索)""" try: service = Service( executable_path=self.driver_path, service_args=['--log-level=OFF'] ) driver = webdriver.Chrome(service=service, options=self.options) # 绕过自动化检测 driver.execute_cdp_cmd( "Page.addScriptToEvaluateOnNewDocument", { "source": """ Object.defineProperty(navigator, 'webdriver', { get: () => undefined }); window.chrome = { runtime: {} }; """ } ) # 步骤1:登录操作(如果需要) if username and password and login_url: login_success, login_msg = self.perform_login(driver, username, password, login_url) if not login_success: return None, f"登录失败: {login_msg}" # 步骤2:导航到目标URL driver.get(url) # 步骤3:执行搜索(如果需要) if search_term: search_success, search_msg = self.perform_search(driver, search_term) if not search_success: return None, f"搜索失败: {search_msg}" # 等待页面加载 WebDriverWait(driver, 20).until( EC.presence_of_element_located((By.TAG_NAME, "body")) ) WebDriverWait(driver, 10).until( lambda d: d.execute_script("return document.readyState") == "complete" ) # 滚动加载动态内容 driver.execute_script(""" // 增强版滚动加载 const scrollHeight = document.body.scrollHeight; const viewportHeight = window.innerHeight; let currentPosition = 0; const scrollStep = viewportHeight * 0.7; function smoothScroll() { if (currentPosition < scrollHeight) { window.scrollTo(0, currentPosition); currentPosition += scrollStep; setTimeout(smoothScroll, 300); } else { window.scrollTo(0, 0); } } smoothScroll(); """) time.sleep(2.5) # 等待滚动完成 # 检查关键元素渲染 driver.execute_script(""" // 强制渲染常见元素 const elementsToRender = [ 'input[type="search"]', '.search-box', '.main-content', '#content' ]; elementsToRender.forEach(selector => { const elements = document.querySelectorAll(selector); elements.forEach(el => { el.style.display = 'block'; if (el.offsetHeight === 0) { el.scrollIntoView({behavior: 'auto', block: 'center'}); } }); }); """) time.sleep(0.5) return driver.get_screenshot_as_png(), None except Exception as e: return None, str(e) finally: try: driver.quit() except: pass # ===== 增强版GUI界面 ===== class EnhancedScreenshotApp: def __init__(self, root): self.root = root root.title("网页截图工具 v2.0") root.geometry("700x600") root.configure(bg="#f0f0f0") # 设置图标(如果存在) try: root.iconbitmap("screenshot_icon.ico") except: pass # 创建选项卡 self.notebook = ttk.Notebook(root) self.notebook.pack(fill='both', expand=True, padx=10, pady=10) # 基本设置选项卡 self.basic_frame = ttk.Frame(self.notebook, padding=10) self.notebook.add(self.basic_frame, text="基本设置") self.create_basic_widgets(self.basic_frame) #!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 精简版网页截图工具 v2.0 功能:登录模块 + 搜索模块 + 智能渲染 """ import os import time import threading import tkinter as tk from tkinter import filedialog, messagebox, ttk from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.chrome.options import Options from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.keys import Keys class ScreenshotTool: def __init__(self, root): self.root = root root.title("网页截图工具") root.geometry("650x550") # 创建主框架 main_frame = ttk.Frame(root, padding=15) main_frame.pack(fill='both', expand=True) # URL输入 url_frame = ttk.Frame(main_frame) url_frame.pack(fill='x', pady=10) ttk.Label(url_frame, text="目标网址:").pack(side='left') self.url_entry = ttk.Entry(url_frame, width=50) self.url_entry.pack(side='left', padx=5) self.url_entry.insert(0, "https://www.baidu.com") # 登录模块 login_frame = ttk.LabelFrame(main_frame, text="登录设置") login_frame.pack(fill='x', pady=10) # 登录URL ttk.Label(login_frame, text="登录页面:").grid(row=0, column=0, sticky='w', pady=5) self.login_url_entry = ttk.Entry(login_frame, width=45) self.login_url_entry.grid(row=0, column=1, padx=5, pady=5) # 用户名 ttk.Label(login_frame, text="用户名:").grid(row=1, column=0, sticky='w', pady=5) self.user_entry = ttk.Entry(login_frame, width=20) self.user_entry.grid(row=1, column=1, padx=5, pady=5, sticky='w') # 密码 ttk.Label(login_frame, text="密码:").grid(row=2, column=0, sticky='w', pady=5) self.pwd_entry = ttk.Entry(login_frame, width=20, show="*") self.pwd_entry.grid(row=2, column=1, padx=5, pady=5, sticky='w') # 搜索模块 search_frame = ttk.LabelFrame(main_frame, text="搜索设置") search_frame.pack(fill='x', pady=10) ttk.Label(search_frame, text="搜索关键词:").grid(row=0, column=0, sticky='w', pady=5) self.search_entry = ttk.Entry(search_frame, width=45) self.search_entry.grid(row=0, column=1, padx=5, pady=5) # 驱动设置 driver_frame = ttk.Frame(main_frame) driver_frame.pack(fill='x', pady=10) ttk.Label(driver_frame, text="驱动路径:").pack(side='left') self.driver_entry = ttk.Entry(driver_frame, width=40) self.driver_entry.pack(side='left', padx=5) ttk.Button(driver_frame, text="浏览", command=self.browse_driver).pack(side='left') # 截图按钮 self.capture_btn = ttk.Button(main_frame, text="开始截图", command=self.start_capture, width=15) self.capture_btn.pack(pady=15) # 状态栏 self.status = ttk.Label(root, text="就绪", anchor='w', relief='sunken') self.status.pack(fill='x', side='bottom', ipady=5) # 自动检测驱动 self.auto_detect_driver() def browse_driver(self): """浏览选择驱动""" file = filedialog.askopenfilename(title="选择Chrome驱动", filetypes=[("可执行文件", "*.exe")]) if file: self.driver_entry.delete(0, tk.END) self.driver_entry.insert(0, file) def auto_detect_driver(self): """自动检测驱动路径(简化实现)""" common_paths = [ "chromedriver.exe", "C:/Program Files/Google/Chrome/Application/chromedriver.exe", "C:/Program Files (x86)/Google/Chrome/Application/chromedriver.exe" ] for path in common_paths: if os.path.exists(path): self.driver_entry.delete(0, tk.END) self.driver_entry.insert(0, os.path.abspath(path)) return self.status.config(text="警告: 未检测到驱动,请手动选择") def start_capture(self): """启动截图线程""" url = self.url_entry.get().strip() driver_path = self.driver_entry.get() login_url = self.login_url_entry.get().strip() username = self.user_entry.get().strip() password = self.pwd_entry.get().strip() search_term = self.search_entry.get().strip() # 验证输入 if not url.startswith("http"): messagebox.showerror("错误", "请输入有效的URL (以http/https开头)") return if not os.path.exists(driver_path): messagebox.showerror("错误", "驱动路径无效或文件不存在") return # 准备线程 self.capture_btn.config(state=tk.DISABLED, text="截图中...") self.status.config(text=f"开始截图: {url}") threading.Thread( target=self.capture_thread, args=(url, driver_path, login_url, username, password, search_term), daemon=True ).start() def capture_thread(self, url, driver_path, login_url, username, password, search_term): """截图线程核心逻辑""" try: # 配置浏览器选项 options = Options() options.add_argument("--headless=new") options.add_argument("--window-size=1920,1080") options.add_argument("--disable-gpu") options.add_argument("--no-sandbox") options.add_argument("--force-device-scale-factor=1") options.add_experimental_option("excludeSwitches", ["enable-automation"]) # 创建浏览器实例 service = Service(executable_path=driver_path) driver = webdriver.Chrome(service=service, options=options) # 绕过自动化检测 driver.execute_cdp_cmd( "Page.addScriptToEvaluateOnNewDocument", { "source": """Object.defineProperty(navigator, 'webdriver', {get: () => undefined});""" } ) # 登录流程 if login_url and username and password: try: driver.get(login_url) # 等待登录表单 WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CSS_SELECTOR, "input[type='password']")) ) # 查找输入框 user_inputs = driver.find_elements(By.CSS_SELECTOR, "input[type='text'], input[type='email']") pwd_inputs = driver.find_elements(By.CSS_SELECTOR, "input[type='password']") if user_inputs and pwd_inputs: user_inputs[0].send_keys(username) pwd_inputs[0].send_keys(password) pwd_inputs[0].send_keys(Keys.RETURN) time.sleep(2) except Exception as e: self.update_status(f"登录失败: {str(e)}", "red") # 导航到目标页面 driver.get(url) time.sleep(2) # 搜索流程 if search_term: try: search_boxes = driver.find_elements(By.CSS_SELECTOR, "input[type='search'], input[name='q']") if search_boxes: search_boxes[0].send_keys(search_term) search_boxes[0].send_keys(Keys.RETURN) time.sleep(2) except: pass # 智能滚动 driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") time.sleep(1) driver.execute_script("window.scrollTo(0, 0);") time.sleep(0.5) # 保存截图 desktop = os.path.expanduser("~/Desktop") filename = f"screenshot_{time.strftime('%Y%m%d_%H%M%S')}.png" save_path = os.path.join(desktop, filename) driver.save_screenshot(save_path) self.update_status(f"截图成功: {save_path}", "green") os.startfile(save_path) except Exception as e: self.update_status(f"截图失败: {str(e)}", "red") finally: try: driver.quit() except: pass self.root.after(0, lambda: self.capture_btn.config(state=tk.NORMAL, text="开始截图")) def update_status(self, message, color="black"): """更新状态栏""" self.root.after(0, lambda: self.status.config(text=message, foreground=color)) # 启动应用 if __name__ == "__main__": try: from selenium import webdriver except ImportError: print("错误: 请先安装selenium - pip install selenium") sys.exit(1) root = tk.Tk() app = ScreenshotTool(root) root.mainloop() 这个代码是好的,可以截下百度首页的图片,但是设计的关键词输入搜索框里的功能没有实
最新发布
08-30
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值