Java網絡爬蟲實操(10)

上一篇:Java網絡爬蟲實操(9)

各位好,馬上又是618購物節了,大家的購物熱情多少有點被勾起吧。相信大家最頻繁的操作肯定是打開購物網站,輸入關心商品的關鍵字,然后看看哪個店的銷量高,哪個店的價格最低,等等。
本篇文章結合Java爬蟲框架NetDiscovery使用selenium技術實現自動化獲取前三個商品的信息。

1) 邏輯流程

  1. 程序打開JD的商品搜索頁面
  2. 自動輸入商品關鍵字
  3. 自動點擊查詢按鈕
  4. 自動點擊銷量按鈕
  5. 獲取前三個商品的信息:店鋪名稱、商品名稱、售價

2) 代碼流程

  1. 使用chrome瀏覽器訪問網頁,需要使用對應平臺和版本的driver程序。
        WebDriverPoolConfig config = new WebDriverPoolConfig("example/chromedriver.exe", Browser.Chrome);
        WebDriverPool.init(config);
  1. 實現一個繼承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 = "http://*[@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 = "http://*[@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;
    }
}
  1. 把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();
    }
}
  1. spider的執行結果


    執行結果

3) 進一步說明

  1. 以上代碼只是例子,實際工作中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);
  1. 如果自動化工作需要周期性執行,可以參考之前的文章,把spider加載到SpiderEngine中,然后調用runRepeat(),實現重復執行。
        SpiderEngine engine = SpiderEngine.create();
        for(...) {
            engine.addSpider(spider);
        }
        engine.runWithRepeat();
  1. 也許有些伙伴會問action類中的xpath怎么來的?我是使用chrome瀏覽器,通過開發者工具中Elements,選中元素后點右鍵,然后找到xpath的。


  2. 如何從html字符串轉換為對象,實現目標數據的精確獲取,有很多方法。比如Jsoup。

好了,本篇只是拋磚引玉,相信有需要的伙伴肯定有深入的需求和想法,歡迎大家關注Java爬蟲框架NetDiscovery https://github.com/fengzhizi715/NetDiscovery

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 你爬了嗎? 要玩大數據,沒有數據怎么玩?這里推薦一些33款開源爬蟲軟件給大家。 爬蟲,即網絡爬蟲,是一種自動獲取網...
    Albert新榮閱讀 2,243評論 0 8
  • 要玩大數據,沒有數據怎么玩?這里推薦一些33款開源爬蟲軟件給大家。 爬蟲,即網絡爬蟲,是一種自動獲取網頁內容的程序...
    評評分分閱讀 8,030評論 2 121
  • 不得不提筆, 四處搜羅了情緒。 絲絲迸發著, 壓抑許久的才氣。 手中的筆并不熟悉, 更不在乎身在哪里。 七月十三,...
    有詩有酒有情郎閱讀 274評論 0 1
  • 聽完樊登老師講解的《谷物大腦》太震撼了。原來我們認為多吃谷物和蔬菜、少吃高膽固醇和高脂肪食物的飲食觀是不科學...
    深藍零點閱讀 695評論 0 0