文档章节

利用crawler4j+jsoup作爬虫

BK灬
 BK灬
发布于 2016/09/01 17:58
字数 960
阅读 488
收藏 5

main方法

package com.ninemax.utils.Crawler;

import edu.uci.ics.crawler4j.crawler.CrawlConfig;
import edu.uci.ics.crawler4j.crawler.CrawlController;
import edu.uci.ics.crawler4j.fetcher.PageFetcher;
import edu.uci.ics.crawler4j.robotstxt.RobotstxtConfig;
import edu.uci.ics.crawler4j.robotstxt.RobotstxtServer;

import java.sql.Timestamp;
import java.util.List;

public class ZiroomController {

    public static void main(String[] args) {

        System.out.println("-------begin:" + new Timestamp(System.currentTimeMillis()));

        final String crawlStorageFolder = "C:\\Users\\AckMan\\Desktop";
        final int numberOfCrawlers = 7;

        final CrawlConfig config = new CrawlConfig();
        config.setCrawlStorageFolder(crawlStorageFolder);
        config.setPolitenessDelay(1000);
        config.setIncludeBinaryContentInCrawling(false);
        config.setMaxPagesToFetch(-1);
        // config.setResumableCrawling(true);
        /*
         * Instantiate the controller for this crawl.
         */
        final PageFetcher pageFetcher = new PageFetcher(config);
        final RobotstxtConfig robotstxtConfig = new RobotstxtConfig();
        final RobotstxtServer robotstxtServer = new RobotstxtServer(robotstxtConfig, pageFetcher);
        CrawlController controller;
        try {
            controller = new CrawlController(config, pageFetcher, robotstxtServer);
            /*
             * For each crawl, you need to add some seed urls. These are the
             * first URLs that are fetched and then the crawler starts following
             * links which are found in these pages
             */
            controller.addSeed("http://sh.ziroom.com/z/nl/?p=");
            // controller.addSeed("http://www.ziroom.com/z/nl/z3-u2.html/");
            // controller.addSeed("http://www.ics.uci.edu/~welling/");
            // controller.addSeed("http://www.ics.uci.edu/");

            /*
             * Start the crawl. This is a blocking operation, meaning that your
             * code will reach the line after this only when crawling is
             * finished.
             */
            controller.start(ZiroomCrawler.class, numberOfCrawlers);

            final List<Object> crawlersLocalData = controller.getCrawlersLocalData();
            long totalLinks = 0;
            long totalTextSize = 0;
            int totalProcessedPages = 0;
            for (final Object localData : crawlersLocalData) {
                final CrawlStat stat = (CrawlStat) localData;
                totalLinks += stat.getTotalLinks();
                totalTextSize += stat.getTotalTextSize();
                totalProcessedPages += stat.getTotalProcessedPages();
            }

            System.out.println("Aggregated Statistics:");
            System.out.println("\tProcessed Pages: {}" + totalProcessedPages);
            System.out.println("\tTotal Links found: {}" + totalLinks);
            System.out.println("\tTotal Text Size: {}" + totalTextSize);
        } catch (final Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

爬虫方法

package com.ninemax.utils.Crawler;

import com.csvreader.CsvWriter;
import edu.uci.ics.crawler4j.crawler.Page;
import edu.uci.ics.crawler4j.crawler.WebCrawler;
import edu.uci.ics.crawler4j.parser.HtmlParseData;
import edu.uci.ics.crawler4j.url.WebURL;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.Set;
import java.util.regex.Pattern;

public class ZiroomCrawler extends WebCrawler {
    /** 爬取数据保存文件路径 */
    private final static String CSV_PATH = "C:\\Users\\AckMan\\Desktop\\ziroom.csv";
    /** 爬取匹配原则 */
    private final static Pattern FILTERS = Pattern.compile(".*(\\.(css|js|bmp|gif|jpe?g|ico"
            + "|png|tiff?|mid|mp2|mp3|mp4" + "|wav|avi|mov|mpeg|ram|m4v|pdf" + "|rm|smil|wmv|swf|wma|zip|rar|gz))$");
    /** 爬取link文件路径 */
    private final static String LINK_PATH = "C:\\Users\\AckMan\\Desktop\\link.csv";

    private static final Logger logger = LoggerFactory.getLogger(ZiroomCrawler.class);

    private final static String URL_PREFIX = "http://sh.ziroom.com/z/nl/?p=";

    private final File csv;
    private final File csv2;
    private CsvWriter cw;
    private CsvWriter cw2;

    /**
     * You should implement this function to specify whether the given url
     * should be crawled or not (based on your crawling logic).
     */
    CrawlStat myCrawlStat;

    public ZiroomCrawler() throws IOException {
        myCrawlStat = new CrawlStat();
        csv = new File(CSV_PATH);
        csv2 = new File(LINK_PATH);
        if (csv.isFile()) {
            csv.delete();
        }
        if (csv2.isFile()) {
            csv2.delete();
        }
        cw2 = new CsvWriter(new FileOutputStream(csv2, true),',',Charset.forName("UTF-8"));
        cw2.write("请求路径");
        cw2.endRecord();
        cw2.close();
        cw = new CsvWriter(new FileOutputStream(csv, true),',',Charset.forName("UTF-8"));
        cw.write("图片");
        cw.write("价格");
        cw.write("地址");
        cw.write("说明");
        cw.endRecord();
        cw.close();
    }

    public void dumpMyData() {
        final int id = getMyId();
        // You can configure the log to output to file
        logger.info("Crawler {} > Processed Pages: {}", id, myCrawlStat.getTotalProcessedPages());
        logger.info("Crawler {} > Total Links Found: {}", id, myCrawlStat.getTotalLinks());
        logger.info("Crawler {} > Total Text Size: {}", id, myCrawlStat.getTotalTextSize());
    }

    @Override
    public Object getMyLocalData() {
        return myCrawlStat;
    }

    @Override
    public void onBeforeExit() {
        dumpMyData();
    }

    /*
     * 这个方法决定了要抓取的URL及其内容,例子中只允许抓取“http://sh.ziroom.com/z/nl/”这个域的页面,
     * 不允许.css、.js和多媒体等文件
     *
     * @see edu.uci.ics.crawler4j.crawler.WebCrawler#shouldVisit(edu.uci.ics.
     * crawler4j.crawler.Page, edu.uci.ics.crawler4j.url.WebURL)
     */
    @Override
    public boolean shouldVisit(Page referringPage, WebURL url) {
        final String href = url.getURL().toLowerCase();

        if (FILTERS.matcher(href).matches() || !href.startsWith(URL_PREFIX)) {
            return false;
        }
        return true;
    }

    /*
     * 当URL下载完成会调用这个方法。你可以轻松获取下载页面的url, 文本, 链接, html,和唯一id等内容。
     *
     * @see
     * edu.uci.ics.crawler4j.crawler.WebCrawler#visit(edu.uci.ics.crawler4j.
     * crawler.Page)
     */
    @Override
    public void visit(Page page) {
        final String url = page.getWebURL().getURL();
        System.out.println("-----------爬取路径:" + url);
        myCrawlStat.incProcessedPages();
        if (page.getParseData() instanceof HtmlParseData) {
            final HtmlParseData htmlParseData = (HtmlParseData) page.getParseData();
            final Set<WebURL> links = htmlParseData.getOutgoingUrls();
            try {
                linkToCsv(links);
            } catch (final IOException e2) {
                // TODO Auto-generated catch block
                e2.printStackTrace();
            }
            myCrawlStat.incTotalLinks(links.size());
            try {
                myCrawlStat.incTotalTextSize(htmlParseData.getText().getBytes("UTF-8").length);
            } catch (final UnsupportedEncodingException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            final String html = htmlParseData.getHtml();

            final Document doc = Jsoup.parse(html);

            final Elements contents = doc.select("li[class=clearfix]");

            for (final Element c : contents) {
                // 图片
                final String img = c.select(".img img").first().attr("src");
                //System.out.println("图片:" + img);

                // 地址
                final Element txt = c.select("div[class=txt]").first();
                final String arr1 = txt.select("h3 a").first().text();
                final String arr2 = txt.select("h4 a").first().text();
                final String arr3 = txt.select("div[class=detail]").first().text();

                final String arr = arr1.concat(arr1 + ",").concat(arr2 + ",").concat(arr3);
                //System.out.println("地址:" + arr);
                // 说明
                final String rank = txt.select("p").first().text();
                //System.out.println("说明:" + rank);

                // 价格
                final String pirce = c.select("p[class=price]").first().text();

                try {
                	cw = new CsvWriter(new FileOutputStream(csv, true),',',Charset.forName("UTF-8"));
                    cw.write(img);
                    cw.write(pirce);
                    cw.write(arr);
                    cw.write(rank);
                    cw.endRecord();
                    cw.flush();
                    cw.close();
                } catch (final IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private void linkToCsv(Set<WebURL> links) throws IOException {
    	 cw2 = new CsvWriter(new FileOutputStream(csv2, true),',',Charset.forName("UTF-8"));
        for (final WebURL webURL : links) {
            cw2.write(webURL.getURL());
        }
        cw2.flush();
        cw2.endRecord();
        cw2.close();

    }
}

实体类

package com.ninemax.utils.Crawler;
public class CrawlStat {
    private long totalLinks;
    private int totalProcessedPages;
    private long totalTextSize;

    public long getTotalLinks() {
        return totalLinks;
    }

    public int getTotalProcessedPages() {
        return totalProcessedPages;
    }

    public long getTotalTextSize() {
        return totalTextSize;
    }

    public void incProcessedPages() {
        this.totalProcessedPages++;
    }

    public void incTotalLinks(int count) {
        this.totalLinks += count;
    }

    public void incTotalTextSize(int count) {
        this.totalTextSize += count;
    }

    public void setTotalLinks(long totalLinks) {
        this.totalLinks = totalLinks;
    }

    public void setTotalProcessedPages(int totalProcessedPages) {
        this.totalProcessedPages = totalProcessedPages;
    }

    public void setTotalTextSize(long totalTextSize) {
        this.totalTextSize = totalTextSize;
    }
}

运行结果

企鹅交流群:260052172(大神莫入)

 

本文转载自:

BK灬

BK灬

粉丝 46
博文 343
码字总数 142562
作品 0
朝阳
后端工程师
私信 提问
加载中

评论(2)

BK灬
BK灬

引用来自“宋鑫001”的评论

bucuo
:bowtie:
宋鑫001
宋鑫001
bucuo
5个python爬虫教材,让小白也有爬虫可写,含视频教程!

认识爬虫   网络爬虫,如果互联网是一张蜘蛛网,网络爬虫既是一个在此网上爬行的蜘蛛,爬了多少路程即获取到多少数据。 python写爬虫的优势   其实以上功能很多语言和工具都能做,但是用...

柯西带你学编程
2018/06/12
0
0
求问一些毕设方面的问题 有关网络爬虫 文本分类的

一、课题的任务内容: 证券行业受外界信息影响巨大,网络是信息的一个重要来源,基于web的信息挖掘可以有效的获取影响证券市场的各类信息。 1. 分析影响证券行业的信息关键词 2. 利用网络蜘蛛...

sloth
2012/04/20
402
2
一步一步教你用 Vue.js + Vuex 制作专门收藏微信公众号的 app

写于 2016.06.30 只看不赞,或者只收藏不赞的都是耍流氓,放学别走,我找我哥收拾你们。 项目地址:github.com/jrainlau/we… 下载&运行 项目介绍 我在微信上关注了不少的公众号,经常浏览里...

Jrain
2018/12/12
0
0
网络爬虫基础

网络爬虫 网络爬虫(Computer Robot)(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。另外一些不...

白志华
2016/01/05
280
0
我投了份简历,接到了十八个骚扰电话

都说金三银四,最近打算换工作的苏大强(蹭热点式化名)在各大招聘平台挂上了自己的简历。谁知道刚过两天就接到了十八个骚扰电话,其中只有两个来自猎头。 在接起第十八个贷款推广骚扰电话后...

又田
03/27
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Class 文件结构

https://www.cnblogs.com/honghuzidelaoren/p/3622021.html

Java搬砖工程师
8分钟前
0
0
未分类资料

$ Inside the Linux Kernel 与知乎出产 一张漫画看懂Linux系统结构

十万猛虎下画山
9分钟前
0
0
Android人脸识别Demo竖屏YUV方向调整和图片保存

本博客包含三个常用方法,用于盛开Android版人脸识别Demo中竖屏使用时送入yuv数据,但一直无法识别的情况。 1.首先可以尝试顺时针旋转90°或270°,然后送入识别SDK。 2.旋转方向后依然无法识...

是哇兴哥棒棒哒
13分钟前
0
0
选择阿里云数据库HBase版十大理由

根据Gartner的预计,全球非关系型数据库(NoSQL)在2020~2022预计保持在30%左右高速增长,远高于数据库整体市场。 阿里云数据库HBase版也是踏着技术发展的节奏,伴随着NoSQL和大数据技术的兴...

阿里云云栖社区
25分钟前
0
0
平滑与滤波

五种常见的平滑滤波器: (1)方框型滤波器: 顾名思义,方框型滤波器就是用一个方框型的kernel跟二维图像进行卷积,其核定义如下: kernel= 其中, a = 1 当该滤波器非归一化滤波器 (1) a=...

yepanl
31分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部