上一篇:Java網路爬蟲實操(9)
各位好,馬上又是618購物節了,大家的購物熱情多少有點被勾起吧。相信大家最頻繁的操作肯定是開啟購物網站,輸入關心商品的關鍵字,然後看看哪個店的銷量高,哪個店的價格最低,等等。 本篇文章結合Java爬蟲框架NetDiscovery使用selenium技術實現自動化獲取前三個商品的資訊。
1) 邏輯流程
- 程式開啟JD的商品搜尋頁面
- 自動輸入商品關鍵字
- 自動點選查詢按鈕
- 自動點選銷量按鈕
- 獲取前三個商品的資訊:店鋪名稱、商品名稱、售價
2) 程式碼流程
- 使用chrome瀏覽器訪問網頁,需要使用對應平臺和版本的driver程式。
WebDriverPoolConfig config = new WebDriverPoolConfig("example/chromedriver.exe", Browser.Chrome);
WebDriverPool.init(config);
複製程式碼
- 實現一個繼承SeleniumAction的類,執行邏輯都在這裡。
package com.cv4j.netdiscovery.example.jd;
import com.cv4j.netdiscovery.selenium.Utils;
import com.cv4j.netdiscovery.selenium.action.SeleniumAction;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
public class JDAction extends SeleniumAction {
@Override
public SeleniumAction perform(WebDriver driver) {
try {
//BrowserAction 最大化瀏覽器視窗
driver.manage().window().maximize();
Thread.sleep(3000);
//輸入商品關鍵字
String searchText = "商務筆記本";
String searchInput = "//*[@id=\"keyword\"]";
WebElement userInput = Utils.getWebElementByXpath(driver, searchInput);
userInput.sendKeys(searchText);
Thread.sleep(3000);
//觸發查詢事件
String searchBtn = "/html/body/div[2]/form/input[4]";
Utils.clickElement(driver, By.xpath(searchBtn));
Thread.sleep(3000);
//觸發銷量事件
String saleSortBtn = "//*[@id=\"J_filter\"]/div[1]/div[1]/a[2]";
Utils.clickElement(driver, By.xpath(saleSortBtn));
Thread.sleep(3000);
//獲取頁面的html原始碼並轉化為物件
String pageHtml = driver.getPageSource();
Document document = Jsoup.parse(pageHtml);
Elements elements = document.select("div[id=J_goodsList] li[class=gl-item]");
if(elements != null && elements.size() >= 3) {
for (int i = 0; i < 3; i++) {
Element element = elements.get(i);
String storeName = element.select("div[class=p-shop] a").first().text();
String goodsName = element.select("div[class=p-name p-name-type-2] a em").first().text();
String goodsPrice = element.select("div[class=p-price] i").first().text();
System.out.println(storeName+" "+goodsName+" ¥"+goodsPrice);
}
}
} catch(InterruptedException e) {
e.printStackTrace();
}
return null;
}
}
複製程式碼
- 把action裝載到下載器SeleniumDownloader,並且構建一個Spider
package com.cv4j.netdiscovery.example.jd;
import com.cv4j.netdiscovery.core.Spider;
import com.cv4j.netdiscovery.selenium.Browser;
import com.cv4j.netdiscovery.selenium.downloader.SeleniumDownloader;
import com.cv4j.netdiscovery.selenium.pool.WebDriverPool;
import com.cv4j.netdiscovery.selenium.pool.WebDriverPoolConfig;
public class JDSpider {
public static void main(String[] args) {
WebDriverPoolConfig config = new WebDriverPoolConfig("example/chromedriver.exe", Browser.Chrome);
WebDriverPool.init(config);
JDAction jdAction = new JDAction();
SeleniumDownloader seleniumDownloader = new SeleniumDownloader(jdAction);
String url = "https://search.jd.com/";
Spider.create()
.name("searchJD")
.url(url)
.downloader(seleniumDownloader)
.run();
}
}
複製程式碼
- spider的執行結果
3) 進一步說明
- 以上程式碼只是例子,實際工作中action邏輯會比較複雜。我們可以根據需求,把action拆分為多個,通過list裝配到載入器,框架會根據add順序排隊執行action。
List<SeleniumAction> actionList = new ArrayList<>();
actionList.add(new BrowserAction());
actionList.add(new InitAction());
actionList.add(new WorkAction());
SeleniumDownloader seleniumDownloader = new SeleniumDownloader(actionList);
複製程式碼
- 如果自動化工作需要週期性執行,可以參考之前的文章,把spider載入到SpiderEngine中,然後呼叫runRepeat(),實現重複執行。
SpiderEngine engine = SpiderEngine.create();
for(...) {
engine.addSpider(spider);
}
engine.runWithRepeat();
複製程式碼
-
也許有些夥伴會問action類中的xpath怎麼來的?我是使用chrome瀏覽器,通過開發者工具中Elements,選中元素後點右鍵,然後找到xpath的。
-
如何從html字串轉換為物件,實現目標資料的精確獲取,有很多方法。比如Jsoup。
好了,本篇只是拋磚引玉,相信有需要的夥伴肯定有深入的需求和想法,歡迎大家關注Java爬蟲框架NetDiscovery https://github.com/fengzhizi715/NetDiscovery