Selenium+PhantomJs 爬取網頁內容


利用Selenium和PhantomJs 可以模擬用戶操作,爬取大多數的網站。下面以新浪財經為例,我們抓取新浪財經的新聞版塊內容。

1.依賴的jar包。我的項目是普通的SSM單間的WEB工程。最后一個jar包是用來在抓取到網頁dom后做網頁內容解析的。

<!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>3.2.0</version>
        </dependency>
        
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-web-api</artifactId>
            <version>7.0</version>
            <scope>provided</scope>
        </dependency>
        
        <!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>20.0</version>
        </dependency>
        
        <dependency>
            <groupId>cn.wanghaomiao</groupId>
            <artifactId>JsoupXpath</artifactId>
            <version>2.2</version>
        </dependency>
        

2.獲取網頁dom內容

package com.nsjr.grab.util;

import java.util.List;
import java.util.concurrent.TimeUnit;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.openqa.selenium.phantomjs.PhantomJSDriver;
import org.openqa.selenium.phantomjs.PhantomJSDriverService;
import org.openqa.selenium.remote.DesiredCapabilities;

import cn.wanghaomiao.xpath.model.JXDocument;

@SuppressWarnings("deprecation")
public class SeleniumUtil {
    
    public static JXDocument getDocument(String driverUrl,String pageUrl){
        JXDocument jxDocument = null;
        PhantomJSDriver driver = null;
        try{
            System.setProperty("phantomjs.binary.path", driverUrl);
            System.setProperty("webdriver.chrome.driver", driverUrl);
            
            DesiredCapabilities dcaps = new DesiredCapabilities();
            //ssl證書支持
            dcaps.setCapability("acceptSslCerts", true);
            //截屏支持
            dcaps.setCapability("takesScreenshot", true);
            //css搜索支持
            dcaps.setCapability("cssSelectorsEnabled", true);
            //js支持
            dcaps.setJavascriptEnabled(true);
            //驅動支持
            dcaps.setCapability(PhantomJSDriverService.PHANTOMJS_EXECUTABLE_PATH_PROPERTY,driverUrl);
            //創建無界面瀏覽器對象
            driver = new PhantomJSDriver(dcaps);
            //WebDriver driver = new ChromeDriver(dcaps);
            driver.get(pageUrl);
            driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
            Document document = Jsoup.parse(driver.getPageSource());
            jxDocument = new JXDocument(document);
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            if(driver != null){
                driver.quit();
            }
        }
        return jxDocument;
    }
    
    
    public static String getProperty(List<Object> list){
        if(list.isEmpty()){
            return "";
        }else{
            return list.get(0).toString();
        }
    }
}

3.解析並保存內容

JXDocument jxDocument = SeleniumUtil.getDocument(captureUrl.getDriverUrl(), captureUrl.getSinaNews());
        
        //保存第一部分加粗新聞
        List<Object> listh3 = jxDocument.sel("//div[@id='impNews1']/div[@id='fin_tabs0_c0']/div[@id='blk_hdline_01']/h3/a");
        for(Object a :listh3){
                JXDocument doc = new JXDocument(a.toString());
                //System.out.println("地址:"+doc.sel("//a/@href"));
                //System.out.println("標題:"+doc.sel("//text()"));
                saveNews(SeleniumUtil.getProperty(doc.sel("//text()")), SeleniumUtil.getProperty(doc.sel("//a/@href")), Constant.NEWS_TYPE_BOTTOM, Constant.NEWS_SOURCE_SINA);
        }
        
        //保存其余新聞
        List<Object> listP = jxDocument.sel("//div[@id='impNews1']/div[@id='fin_tabs0_c0']/div[@id='blk_hdline_01']/p/a");
        for(Object a :listP){
            JXDocument doc = new JXDocument(a.toString());
            //System.out.println("地址:"+doc.sel("//a/@href"));
            //System.out.println("標題:"+doc.sel("//text()"));
            saveNews(SeleniumUtil.getProperty(doc.sel("//text()")), SeleniumUtil.getProperty(doc.sel("//a/@href")), Constant.NEWS_TYPE_BOTTOM, Constant.NEWS_SOURCE_SINA);

        }
        
        //保存第二部分新聞
        List<Object> listpart2 = jxDocument.sel("//div[@id='impNews1']/div[@id='fin_tabs0_c0']/div[2]/ul");
        for(Object a :listpart2){
            JXDocument doc = new JXDocument(a.toString());
            List<Object> alist = doc.sel("//li/a");
            for(Object a2 :alist){
                JXDocument doc2 = new JXDocument(a2.toString());
                //System.out.println("地址:"+doc2.sel("//a/@href"));
                //System.out.println("標題:"+doc2.sel("//text()"));
                saveNews(
                        SeleniumUtil.getProperty(doc2.sel("//text()")), 
                        SeleniumUtil.getProperty(doc2.sel("//a/@href")), 
                        Constant.NEWS_TYPE_BOTTOM, 
                        Constant.NEWS_SOURCE_SINA
                    );
            }
        }

4.解釋

captureUrl.getDriverUrl(), captureUrl.getSinaNews() 這兩個地址分別是PhantomJs工具的地址和要爬取的網站的地址,其中
sina_news = https://finance.sina.com.cn/
driverUrl= D:\\phantomjs-2.1.1-windows\\bin\\phantomjs.exe

關於PhantomJs 工具的下載可以直接去官網下載 http://phantomjs.org/download.html,有windows 和Linux版供下載。關於網頁結構的解析使用JsoupXpath ,是一個國人寫的html文檔解析工具包,挺好用的。語法可以參考Xpath的相關語法進行節點的選取。

5.爬取結果。由於項目需求較為簡單,對實時性和性能要求不高,所以只做到入庫,即可滿足需求。

最后,剛開始接觸爬蟲類的東西,有的需求webmagic 可以滿足,有的需要其他方式,需要具體問題具體分析。尚在摸索階段,本文僅僅是提供一種解決思路。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM