寫在前面:
老大讓我寫個腳本自動給他寫dms有一段時間了,說實話當時不知道老大指的這個腳本是什么?畢竟是做web的,難道是寫個數據庫sql語句腳本嗎?也就放在了一邊。巧了,最近一個朋友說他之前寫了個程式,我就問了一下。哇,這不正是我想要的!他是做了一個可以自動登錄網站,然后自動填寫日報的程式。看了之后感覺很棒,於是請教了一下。
朋友的程式是用的c#做的,然后內嵌了一個瀏覽器控件webbrowser。一下子恍然大悟,還可以這么玩。平時工作也沒有接觸到瀏覽器控件,於是趕緊去搜索java的瀏覽器控件。然后最后也花了點時間,還好,馬馬虎虎的完成了任務。
思路:
使用javase做一個桌面應用程序,彈出一個框,然后里面內嵌一個瀏覽器,可以模擬自動登錄網站,並可以自動填寫日報,達到想要的效果。
對於使用java彈出一個應用框是很好實現的,使用JFrame來實現就好了,主要是如何在彈出框里面內嵌一個瀏覽器?
首先百度,java瀏覽器控件,出來的就是jxbrowser,於是去查資料了解
想要做一個自動登錄網站的應用,使用javase,內嵌一個瀏覽器是很好的選擇。這樣就避免了一些cookie之類的設置。
jxbrowser是什么?
jxbrowser是一個java瀏覽器控件,是基於chromium內核的。(如果要自動登錄的系統是適應ie瀏覽器的,那么有可能使用此款瀏覽器控件,在有些功能上不兼容適用。這里稍微注意下,以免踩坑)
如何使用?
首先去下載,http://www.pc0359.cn/downinfo/95385.html,下載下來后進行解壓
對於如何破解,可以參考對應的資料,https://blog.csdn.net/Jumenglo/article/details/79459102
下面簡單看下項目的破解步驟:
1.創建java項目,導入相關的jxbrowser需要的jar包,(在解壓的目錄下就可以復制);然后在解壓文件里找對對應的demo,復制META-INF文件夾(證書),到自己的項目目錄下。然后這個時候如果對應的證書的期限到了,是無法使用的,所以要破解。

2.打開證書teamdev.licenses,直接復制下面的代碼,即可。
Product: JxBrowser
Version: 6.x
Licensed to:
License type: Enterprise
License info: JxBrowser Demo License
Expiration date: 01-01-9999
Support expiration date: NO SUPPORT
Generation date: 01-01-9999
Platforms: win32/x86;win32/x64;mac/x86;mac/x64;linux/x86;linux/x64
Company name: TeamDev Ltd.
SigB: 1
SigA: 1
3.在代碼中添加破解的代碼塊
/*破解jxbrowser的代碼塊 導入下面的包是關鍵 * import com.teamdev.jxbrowser.chromium.ba; * */ static { try { Field e = ba.class.getDeclaredField("e"); e.setAccessible(true); Field f = ba.class.getDeclaredField("f"); f.setAccessible(true); Field modifersField = Field.class.getDeclaredField("modifiers"); modifersField.setAccessible(true); modifersField.setInt(e, e.getModifiers() & ~Modifier.FINAL); modifersField.setInt(f, f.getModifiers() & ~Modifier.FINAL); e.set(null, new BigInteger("1")); f.set(null, new BigInteger("1")); modifersField.setAccessible(false); } catch (Exception e1) { e1.printStackTrace(); } }
注意,此時添加代碼塊后,可能找不到ba,因為還需要導入對應的包,這里我導入的是import com.teamdev.jxbrowser.chromium.ba; 有可能jxbrowser的版本不同,這里導入的包也不同,即使用的ba的名字會有變化,這里可以在網上查看下,這里我的版本是6.21。
此時,不出意外就已經破解好了,可以開始編碼了。然后這里我做的是程序啟動,彈出一個框,框里內嵌了jxbrowser瀏覽器,然后會打開一個網站系統,實現自動登錄並填寫東西,並提交。(這里我的系統是公司內部系統,如果要做其他的仿照即可,大概思路與原理是一個樣子的)
下面直接上代碼:
import com.teamdev.jxbrowser.chromium.Browser; import com.teamdev.jxbrowser.chromium.ba; import com.teamdev.jxbrowser.chromium.dom.*; import com.teamdev.jxbrowser.chromium.events.FinishLoadingEvent; import com.teamdev.jxbrowser.chromium.events.LoadAdapter; import com.teamdev.jxbrowser.chromium.swing.BrowserView; import javax.swing.*; import java.awt.*; import java.io.*; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.math.BigInteger; import java.util.List; import java.util.Properties; /** * Description:PACKAGE_NAME * Author: Eleven * Date: 2019/1/9 9:15 */ public class Demo { /*破解jxbrowser的代碼塊 導入下面的包是關鍵 * import com.teamdev.jxbrowser.chromium.ba; * */ static { try { Field e = ba.class.getDeclaredField("e"); e.setAccessible(true); Field f = ba.class.getDeclaredField("f"); f.setAccessible(true); Field modifersField = Field.class.getDeclaredField("modifiers"); modifersField.setAccessible(true); modifersField.setInt(e, e.getModifiers() & ~Modifier.FINAL); modifersField.setInt(f, f.getModifiers() & ~Modifier.FINAL); e.set(null, new BigInteger("1")); f.set(null, new BigInteger("1")); modifersField.setAccessible(false); } catch (Exception e1) { e1.printStackTrace(); } } /*正式程序編寫*/ private static InputStream in = null; private static Properties properties =new Properties(); ///累計加載的次數 static int num = 0; public static void main(String[] args) { File directory = new File("");// 參數為空,獲取所在的路徑 String courseFile = ""; try { //加載讀取config.properties文件,配置文件主要存放了一些登陸用戶名與密碼還有一些其他的參數設置 /*獲取項目的根路徑,因為這里我是將配置文件與項目放在同級的*/ courseFile = directory.getCanonicalPath(); System.out.println(courseFile); String configPath = courseFile+"/config.properties"; in = new BufferedInputStream(new FileInputStream(configPath)); properties.load(new InputStreamReader(in, "UTF-8")); } catch (IOException e) { e.printStackTrace(); } /*系統的訪問地址*/ final String url = "http://10.202.10.94/DMS/index.jsp"; final String title = "DMS"; Browser browser = new Browser(); BrowserView view = new BrowserView(browser); /*窗口制作,設置相關的屬性*/ JFrame frame = new JFrame("DMS自動-V1.0"); frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); //不顯示標題欄,最大化,最小化,退出按鈕 frame.setSize(600, 500); frame.add(view, BorderLayout.CENTER); frame.setLocationRelativeTo(null); frame.setVisible(true); /*使用瀏覽器控件加載訪問系統網站地址*/ browser.loadURL(url); /*添加一個完成加載的事件:這里當每次加載一個新的頁面的時候(browser.loadURL(...)),都會進來此方法*/ browser.addLoadListener(new LoadAdapter() { @Override public void onFinishLoadingFrame(FinishLoadingEvent event) { if (event.isMainFrame()) { /*因為當加載新的頁面時,都會進來此方法,所以,這里要用數字做一個判斷,判斷是哪個頁面,第幾次加載,根據自己的需求來*/ if(num == 0){ DOMDocument doc = event.getBrowser().getDocument(); /*找到頁面name為personcode的對象,並給它設置值*/ DOMElement username = doc.findElement(By.name("personcode")); //找到對應的輸入框元素(這里的By類提供了多種查找的方式) /*這里我設置的值是從配置文件中加載的,這里可以直接設置也可以*/ username.setAttribute("value", properties.getProperty("personcode")); //在輸入框中輸入內容 DOMElement password = doc.findElement(By.name("password")); password.setAttribute("value",properties.getProperty("password")); /*找到頁面name為Submit的按鈕,然后模擬點擊*/ DOMElement loginBtn = doc.findElement(By.name("Submit")); loginBtn.click();//模擬點擊 num++; }else if(num == 1){ Browser browser1 = event.getBrowser(); //模擬跳轉到點擊input Daily Record后的頁面 browser1.loadURL("http://10.202.10.94/DMS/dailyreport/dailyRecordMaintain.jsp"); num++; }else if(num == 2){ DOMDocument doc = event.getBrowser().getDocument(); /*找到頁面指定id的下拉框*/ DOMSelectElement dDateFrom = (DOMSelectElement) doc.findElement(By.id("dDateFrom")); DOMSelectElement dDateTo = (DOMSelectElement) doc.findElement(By.id("dDateTo")); /*獲取下拉框的options集合*/ List<DOMOptionElement> optionElementList = dDateFrom.getOptions(); List<DOMOptionElement> optionElementList2 = dDateTo.getOptions(); for(DOMOptionElement opt:optionElementList){ /*模擬下拉框選中時間*/ if(opt.getAttribute("value").equals(properties.getProperty("startTime"))){ opt.setSelected(true); } } for(DOMOptionElement opt:optionElementList2){ /*模擬下拉框選中時間*/ if(opt.getAttribute("value").equals(properties.getProperty("endTime"))){ opt.setSelected(true); } } /*由於dms系統是兼容ie的,在谷歌上點擊對應的study按鈕是沒有反應的,故這里直接使用給iframe設置src的方式來模擬用戶點擊study按鈕*/ DOMFrameElement workitemFrame = (DOMFrameElement) doc.findElement(By.name("workitem")); String tempSrc = workitemFrame.getAttribute("src"); workitemFrame.setAttribute("src","http://10.202.10.94/DMS/dailyreport/addStudyRecordInformation.jsp"); /*特別特別要注意!!!有可能父頁面加載子iframe加載完成需要一定的時間,故需要做延遲,特別注意,別踩坑!!!! * 剛開始獲取不到,還以為自己寫的問題!!!!! * */ /*這里要延遲,不然后面可能無法獲取到對應的組件元素*/ try { Thread.sleep(1000*1); } catch (InterruptedException e) { e.printStackTrace(); } DOMDocument wkDocument = workitemFrame.getContentDocument(); DOMElement workitemname = wkDocument.findElement(By.name("workitemname")); DOMElement content = wkDocument.findElement(By.name("content")); workitemname.setAttribute("value",properties.getProperty("workitemname")); content.setTextContent(properties.getProperty("content")); //模擬點擊提交 DOMElement b_save = wkDocument.findElement(By.name("b_save")); b_save.click(); num++; }else if(num == 3){ //System.out.println("到這里了"); } } } }); } }
下面是我自己的配置文件,這個根據自己的需求就好了:

代碼中注釋已經寫得很清楚了,應該大概都可以看得懂把~~~~~~~。
這里還是要提及一下,一定要注意,當頁面有子頁面iframe,加載iframe設置的時候,有的頁面加載需要一定的時間,故需要做一定的延遲!!!不然無法獲取到加載頁面的元素,這里一定要注意,至於需要延遲多久,就需要自己測試一下子!
到這里程序就寫完了,然后我們可以將項目打成jar包,然后使用exe4j打成exe可執行文件。這樣子就方便多啦。對於如何打成jar包以及如果使用exe4j,就不多說了,可以網上參考相關的資料。
對了,如果需要知道更多有關jxbrowser的一些方法事件,可以去解壓文件里找到api文檔,不過是全英文的。
還有要稍微注意下,使用exe4j生成的可執行程式后,需要配置對應的EXE4J_JAVA_HOME環境變量,不然會報錯的。
參考博客:
http://ciika.com/2018/05/java-jxbrowser-helloworld/--------JxBrowser的初步使用和證書
https://www.cnblogs.com/chevin/p/10029256.html------JxBrowser之二:常用函數addLoadListener
https://blog.csdn.net/weixin_42273374/article/details/80405456------properties文件第一行獲取的值為null
https://blog.csdn.net/qq_30730419/article/details/78041133------No JVM could be found on your system.please define ESE4J_JAVA_HOME to point to an installed 32-bit o
https://blog.csdn.net/zzzgd_666/article/details/80757194------exe4j打成的exe文件運行時彈窗this executable was created with an evaluation version of exe4j問題解決
