Commit 025a4e15 authored by shanglipeng's avatar shanglipeng

代码完善

parent f6bd2d52
"/Google/Chrome/Application/chrome.exe" --remote-debugging-port=9222 --user-data-dir="c:/selenium/ChromeProfile" --allow-pre-commit-input --disable-background-networking --disable-backgrounding-occluded-windows --disable-client-side-phishing-detection --disable-default-apps --disable-hang-monitor --disable-infobars --disable-popup-blocking --disable-prompt-on-repost --disable-sync --enable-blink-features=ShadowDOMV0 --enable-logging --ignore-certificate-errors --log-level=3 --no-service-autorun --password-store=basic --start-maximized --test-type --use-mock-keychain --flag-switches-begin --flag-switches-end
\ No newline at end of file
package com.greatchn;
import com.greatchn.kits.ChromeKits;
import com.greatchn.yzh.TaskExecutor;
/**
......@@ -9,7 +10,9 @@ import com.greatchn.yzh.TaskExecutor;
* @since 1.0.0
*/
public class Main {
public static void main(String[] args) {
public static void main(String[] args) throws Exception {
ChromeKits.killBrowser();
ChromeKits.utilBrowserStart("./files/chrome_no_proxy.bat");
new TaskExecutor();
}
}
\ No newline at end of file
......@@ -76,7 +76,7 @@ public abstract class BaseEtax {
return this.config;
}
protected RpaCore rpa() {
public RpaCore rpa() {
return this.rpa;
}
......
package com.greatchn.kits;
import org.apache.commons.lang3.StringUtils;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Date;
public class ChromeKits {
public static void killBrowser(){
ProcessKits.killProcess(Arrays.asList( "firefox","geckodriver","crashreporter","chromedriver","chrome"));
}
//创建浏览器
public static String utilBrowserStart(String batPath) throws Exception
{
Runtime rt = Runtime.getRuntime();
try
{
Process process = rt.exec(new File(batPath).getAbsolutePath());
// 获取启动返回信息
InputStreamReader isr = new InputStreamReader(process.getErrorStream());
BufferedReader br = new BufferedReader(isr);
long startTime = new Date().getTime();
String browserWs = "";
while (true)
{
if (new Date().getTime() - startTime >= 60000*2)
{
break;
}
browserWs = br.readLine();
if (browserWs != null && browserWs.startsWith("DevTools"))
{
browserWs = browserWs.substring(browserWs.indexOf("ws:"));
break;
}
else
{
Thread.sleep(100);
}
}
if (StringUtils.isEmpty(browserWs))
{
throw new RuntimeException("初始化chrome失败");
}
System.out.println(browserWs);
return browserWs;
}
catch (Exception e)
{
throw e;
}
}
}
package com.greatchn.kits;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.MessageFormat;
import java.util.List;
public class ProcessKits
{
/**
* 判断指定进程是否存在
*
* @param processName
* @return
*/
public static Boolean isProcessExist(String processName)
{
try
{
String os = System.getProperty("os.name");
if (os.toLowerCase().startsWith("win"))
{
return isWindowsProcessExist(processName);
}
if (os.toLowerCase().startsWith("lin"))
{
return isLunuxProcessExist(processName);
}
else
{
return false;
}
}
catch (Exception e)
{
return false;
}
}
public static boolean isLunuxProcessExist(String processName)
{
BufferedReader bufferedReader = null;
try
{
Process proc = Runtime.getRuntime().exec("ps -e");
bufferedReader = new BufferedReader(new InputStreamReader(proc.getInputStream()));
String line = null;
while ((line = bufferedReader.readLine()) != null)
{
if (line.contains(processName)) // 判断是否存在
{
return true;
}
}
return false;
}
catch (Exception ex)
{
ex.printStackTrace();
return false;
}
finally
{
if (bufferedReader != null)
{
try
{
bufferedReader.close();
}
catch (Exception ex)
{
}
}
}
}
public static boolean isWindowsProcessExist(String processName)
{
BufferedReader bufferedReader = null;
try
{
String cmd = MessageFormat.format("{0}\\system32\\tasklist.exe",System.getenv("windir"));
Process proc = Runtime.getRuntime().exec(cmd);
bufferedReader = new BufferedReader(new InputStreamReader(proc.getInputStream()));
String line = null;
while ((line = bufferedReader.readLine()) != null)
{
System.out.println(line);
if (line.contains(processName)) // 判断是否存在
{
return true;
}
}
return false;
}
catch (Exception ex)
{
ex.printStackTrace();
return false;
}
finally
{
if (bufferedReader != null)
{
try
{
bufferedReader.close();
}
catch (Exception ex)
{
}
}
}
}
public static Boolean startProcess(List<String> exeFileFullPathNameList)
{
try
{
String os = System.getProperty("os.name");
if (os.toLowerCase().startsWith("win"))
{
startWindowsProcess(exeFileFullPathNameList);
}
if (os.toLowerCase().startsWith("lin"))
{
startLinuxProcess(exeFileFullPathNameList);
}
else
{
return false;
}
return true;
}
catch (Exception e)
{
// TODO: handle exception
e.printStackTrace();
return false;
}
}
private static void startWindowsProcess(List<String> exeFileFullPathNameList)
{
try
{
Runtime runtime = Runtime.getRuntime();
for (String string : exeFileFullPathNameList)
{
runtime.exec(string);
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
private static void startLinuxProcess(List<String> exeFileFullPathNameList)
{
try
{
// 如果是 linux系统
for (String processName : exeFileFullPathNameList)
{
// String commandString = MessageFormat.format("ps -ef | grep {0} | grep -v grep | awk '''{'print $2'}''' | xargs kill -9", processName);
System.out.println(processName);
// 当需要执行的linux命令带有管道符时(例如:ps -ef|grep java),用上面的方法是不行的,解决方式是将需要执行的命令作为参数传给shell
String[] cmds = { "/bin/sh", "-c", processName };
Runtime.getRuntime().exec(cmds);
}
}
catch (Exception e)
{
// TODO: handle exception
e.printStackTrace();
}
}
/**
* 根据进程名称集合结束进程
*
* @param processNameList
* 进程名称集合 例如firefox,chrome 不带后缀
* @return
*/
public static Boolean killProcess(List<String> processNameList)
{
try
{
String os = System.getProperty("os.name");
if (os.toLowerCase().startsWith("win"))
{
killWindowsProcess(processNameList);
}
if (os.toLowerCase().startsWith("lin"))
{
killLinuxProcess(processNameList);
}
else
{
return false;
}
return true;
}
catch (Exception e)
{
// TODO: handle exception
e.printStackTrace();
return false;
}
}
/**
* 在windows环境下根据进程名称结束进程
*
* @param processNameList
* 进程名称集合
*/
private static void killWindowsProcess(List<String> processNameList)
{
try
{
// 如果是 windows系统
for (String processName : processNameList)
{
// String commandString=MessageFormat.format("taskkill /f /IM phantomjs.exe", arg1)
String commandString = MessageFormat.format("taskkill /f /IM {0}.exe", processName);
Runtime.getRuntime().exec(commandString);
}
}
catch (Exception e)
{
// TODO: handle exception
e.printStackTrace();
}
}
/**
* 在Linux环境下根据进程名称结束进程
*
* @param processNameList
* 进程名称集合
*/
private static void killLinuxProcess(List<String> processNameList)
{
try
{
// 如果是 linux系统
for (String processName : processNameList)
{
String commandString = MessageFormat.format("ps -ef | grep {0} | grep -v grep | awk '''{'print $2'}''' | xargs kill -9", processName);
System.out.println(commandString);
// 当需要执行的linux命令带有管道符时(例如:ps -ef|grep java),用上面的方法是不行的,解决方式是将需要执行的命令作为参数传给shell
String[] cmds = { "/bin/sh", "-c", commandString };
Runtime.getRuntime().exec(cmds);
}
}
catch (Exception e)
{
// TODO: handle exception
e.printStackTrace();
}
}
}
package com.greatchn.rpa;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import com.fasterxml.jackson.databind.JsonNode;
import com.greatchn.kits.JacksonKits;
import com.greatchn.kits.RandomKits;
......@@ -13,22 +15,30 @@ import net.lightbody.bmp.client.ClientUtil;
import net.lightbody.bmp.core.har.Har;
import net.lightbody.bmp.proxy.CaptureType;
import org.apache.commons.lang3.StringUtils;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.v109.network.Network;
import org.openqa.selenium.devtools.v109.network.model.Response;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.text.MessageFormat;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
/**
* 自动化机器人对象,对 selenium 功能进行封装,方便后期使用
......@@ -78,6 +88,11 @@ public class RpaCore {
*/
private Point browserOffset;
private Thread heartThread = null;
private Map<String, Date> heartThreadCmd = new HashMap<>();
private final static String ENTER = "enter";
/* ------------------------- 构造方法 ------------------------- */
......@@ -87,11 +102,34 @@ public class RpaCore {
* @param config 配置参数
*/
public RpaCore(RpaConfig config) {
this.config = config;
this.scale = config.getScale();
if (config.getRpa().isAutoCreate()) {
this.create();
}
heartThread = new Thread(() -> {
while (true) {
try {
if (MapUtil.isEmpty(this.heartThreadCmd)) {
TimeUnit.SECONDS.sleep(1L);
continue;
}
// 获取回车命令
Date date = this.heartThreadCmd.get(ENTER);
if (date != null && System.currentTimeMillis() > date.getTime()) {
//发送回车命令
WinApi.enter();
this.clearCmd();
System.out.println(DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss") + " heartThread已执行WinApi.enter()");
}
} catch (Exception e) {
}
}
});
heartThread.start();
}
/* ------------------------- 核心对象处理 ------------------------- */
......@@ -146,30 +184,36 @@ public class RpaCore {
this.createProxy();
}
var options = new ChromeOptions();
options.addArguments(
"--start-maximized",
"disable-infobars",
"--test-type",
"--ignore-certificate-errors"
);
options.setExperimentalOption("excludeSwitches", new String[]{"enable-automation"});
options.setExperimentalOption("prefs", new HashMap<String, Boolean>(3) {
{
this.put("download.prompt_for_download", false);
this.put("download.directory_upgrade", false);
this.put("safebrowsing.enabled", false);
//自动启动浏览器
if (this.config.isRemoteDebugging() == false) {
//Logger.getLogger("org.openqa.selenium.devtools").setLevel(Level.OFF);
options.addArguments("--log-level=3");
options.addArguments("--start-maximized", "disable-infobars", "--test-type", "--ignore-certificate-errors");
options.setExperimentalOption("excludeSwitches", new String[]{"enable-automation", "enable-logging"});
options.setExperimentalOption("prefs", new HashMap<String, Boolean>(3) {
{
this.put("download.prompt_for_download", false);
this.put("download.directory_upgrade", false);
this.put("safebrowsing.enabled", false);
}
});
if (this.config.getRpa().isFullScreen()) {
options.addArguments("--kiosk");
}
});
if (this.config.getRpa().isFullScreen()) {
options.addArguments("--kiosk");
options.addArguments("--user-data-dir=/selenium/ChromeProfile");
}
//手动启动浏览器
if (this.config.isRemoteDebugging() == true) {
options.setExperimentalOption("debuggerAddress", this.config.getRemoteDebuggingIP() + ":" + this.config.getRemoteDebuggingPort());
}
//Mobo
if (this.config.getRpa().getProxy().isEnable()) {
var seleniumProxy = ClientUtil.createSeleniumProxy(proxy);
options.setCapability(CapabilityType.PROXY, seleniumProxy);
}
options.setCapability("acceptInsecureCerts", true);
var builder = new ChromeDriverService.Builder();
builder.usingDriverExecutable(this.config.getSelenium().getExe());
var service = builder.build();
......@@ -177,6 +221,17 @@ public class RpaCore {
if (this.config.getRpa().getCookies().isClean()) {
this.driver.manage().deleteAllCookies();
}
HashMap<String, Object> cdpCmd = new HashMap<String, Object>();
cdpCmd.put("source", """
(function() {
try {
window.alert = function() {}
window.confirm = function() {return true;}
} catch (e) {
}
})()
""");
Map<String, Object> tmp_res = driver.executeCdpCommand("Page.addScriptToEvaluateOnNewDocument", cdpCmd);
this.create = true;
}
......@@ -219,18 +274,32 @@ public class RpaCore {
* 开启一个新的监听集合
*/
public Har newHar() {
if (!this.config.getRpa().getProxy().isEnable()) {
throw new IllegalStateException("当前 Robot 对象没有开启网络代理!");
//Mobo模式开启
if (this.config.isNetworkProxy()==false) {
if (!this.config.getRpa().getProxy().isEnable()) {
throw new IllegalStateException("当前 Robot 对象没有开启网络代理!");
}
this.endHar();
return this.proxy.newHar(String.format("robot_har_%d", this.harCount.getAndAdd(DELTA)));
}
//chrome模式开启
else {
this.enableNetWork();
return null;
}
this.endHar();
return this.proxy.newHar(String.format("robot_har_%d", this.harCount.getAndAdd(DELTA)));
}
/**
* 结束当前网络监听集合
*/
public void stopHar() {
this.proxy.waitForQuiescence(QUIT_PERIOD, QUIT_PERIOD, TimeUnit.SECONDS);
if (this.config.isNetworkProxy()==false) {
this.proxy.waitForQuiescence(QUIT_PERIOD, QUIT_PERIOD, TimeUnit.SECONDS);
return;
}
else {
this.closeNetWork();
}
}
/**
......@@ -251,28 +320,32 @@ public class RpaCore {
* @return 监听响应
*/
public String listen(String uri, long timeout) {
final var outTime = System.currentTimeMillis() + timeout * 1000;
try {
while (true) {
var har = this.proxy.getHar();
for (var entry : har.getLog().getEntries()) {
if (!Objects.isNull(entry.getRequest())
&& entry.getRequest().getUrl().contains(uri)
&& !Objects.isNull(entry.getResponse())
&& entry.getResponse().getStatus() == 200) {
return entry.getResponse().getContent().getText();
//Mobo模式的network
if (this.config.isNetworkProxy()==false) {
final var outTime = System.currentTimeMillis() + timeout * 1000;
try {
while (true) {
var har = this.proxy.getHar();
for (var entry : har.getLog().getEntries()) {
if (!Objects.isNull(entry.getRequest()) && entry.getRequest().getUrl().contains(uri) && !Objects.isNull(entry.getResponse()) && entry.getResponse().getStatus() == 200) {
return entry.getResponse().getContent().getText();
}
}
if (System.currentTimeMillis() > outTime) {
throw new TimeoutException(String.format("监听 %s 的响应超时;", uri));
}
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException ignored) {
}
}
if (System.currentTimeMillis() > outTime) {
throw new TimeoutException(String.format("监听 %s 的响应超时;", uri));
}
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException ignored) {
}
} finally {
this.stopHar();
}
} finally {
this.stopHar();
}
//chrome的network
else{
return this.listenNetWorkCenter(uri,timeout*1000L);
}
}
......@@ -332,12 +405,17 @@ public class RpaCore {
* @param url 页面 URL
*/
public void visit(String url) {
this.driver.get(url);
// 计算浏览器右下角位置
var x = this.driver.executeScript("return window.outerWidth - window.innerWidth");
var y = this.driver.executeScript("return window.outerHeight - window.innerHeight");
if (x instanceof Number pX && y instanceof Number pY) {
browserOffset = new Point(pX.doubleValue() * this.scale, pY.doubleValue() * this.scale);
try {
this.driver.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(30));
this.driver.get(url);
// 计算浏览器右下角位置
var x = this.driver.executeScript("return window.outerWidth - window.innerWidth");
var y = this.driver.executeScript("return window.outerHeight - window.innerHeight");
if (x instanceof Number pX && y instanceof Number pY) {
browserOffset = new Point(pX.doubleValue() * this.scale, pY.doubleValue() * this.scale);
}
} catch (org.openqa.selenium.TimeoutException e) {
this.executeJavaScript("window.stop()", Objects.class);
}
}
......@@ -581,31 +659,14 @@ public class RpaCore {
""", String.class), Point.class);
assert result != null;
var leftTopOffset = new Point(
this.browserOffset.x() + result.x() * this.scale,
this.browserOffset.y() + result.y() * this.scale
);
var elementRect = JacksonKits.toJsonNode(
this.executeJavaScript("return JSON.stringify(arguments[0].getBoundingClientRect())", String.class, element)
);
var lt = new Point(
(leftTopOffset.x() + this.readFromJsonNode(elementRect, "left")) * this.scale,
(leftTopOffset.y() + this.readFromJsonNode(elementRect, "top")) * this.scale
);
var rt = new Point(
(leftTopOffset.x() + this.readFromJsonNode(elementRect, "right")) * this.scale,
(leftTopOffset.y() + this.readFromJsonNode(elementRect, "top")) * this.scale
);
var rb = new Point(
(leftTopOffset.x() + this.readFromJsonNode(elementRect, "right")) * this.scale,
(leftTopOffset.y() + this.readFromJsonNode(elementRect, "bottom")) * this.scale
);
var lb = new Point(
(leftTopOffset.x() + this.readFromJsonNode(elementRect, "left")) * this.scale,
(leftTopOffset.y() + this.readFromJsonNode(elementRect, "bottom")) * this.scale
);
var leftTopOffset = new Point(this.browserOffset.x() + result.x() * this.scale, this.browserOffset.y() + result.y() * this.scale);
var elementRect = JacksonKits.toJsonNode(this.executeJavaScript("return JSON.stringify(arguments[0].getBoundingClientRect())", String.class, element));
var lt = new Point((leftTopOffset.x() + this.readFromJsonNode(elementRect, "left")) * this.scale, (leftTopOffset.y() + this.readFromJsonNode(elementRect, "top")) * this.scale);
var rt = new Point((leftTopOffset.x() + this.readFromJsonNode(elementRect, "right")) * this.scale, (leftTopOffset.y() + this.readFromJsonNode(elementRect, "top")) * this.scale);
var rb = new Point((leftTopOffset.x() + this.readFromJsonNode(elementRect, "right")) * this.scale, (leftTopOffset.y() + this.readFromJsonNode(elementRect, "bottom")) * this.scale);
var lb = new Point((leftTopOffset.x() + this.readFromJsonNode(elementRect, "left")) * this.scale, (leftTopOffset.y() + this.readFromJsonNode(elementRect, "bottom")) * this.scale);
return new Rectangle(lt, rt, rb, lb);
}
......@@ -820,10 +881,7 @@ public class RpaCore {
*/
public void moveTo(WebElement element, MoveDirection direction) {
var rect = this.sumElementRectangle(element);
var point = new Point(
(rect.leftTop().x() + rect.rightBottom().x()) / 2,
(rect.leftTop().y() + rect.rightBottom().y()) / 2
);
var point = new Point((rect.leftTop().x() + rect.rightBottom().x()) / 2, (rect.leftTop().y() + rect.rightBottom().y()) / 2);
this.moveTo(point, direction);
}
......@@ -862,6 +920,36 @@ public class RpaCore {
WinApi.dragTo(point.x(), point.y(), duration);
}
/**
* 使用selenium方式拖拽元素一定的偏移距离
* @param dragHandler
* @param xoffset
*/
public void dragCenter(WebElement dragHandler, int xoffset) {
this.resetInputState();
Actions action = new Actions(this.driver);
action.moveToElement(dragHandler).clickAndHold().build().perform();
int currentOffset = 0;
int setp = 10;
while (true) {
action = new Actions(this.driver);
action.moveByOffset(setp, 0).build().perform();
currentOffset += setp;
if (currentOffset >= xoffset) {
break;
}
this.sleep(1);
}
action = new Actions(this.driver);
action.release().build().perform();
}
public void drag(WebElement dragHandler, WebElement dragHandlerContiner){
// Rectangle handlerRect = this.sumElementRectangle(dragHandlerContiner);
int xoffset=dragHandlerContiner.getRect().width;
this.dragCenter(dragHandler,xoffset);
}
/* ------------------------- 辅助方法 ------------------------- */
/**
......@@ -924,5 +1012,179 @@ public class RpaCore {
WinApi.delay(ms);
}
public boolean isAlertPersent() {
try {
this.driver.switchTo().alert();
return true;
} catch (Exception e) {
return false;
}
}
public String getAlert() {
String currentWindowHandle = this.getCurrentWindowHandle();
Alert alert = this.driver.switchTo().alert();
String text = alert.getText();
alert.accept();
this.switchWindow(currentWindowHandle);
return text;
}
public void acceptAlert() {
String currentWindowHandle = this.getCurrentWindowHandle();
Alert alert = this.driver.switchTo().alert();
alert.accept();
this.switchWindow(currentWindowHandle);
}
public void sendEnterCmd(int offsetMiliSeconds) {
System.out.println(DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss") + "driver 已发送 enter");
Date exeDate = new Date(System.currentTimeMillis() + offsetMiliSeconds);
//发送命令
this.heartThreadCmd.put(ENTER, exeDate);
//尝试点击alert
if (this.isAlertPersent()) {
this.acceptAlert();
}
System.out.println(DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss") + "driver 已经清空 enter");
this.clearCmd();
}
public void clearCmd() {
this.heartThreadCmd.clear();
}
public Set<String> getWindowHandles() {
try {
return this.driver.getWindowHandles();
} catch (Exception e) {
return null;
}
}
public String getCurrentWindowHandle() {
try {
return this.driver.getWindowHandle();
} catch (Exception e) {
return "";
}
}
public void switchWindow(String nameOrHandle) {
try {
this.driver.switchTo().window(nameOrHandle);
} catch (Exception e) {
throw e;
}
}
private ConcurrentHashMap<String, String> networkMap = new ConcurrentHashMap<>();
public void enableNetWork() {
//开启监听
DevTools devTools = this.driver.getDevTools();
devTools.createSession();
devTools.send(Network.enable(Optional.empty(), Optional.empty(), Optional.empty()));
//增加全部的请求
devTools.addListener(Network.responseReceived(), res -> {
try {
networkMap.put(res.getResponse().getUrl(), devTools.send(Network.getResponseBody(res.getRequestId())).getBody());
}
catch (Exception ex){
}
});
}
public String listenNetWorkCenter(String matchUrl, Long timeoutMs) {
try {
Date startTime = new Date();
while (true) {
for (Map.Entry<String, String> item : networkMap.entrySet()) {
if (StringUtils.contains(item.getKey(), matchUrl)) {
return item.getValue();
}
}
this.sleep(10);
if (System.currentTimeMillis() - startTime.getTime() > timeoutMs) {
throw new TimeoutException("listenNetWork time out");
}
}
} finally {
this.closeNetWork();
}
}
private String listenNetWorkCenterExample(String matchUrl, Long timeoutMs) {
// devTools.addListener(Network.responseReceived(),responseReceived -> {
// RequestId requestId = responseReceived.getRequestId();
// Network.GetResponseBodyResponse response = devTools.send(Network.getResponseBody(requestId));
//
// String body = response.getBody();
// System.out.println(body);
// });
// 获取Request信息
// devTools.addListener(Network.requestWillBeSent(), res -> {
// System.out.println("RequestHeaders:" + res.getRequest().getHeaders());
// System.out.println("RequestHeaders:" + res.getRequest().getUrl());
// });
// 获取Response信息
// devTools.addListener(Network.responseReceived(), res -> {
// System.out.println("ResponseHeaders:" + res.getResponse().getHeaders());
// System.out.println("ResponseURL:" + res.getResponse().getUrl());
// });
// xhr MimeType
// 'application/javascript', 'application/x-javascript', 'text/css', 'webp', 'image/png', 'image/gif',
// 'image/jpeg', 'image/x-icon', 'application/octet-stream','xhr'
// if ("xhr".equals(response.getMimeType()))
DevTools devTools = this.driver.getDevTools();
try {
AtomicReference<String> responseBody = new AtomicReference<>("");
// 获取Response响应内容
devTools.addListener(Network.responseReceived(), res -> {
Response response = res.getResponse();
System.out.println("response.getUrl():" + response.getUrl());
if (response.getUrl().contains(matchUrl)) {
if (StringUtils.isBlank(responseBody.get())) {
// 获取network 请求的responseBody
responseBody.set(devTools.send(Network.getResponseBody(res.getRequestId())).getBody());
}
}
});
Date startTime = new Date();
while (true) {
this.sleep(10);
if (StringUtils.isNotBlank(responseBody.get())) {
return responseBody.get();
}
if (System.currentTimeMillis() - startTime.getTime() > timeoutMs) {
throw new TimeoutException("listenNetWork time out");
}
}
} finally {
this.closeNetWork();
}
}
public void closeNetWork() {
try {
this.driver.getDevTools().send(Network.disable());
} catch (Exception e) {
} finally {
this.networkMap.clear();
}
}
public void resetInputState() {
this.driver.resetInputState();
}
}
......@@ -4,6 +4,7 @@ import com.greatchn.rpa.beans.Button;
import com.greatchn.rpa.beans.Point;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;
......@@ -144,6 +145,11 @@ public final class WinApi {
}
}
public static void enter(){
ROBOT.keyPress(KeyEvent.VK_ENTER);
ROBOT.keyRelease(KeyEvent.VK_ENTER);
}
public static void main(String[] args) {
mouseMove(0, 0);
mouseMove(1000, 1000, 1000);
......
......@@ -22,6 +22,12 @@ public class RpaConfig {
private Browser browser;
private Rpa rpa;
private Double scale;
//新增参数
private boolean useSeleniumDrag;
private boolean networkProxy;
private boolean remoteDebugging;
private int remoteDebuggingPort;
private String remoteDebuggingIP;
/**
* 使用默认配置文件加载配置
......
package com.greatchn.yzh;
import cn.hutool.core.date.DateUtil;
import com.greatchn.etax.monitor.Monitor;
import com.greatchn.etax.tianjin.Tianjin;
import com.greatchn.kits.EnvironmentToolkit;
import com.greatchn.kits.HashKits;
import com.greatchn.rpa.WinApi;
import com.greatchn.rpa.config.RpaConfig;
import com.greatchn.yzh.db.Db;
import lombok.extern.slf4j.Slf4j;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
* 云账户 RPA 任务处理器
......@@ -25,21 +36,90 @@ public final class TaskExecutor {
private final Tianjin tianjin;
private final Monitor monitor;
private final Monitor monitor=null;
private final String instanceID;
private final String ip;
public TaskExecutor() {
public TaskExecutor() throws InterruptedException {
instanceID = "%s_java_rpa".formatted(HashKits.sha256(EnvironmentToolkit.getMac().getBytes(StandardCharsets.UTF_8)));
ip = EnvironmentToolkit.getLocalIp();
db = new Db();
tianjin = new Tianjin(RpaConfig.build("rpa.yaml"));
monitor = new Monitor();
// monitor = new Monitor();
String taxFileNo="91120116MA05TT0A0D";
tianjin.login(taxFileNo, "13516135467", "Badboy1993");
tianjin.login("91120223MA079XXY07", "131026199607185115", "ds111111");
//我要办税
WebElement wybs = tianjin.rpa().findElement(By.xpath(".//a[text()='我要办税']"),10);
tianjin.rpa().click(wybs);
//frame
WebElement iframe = tianjin.rpa().findElement(By.cssSelector("#profile > iframe"), 10);
//税务数字账户
tianjin.rpa().switchToFrame(iframe);
WebElement swsszh = tianjin.rpa().findElement(By.xpath(".//li[@title='税务数字账户']"),10);
tianjin.rpa().click(swsszh);
tianjin.rpa().switchToParent();
//tianjin.rpa().listen("/menuAuth/getMenuAuthSwitch.do",10);
tianjin.rpa().refresh();
System.out.println("已刷新");
//税务数字账户2
WebElement swsszh2 = tianjin.rpa().findElement(By.xpath(".//div[@class='leftPanel-li-div']//span[text()='税务数字账户']"),10);
tianjin.rpa().click(swsszh2);
System.out.println("税务数字账户2点击完毕");
Thread.sleep(10000L);
tianjin.rpa().sendEnterCmd(10000);
while(true) {
//new page
Thread.sleep(1000);
Set<String> windowHandles = tianjin.rpa().getWindowHandles();
System.out.println("windowHandles:"+windowHandles.size());
if (windowHandles.size()>1) {
List<String> collect = windowHandles.stream().collect(Collectors.toList());
tianjin.rpa().switchWindow(collect.get(1));
break;
}
}
tianjin.rpa().visit("https://dppt.tianjin.chinatax.gov.cn:8443/invoice-query/invoice-query?ruuid="+System.currentTimeMillis());
Thread.sleep(10000L);
tianjin.rpa().sendEnterCmd(10000);
//发票查询统计
// WebElement fpcxtj = tianjin.rpa().findElement(By.xpath(".//div[@class='app_name__bold'][text()='发票查询统计']"),10);
// tianjin.rpa().click(fpcxtj);
//全量发票查询
// WebElement qlfpcx = tianjin.rpa().findElement(By.xpath(".//div[@class='g-card-menu-item__title'][text()='全量发票查询']"));
// tianjin.rpa().click(qlfpcx);
// tianjin.rpa().visit("https://dppt.tianjin.chinatax.gov.cn:8443/invoice-query/invoice-query?"+System.currentTimeMillis());
tianjin.rpa().newHar();
WebElement queryButton = tianjin.rpa().findElement(By.xpath(".//span[text()='查询']"), 60);
tianjin.rpa().click(queryButton);
tianjin.rpa().listen("/qlfpcx/v1/queryFpjeseHj",10);
File srcFile = tianjin.rpa().driver().getScreenshotAs(OutputType.FILE);
srcFile.renameTo(new File("./files/全电_%s_%s.jpg".formatted(taxFileNo, DateUtil.format(new Date(),"yyyy_MM_dd HH_mm_ss"))));
System.out.println("finish");
// tianjin.queryDutyPaidProof("91120223MA079XXY07", "131026199607185115", "ds111111","510211201000000362315","2019-01-01", "2019-12-31");
// 心跳
{
......
......@@ -3,13 +3,27 @@ selenium:
browser:
chrome: /Google/Chrome/Application/chrome.exe
rpa:
#Mobo代理
proxy:
enable: true
enable: false
port: 30001
cookies:
clean: true
fullScreen: false
autoScroll: true
autoCreate: true
simulate: true
scale: 1.00
\ No newline at end of file
simulate: false
#新增参数
useSeleniumDrag: true
#chrome的network,不可以与Mobo代理同时打开
networkProxy: true
#是否使用selenium来自动启动浏览器
remoteDebugging: true
remoteDebuggingPort: 9222
remoteDebuggingIP: "127.0.0.1"
scale: 1.00
import com.greatchn.rpa.RpaCore;
import com.greatchn.rpa.config.RpaConfig;
import com.greatchn.yzh.TaskExecutor;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
public class DriverTest {
public static void main(String[] args) throws InterruptedException {
var config = RpaConfig.build();
RpaCore rpa=new RpaCore(config);
rpa.visit("chrome://version/");
//network
//rpa.enableNetWork();
rpa.visit("https://www.baidu.com");
System.out.println(rpa.listenNetWorkCenter("sugrec", 10000L));
//drag
rpa.visit("https://tpass.tianjin.chinatax.gov.cn:8443/#/login?redirect_uri=https%3A%2F%2Fetax.tianjin.chinatax.gov.cn%2Foutsider%2Fsso%2FmainPage.do&client_id=x3ef652ax3294xz6beefnf5zadbf66cc&response_type=code&state=test");
var dragHandler = rpa.findElement(By.cssSelector(".handler.animate"), 1);
WebElement continer=rpa.findElement(dragHandler,By.xpath("./.."));
System.out.println(continer.getText());
rpa.drag(dragHandler,continer);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment