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 可以满足,有的需要其他方式,需要具体问题具体分析。尚在摸索阶段,本文仅仅是提供一种解决思路。

 

猜你喜欢

转载自www.cnblogs.com/li-zhi-long/p/10298911.html
今日推荐