Selenium也是一個用於Web應用程式測試的工具。Selenium測試直接執行在瀏覽器中,就像真正的使用者在操作一樣。支援的瀏覽器包括IE、Mozilla Firefox、Mozilla Suite等。這個工具的主要功能包括:測試與瀏覽器的相容性——測試你的應用程式是否能夠很好得工作在不同的瀏覽器和作業系統之上。測試系統功能——建立衰退測試檢驗軟體功能和使用者需求。支援自動錄製動作和自動生成。Net、Java、Perl等不同語言的測試指令碼。Selenium 是ThoughtWorks專門為Web應用程式編寫的一個驗收測試工具。
以selenium獲取支付寶賬單記錄為例,具體思路透過selenium模擬使用者登入支付寶,然後跳轉支付寶賬單頁面透過xpath定位賬單的dom,然後解析dom,獲取到賬單列表的資料,每過3分鐘重新整理一下賬單資訊,這樣有資料變化的話可以寫一個回撥函式,這樣就實現了支付寶免籤。經測試在伺服器環境會出現驗證碼情況,支付寶應該做了安全驗證,解決驗證碼需要用到機器學習,這裡不解決,個人使用是不會出現安全驗證的,可以自己使用。
首先準備開發環境需要三樣東西(使用java程式設計)chrome瀏覽器
chrome驅動必須和chrome版本相匹配,驅動當中的特徵字元傳需要替換掉,否則會讓網站檢測到,出現驗證碼
<dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-server</artifactId> <version>4.0.0-alpha-2</version> </dependency>
關鍵程式碼邏輯實現
Resource resource = resourceLoader.getResource("classpath:chrome/chromedriver.exe"); System.setProperty("webdriver.chrome.driver", resource.getFile().getAbsolutePath()); chromeOptions = new ChromeOptions(); chromeOptions.setExperimentalOption("excludeSwitches", Collections.singletonList("enable-automation")); chromeOptions.setExperimentalOption("useAutomationExtension", false); chromeOptions.addArguments("--disable-blink-features=AutomationControlled"); ChromeDriver chromeDriver = new ChromeDriver(chromeOptions); try {//最大化視窗 chromeDriver.manage().window().maximize(); chromeDriver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS); // get()開啟一個登入站點 chromeDriver.get("https://auth.alipay.com/login/index.htm"); Thread.sleep(2000); chromeDriver.findElement(By.cssSelector("#J-loginMethod-tabs > li:nth-child(2)")).click(); Thread.sleep(2000); //輸入使用者名稱和密碼 for (char chars : "username").toCharArray()) { Thread.sleep(RandomUtil.randomInt(300, 500)); chromeDriver.findElement(By.xpath("//*[@id=\"J-input-user\"]")).sendKeys(String.valueOf(chars)); } Thread.sleep(RandomUtil.randomInt(500, 800)); for (char chars : "password".toCharArray()) { Thread.sleep(RandomUtil.randomInt(300, 500)); chromeDriver.findElement(By.xpath("//*[@id=\"password_rsainput\"]")).sendKeys(String.valueOf(chars)); } Thread.sleep(RandomUtil.randomInt(500, 1000)); chromeDriver.findElement(By.xpath("//*[@id=\"J-login-btn\"]")).click(); Thread.sleep(5 * 1000) while (true) { Thread.sleep(3*60 * 1000); //調整賬單頁面 chromeDriver.get("https://mbillexprod.alipay.com/enterprise/fundAccountDetail.htm#/"); chromeDriver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS); //切換為最近7天 try { chromeDriver.findElementByXPath("//*[@id=\"root\"]/div/div/div/div[2]/div/div/form/div[1]/div[2]/div[2]/div/span/div/div[2]/div[3]").click(); }catch (org.openqa.selenium.NoSuchElementException noSuchElementException){ continue; } Thread.sleep(3000); try { WebElement elementByXPath = chromeDriver.findElementByXPath("//*[@id=\"root\"]/div/div/div/div[4]/div[1]/div/div/div/div/div[1]/div/div/div[1]/div/span"); } catch (org.openqa.selenium.NoSuchElementException noSuchElementException) { continue; } chromeDriver.findElementByXPath("//*[@id=\"root\"]/div/div/div/div[4]/div[2]/div[1]/div[1]/div[2]/div/div/div/div[1]/div[2]").click(); } Thread.sleep(RandomUtil.randomInt(2000, 3000)); WebElement tbody = chromeDriver.findElementByXPath("//*[@id=\"root\"]/div/div/div/div[4]/div[2]/div[2]/div/div/div/div/div/div[1]/div/table/tbody"); List<WebElement> tr = tbody.findElements(By.tagName("tr")); Stream<ConcurrentHashMap> concurrentHashMapStream = tr.stream().map(webElement -> { List<WebElement> elements = webElement.findElements(By.tagName("td")); //入賬時間 String entryTime = elements.get(0).findElement(By.tagName("span")).findElement(By.tagName("span")).getText(); //支付寶交易單號 String serialNumber = elements.get(1).findElement(By.tagName("span")).findElement(By.tagName("span")).findElement(By.tagName("span")).getAttribute("title"); //商家訂單號 String orderNumber = new String(); try { orderNumber = elements.get(2).findElement(By.tagName("span")).findElement(By.tagName("span")).findElement(By.tagName("span")).getAttribute("title"); } catch (org.openqa.selenium.NoSuchElementException noSuchElementException) { } //對方資訊 String otherInfo = elements.get(3).findElement(By.tagName("div")).getText(); //財務型別 String financialType = elements.get(4).findElement(By.tagName("span")).findElement(By.tagName("span")).getText(); //收支金額 String amount = elements.get(5).findElement(By.tagName("span")).findElement(By.tagName("span")).getText(); //賬戶餘額 String balance = elements.get(6).findElement(By.tagName("span")).findElement(By.tagName("span")).getText(); //備註 // String remark = elements.get(7).findElement(By.tagName("span")).findElement(By.tagName("span")).getText(); ConcurrentHashMap concurrentHashMap = new ConcurrentHashMap(); concurrentHashMap.put("entryTime", entryTime); concurrentHashMap.put("serialNumber", serialNumber); concurrentHashMap.put("orderNumber", orderNumber); concurrentHashMap.put("otherInfo", otherInfo); concurrentHashMap.put("financialType", financialType); concurrentHashMap.put("amount", amount); concurrentHashMap.put("balance", balance); // concurrentHashMap.put("remark", remark); return concurrentHashMap; }); //列表資料獲取完成,至於是否跳轉下頁,是否發生回撥函式根據需求實現 } catch (Exception e) { log.error("爬蟲------------------------------------------------", e); chromeDriver.quit(); } });
執行後selenium會透過chrome驅動來自動操作chrome瀏覽器,完成登入操作和頁面跳轉,最終採集到需要的資訊,其中很多操作都需要休眠是因為平臺能夠檢測到是否是真實使用者,所以要進行模擬使用者行為,這樣才能安全使用。