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()
这个代码是好的,可以截下百度首页的图片,但是设计的关键词输入搜索框里的功能没有实
最新发布