[关闭]
@xiaoxiaowang 2018-07-19T14:10:03.000000Z 字数 3167 阅读 771

VW-Crawler

Java 爬虫 开源


VW-Crawler

Central

背景

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

特点

使用

使用Maven

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

  1. <dependency>
  2. <groupId>com.github.vector4wang</groupId>
  3. <artifactId>vw-crawler</artifactId>
  4. <version>${last.version}</version>
  5. </dependency>

离线使用

可以在项目主页的release下载最新版本jar,然后导入自己的项目中。

步骤

各环节均支持自定义

示例

抓取CSDN某用户的博客内容

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

  1. new VWCrawler.Builder()
  2. // 配置参数
  3. .setHeader("User-Agent",
  4. "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.108 Safari/537.36") // 设置请求头
  5. .setUrl("https://blog.csdn.net/qqhjqs") // 设置爬虫起始地址
  6. .setThreadCount(10) // 设置几个线程抓取数据
  7. .setTimeOut(5000) // 设置超时时间
  8. // 抽象正则
  9. .setTargetUrlRex("https://blog.csdn.net/qqhjqs/article/details/[0-9]+") // 设置目标页面url的正则表达式
  10. // 解析页面
  11. .setPageParser(new CrawlerService<Blog>() {
  12. /**
  13. * 有的url可能在某个场景下不需要可在此处理
  14. * 默认返回false,可以不做处理
  15. * @param url 即将要抓取的url
  16. * @return
  17. */
  18. @Override
  19. public boolean isExist(String url) {
  20. if ("https://blog.csdn.net/qqhjqs/article/details/79101846".equals(url)) {
  21. return true;
  22. }
  23. return false;
  24. }
  25. /**
  26. * 有的页面有WAF,可以再真正解析前,做个判断,遇到特殊标志的直接可以跳过
  27. * 默认返回true,可以不做处理
  28. * @param document 即将要解析的document
  29. * @return
  30. */
  31. @Override
  32. public boolean isContinue(Document document) {
  33. if ("最近和未来要做的事 - CSDN博客".equals(document.title())) {
  34. System.out.println("模拟遇到WAF此页面不做解析");
  35. return false;
  36. }
  37. return true;
  38. }
  39. /**
  40. * 目标页面的doc对象,还有通过注解处理后的对象
  41. * @param doc 文档内容
  42. * @param pageObj 封装的对象
  43. */
  44. @Override
  45. public void parsePage(Document doc, Blog pageObj) {
  46. // 可进行二次处理
  47. pageObj.setReadNum(pageObj.getReadNum().replace("阅读数:", ""));
  48. }
  49. // 保存数据
  50. /**
  51. * 可以做保存对象的处理
  52. * @param pageObj 页面对象
  53. */
  54. @Override
  55. public void save(Blog pageObj) {
  56. System.out.println("save blog summery: " + pageObj.toString());
  57. }
  58. }) // 自定义解析service
  59. .build().start(); // 启动

配置页面数据对象的注解

  1. @CssSelector(selector = "#mainBox > main > div.blog-content-box > div.article-title-box > h1", resultType = SelectType.TEXT)
  2. private String title;
  3. @CssSelector(selector = "#mainBox > main > div.blog-content-box > div.article-info-box > div > span.time", dateFormat = "yyyy年MM月dd日 HH:mm:ss")
  4. private Date lastUpdateDate;
  5. @CssSelector(selector = "#mainBox > main > div.blog-content-box > div.article-info-box > div > div > span", resultType = SelectType.TEXT)
  6. private String readNum;

这里使用比较流行的注解方式,通过cssselector来获取节点数据可通过resultType来指定填充的是text还是html。

随便配置一下,就能抓取一个页面的数据

  1. new VWCrawler.Builder().setUrl("https://www.qiushibaike.com/").setPageParser(new CrawlerService() {
  2. @Override
  3. public void parsePage(Document doc, Object pageObj) {
  4. System.out.println(doc.toString());
  5. }
  6. @Override
  7. public void save(Object pageObj) {
  8. }
  9. }).build().start();

更多

更多的示例可移步more

抓取了足够多的数据,我们可以拿数据做很多事,比如统计各大人才网的职位分布图
职位分布图
有关ES的可移步这里

最后

轮子造多了就想着造一个模具,代码写多了就想写个框架,一样的道理。帮助他人,顺便提升自己。框架还有很多需要完善的地方,希望使用者多多提issue,也希望大家提PR~~~

源码

欢迎大家访问




添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注