Java 爬虫框架 VW-Crawler

MIT
Java 查看源码»
跨平台
2018-07-30
BMHJQS

VW-Crawler

背景

自己一直对爬虫比较感兴趣,大学的毕业论文也是一个爬虫项目(爬教务处信息,然后做了个Android版教务管理系统,还获得了优秀毕业设计的称号),自那以后遇到自己感兴趣的网站就会去抓一下。前段时间工作上需要一些JD信息,我就从网上找了个开源的爬虫框架WebMagic,使用简单,易配置,功能也很强大,当然了也有些网站的数据不适合使用。前前后后写了不下十几个,慢慢的就想是不是可以把这些爬虫代码再抽象出来,做出一个简易的爬虫框架呢?于是就尝试去看WebMagic的源码,后来又发现了一个源码比较容易解读的爬虫框架XXL-CRAWLER,简单的分析了源码之后,开发自己一套爬虫框架的欲望更加强烈,于是在2017年底的时候就开始了开发,中间断断续续得停了写,写了停。直到最近8月底的时候才算出了一个版本,然后顺势把它放到了Maven公服仓库上。一个人的力量很薄弱,要想完善这个爬虫的健壮性、可用性和易扩展性还需要大家的力量!

特点

  •  语言: Java开发,框架比较简单,多处使用的是接口编程,是学习Java不错的例子

  •  难度: 及其简单,配置一下,写个解析逻辑,整理下保存方法,就OK了

  •  轻量: 使用Jsoup做默认的下载器,依赖性较低

  •  线程: 可自主**设置线程**数抓取,提高抓取效率

  •  重试: 支持失败重试,次数可以自定义

  •  代理: 支持配置**代理池**,默认随机使用代理IP,也可自定义算法获取

  •  去重: **双重去重**,默认对URL去重,也可以定义第二层去重逻辑

  •  控制: 可**自主控制**是否需要解析页面,减少资源的使用

  •  精准: 通过设置URL的正则来**精准**的解析每一个URL

  •  扩展: 几乎每一个环节都可以自定义

使用

使用Maven

http://search.maven.org上使用最新的版本
在pom中引入

<dependency>
    <groupId>com.github.vector4wang</groupId>
    <artifactId>vw-crawler</artifactId>
    <version>${last.version}</version>
</dependency>

离线使用

可以在项目主页的[release](https://github.com/vector4wang/vw-crawler/releases)下载最新版本jar,然后导入自己的项目中。

步骤

  1.  配置参数

  2.  抽象正则

  3.  解析页面

  4.  保存数据

各环节均支持自定义

示例

抓取CSDN某用户的博客内容

设置爬虫的基本配置,如User-Agent、起始地址、目标页面的url正则表达式、线程数和超时时间等

new VWCrawler.Builder()
        // 配置参数
        .setHeader("User-Agent",
                "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.108 Safari/537.36") // 设置请求头
        .setUrl("https://blog.csdn.net/qqhjqs") // 设置爬虫起始地址
        .setThreadCount(10) // 设置几个线程抓取数据
        .setTimeOut(5000) // 设置超时时间

        // 抽象正则
        .setTargetUrlRex("https://blog.csdn.net/qqhjqs/article/details/[0-9]+") // 设置目标页面url的正则表达式

        // 解析页面
        .setPageParser(new CrawlerService<Blog>() {

            /**
             * 有的url可能在某个场景下不需要可在此处理
             * 默认返回false,可以不做处理
             * @param url 即将要抓取的url
             * @return
             */
            @Override
            public boolean isExist(String url) {
                if ("https://blog.csdn.net/qqhjqs/article/details/79101846".equals(url)) {
                    return true;
                }
                return false;
            }

            /**
             * 有的页面有WAF,可以再真正解析前,做个判断,遇到特殊标志的直接可以跳过
             * 默认返回true,可以不做处理
             * @param document 即将要解析的document
             * @return
             */
            @Override
            public boolean isContinue(Document document) {
                if ("最近和未来要做的事 - CSDN博客".equals(document.title())) {
                    System.out.println("模拟遇到WAF此页面不做解析");
                    return false;
                }
                return true;
            }

            /**
             * 目标页面的doc对象,还有通过注解处理后的对象
             * @param doc 文档内容
             * @param pageObj 封装的对象
             */
            @Override
            public void parsePage(Document doc, Blog pageObj) {
                // 可进行二次处理
                pageObj.setReadNum(pageObj.getReadNum().replace("阅读数:", ""));
            }


            // 保存数据

            /**
             * 可以做保存对象的处理
             * @param pageObj 页面对象
             */
            @Override
            public void save(Blog pageObj) {
                System.out.println("save blog summery: " + pageObj.toString());
            }
        }) // 自定义解析service


        .build().start(); // 启动

配置页面数据对象的注解

@CssSelector(selector = "#mainBox > main > div.blog-content-box > div.article-title-box > h1", resultType = SelectType.TEXT)
private String title;

@CssSelector(selector = "#mainBox > main > div.blog-content-box > div.article-info-box > div > span.time", dateFormat = "yyyy年MM月dd日 HH:mm:ss")
private Date lastUpdateDate;

@CssSelector(selector = "#mainBox > main > div.blog-content-box > div.article-info-box > div > div > span", resultType = SelectType.TEXT)
private String readNum;

这里使用比较流行的注解方式,通过cssselector来获取节点数据可通过resultType来指定填充的是text还是html。随便配置一下,就能抓取一个页面的数据

new VWCrawler.Builder().setUrl("https://www.qiushibaike.com/").setPageParser(new CrawlerService() {
    @Override
    public void parsePage(Document doc, Object pageObj) {
        System.out.println(doc.toString());
    }

    @Override
    public void save(Object pageObj) {

    }
}).build().start();
加载中

评论(2)

_vince
_vince
我还是喜欢jodd里面的jerry ,号称jquer in java
BMHJQS
BMHJQS 软件作者
欢迎到github上获取最新代码

暂无资讯

暂无问答

一套简单的java爬虫框架VW-Crawler发布啦!!!

VW-Crawler 背景 自己一直对爬虫比较感兴趣,大学的毕业论文也是一个爬虫项目(爬教务处信息,然后做了个Android版教务管理系统,还获得了优秀毕业设计的称号),自那以后遇到自己感兴趣的网站...

07/28 14:04
16
0
SQL 基础--> 视图(CREATE VIEW)

--================================ -- SQL 基础--> 视图(CREATE VIEW) --================================ 视图: 从表中抽出来的逻辑上相关的数据集合 视图其实就是一条查询SQL语句,用于...

2012/03/09 16:25
16
0
PL/SQL --> INSTEAD OF 触发器

--============================== -- PL/SQL --> INSTEAD OF 触发器 --============================== INSTEAD OF 触发器常用于管理编写不可更新的视图,INSTEAD-OF触发器必须是行级的。 ...

2012/03/09 16:22
20
0
基于Quorum投票的冗余控制算法

仲裁算法 算法概述 Quorom 机制,是一种分布式系统中常用的,用来保证数据冗余和最终一致性的投票算法,其主要数学思想来源于鸽巢原理。 在有冗余数据的分布式存储系统当中,冗余数据对象会在...

2016/04/13 22:10
10
1
python开源爬虫框架scrapy源码解析(三)

从本节开始将介绍scrapy最核心的部分crawl命令的实现,通过crawl命令可以启动一个爬虫工程.接下来我将介绍scrapy的引擎、调度器、下载器等组件是如何协同工作的。

2016/03/30 22:14
287
1
百度语音使用步骤(语音识别接入流程)

请参考《百度语音开放平台使用指南》创建应用,开通服务并完成个性化设置。 引入编译需要的Framework: BDVRClient包含的功能以及需要的Framework有: 功能 framework名称 录音和播放 AudioT...

2016/03/03 11:23
212
2
css3中的一些特别的单位:em、rem、vw、vh、vmin、vmax

css3中一些特别单位的介绍。

2016/05/20 15:46
112
2
em,rem和vh

css3

2016/03/30 23:41
54
2

没有更多内容

加载失败,请刷新页面

返回顶部
顶部