如何保存IE新窗口中打开的PDF?Selenium技术实现求助
银行应用内嵌PDF保存解决方案
针对你遇到的场景,以下是几个可行的解决思路:
1. 精准控制Robot类的鼠标定位与停留
之前的失败可能是坐标精度不足或停留时间不够。需要先区分PDF是全屏显示还是在浏览器窗口内,再计算目标坐标:
- 若为全屏:通过屏幕尺寸计算底部区域坐标,停留足够时间触发保存按钮
- 若在浏览器窗口内:先用Selenium获取窗口位置与尺寸,计算窗口内的底部相对坐标
示例代码:
Robot robot = new Robot(); // 获取浏览器窗口的位置和尺寸 Rectangle windowRect = driver.manage().window().getRect(); int targetX = windowRect.x + windowRect.width / 2; // 窗口水平居中 int targetY = windowRect.y + (int)(windowRect.height * 0.95); // 窗口底部区域 // 移动鼠标到目标位置 robot.mouseMove(targetX, targetY); robot.delay(2000); // 等待保存按钮加载完成 // 点击保存按钮(若按钮位置有偏移,微调targetX/targetY即可) robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
2. 模拟真实鼠标平滑移动轨迹
部分银行应用会检测鼠标是否为自然移动,瞬间跳转可能被判定为自动化工具。可以编写方法模拟逐步移动:
public void smoothMouseMove(Robot robot, int startX, int startY, int endX, int endY) throws InterruptedException { int steps = 50; int deltaX = (endX - startX) / steps; int deltaY = (endY - startY) / steps; for (int i = 0; i < steps; i++) { robot.mouseMove(startX + deltaX * i, startY + deltaY * i); Thread.sleep(10); // 每步间隔10ms,模拟自然移动 } // 最后一步精准定位到目标点 robot.mouseMove(endX, endY); }
调用该方法后再停留等待按钮出现,能提升触发成功率。
3. 触发容器hover事件的多位置移动
若PDF嵌入自定义容器,单纯停留可能无法触发hover事件。可在底部区域做小范围往复移动,强制触发容器的交互检测:
int baseX = windowRect.x + windowRect.width / 2; int baseY = windowRect.y + (int)(windowRect.height * 0.95); // 在底部区域左右小范围移动3次 for (int i = 0; i < 3; i++) { robot.mouseMove(baseX - 10, baseY); robot.delay(100); robot.mouseMove(baseX + 10, baseY); robot.delay(100); } // 回到中心位置等待按钮出现 robot.mouseMove(baseX, baseY); robot.delay(2000);
4. 字节流捕获替代方案(优先尝试)
若能获取PDF的真实请求地址,可跳过UI操作直接保存字节流:
- 用
driver.getCurrentUrl()获取当前窗口的PDF链接 - 带上当前会话的Cookie发起请求,保持登录状态
- 将响应流写入本地文件
示例代码:
String pdfUrl = driver.getCurrentUrl(); URL url = new URL(pdfUrl); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); // 传递当前会话的Cookie,确保权限 String cookies = driver.manage().getCookies().stream() .map(c -> c.getName() + "=" + c.getValue()) .collect(Collectors.joining("; ")); conn.setRequestProperty("Cookie", cookies); // 保存字节流到本地 InputStream in = conn.getInputStream(); Files.copy(in, Paths.get("bank_document.pdf"), StandardCopyOption.REPLACE_EXISTING); // 关闭资源 in.close(); conn.disconnect();
内容的提问来源于stack exchange,提问作者Vinoth Ramasamy
相关产品推荐
相关产品推荐

