WebMagic是一款简单灵活的爬虫框架。基于它你可以很容易的编写一个爬虫。

简介

WebMagic项目代码分为核心和扩展两部分。核心部分(webmagic-core)是一个精简的、模块化的爬虫实现,而扩展部分则包括一些便利的、实用性的功能。WebMagic的架构设计参照了Scrapy,目标是尽量的模块化,并体现爬虫的功能特点。

WebMagic总体架构图如下:

WebMagic的四个组件

1.Downloader

Downloader负责从互联网上下载页面,以便后续处理。WebMagic默认使用了Apache HttpClient作为下载工具。

2.PageProcessor

PageProcessor负责解析页面,抽取有用信息,以及发现新的链接。WebMagic使用Jsoup作为HTML解析工具,并基于其开发了解析XPath的工具Xsoup。

在这四个组件中,PageProcessor对于每个站点每个页面都不一样,是需要使用者定制的部分。

3.Scheduler

Scheduler负责管理待抓取的URL,以及一些去重的工作。WebMagic默认提供了JDK的内存队列来管理URL,并用集合来进行去重。也支持使用Redis进行分布式管理。

除非项目有一些特殊的分布式需求,否则无需自己定制Scheduler。

4.Pipeline

Pipeline负责抽取结果的处理,包括计算、持久化到文件、数据库等。WebMagic默认提供了“输出到控制台”和“保存到文件”两种结果处理方案。

Pipeline定义了结果保存的方式,如果你要保存到指定数据库,则需要编写对应的Pipeline。对于一类需求一般只需编写一个Pipeline。

主要部分

WebMagic主要包括两个包,这两个包经过广泛实用,已经比较成熟:

webmagic-core

webmagic-core是WebMagic核心部分,只包含爬虫基本模块和基本抽取器。WebMagic-core的目标是成为网页爬虫的一个教科书般的实现。

webmagic-extension

webmagic-extension是WebMagic的主要扩展模块,提供一些更方便的编写爬虫的工具。包括注解格式定义爬虫、JSON、分布式等支持。

Maven依赖

WebMagic基于Maven进行构建,推荐使用Maven来安装WebMagic。在你自己的项目(已有项目或者新建一个)中添加以下依赖即可:

        <!--web magic爬虫--><dependency><groupId>us.codecraft</groupId><artifactId>webmagic-core</artifactId><version>0.7.3</version><exclusions><exclusion><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId></exclusion></exclusions></dependency><dependency><groupId>us.codecraft</groupId><artifactId>webmagic-extension</artifactId><version>0.7.3</version></dependency>

第一个爬虫项目

这里我以领导留言板的案例举例

网站页面如上,代码如下

Spider

Spider是爬虫启动的入口。在启动爬虫之前,我们需要使用一个PageProcessor创建一个Spider对象,然后使用run()进行启动。同时Spider的其他组件(Downloader、Scheduler、Pipeline)都可以通过set方法来进行设置。

package com.zcf.spider.crawler;import com.zcf.common.config.HttpConfig;
import com.zcf.spider.webmagic.DataPipeline;
import com.zcf.spider.webmagic.LiuYanBanProcessor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import us.codecraft.webmagic.Request;
import us.codecraft.webmagic.Spider;
import us.codecraft.webmagic.model.HttpRequestBody;
import us.codecraft.webmagic.utils.HttpConstant;import java.util.Date;
import java.util.HashMap;
import java.util.Map;/*** @Description TODO* @Author zcf* @Date 2020/5/20**/
@Component
public class LiuYanBanCrawler {private static final Logger LOG = LoggerFactory.getLogger(LiuYanBanCrawler.class);@Autowiredprivate LiuYanBanProcessor liuYanBanProcessor;@Autowiredprivate DataPipeline dataPipeline;/*** @Scheduled(cron = "0 0 0/2 * * ? ")          //  每2个小时执行一次* @Scheduled(cron = "0 0/1 * * * ?")           //  每1分钟执行一次* @Scheduled(cron = "0/30 * * * * ?")          //  每30秒执行一次*/@Async("taskExecutor")@Scheduled(cron = "0 0 0/2 * * ? ")public void governmentLiuYanBan(){LOG.info("执行开始时间:{}",new Date());int fid = 561;Map<String,Object> map = new HashMap<>();map.put("fid",fid);map.put("lastItem",0);String referer_url = "http://liuyan.people.com.cn/threads/list?fid="+fid;Request request = getRequest(map, referer_url);try {Thread.sleep(1000*10); // 休眠10秒Spider.create(liuYanBanProcessor).addRequest(request).thread(10).addPipeline(dataPipeline).run();LOG.info("执行结束时间:{}",new Date());} catch (InterruptedException e) {e.printStackTrace();}}private Request getRequest(Map<String, Object> map, String referer_url){Request request = new Request();request.setMethod(HttpConstant.Method.POST);request.addHeader("Referer",referer_url);request.addHeader("Origin","http://liuyan.people.com.cn");request.addHeader("User-Agent",HttpConfig.USER_AGENT);request.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");//构造map用于第一条请求的请求体request.setRequestBody(HttpRequestBody.form(map,"utf-8"));request.setUrl("http://liuyan.people.com.cn/threads/queryThreadsList");return request;}
}
Site

Site对站点本身的一些配置信息,例如编码、HTTP头、超时时间、重试策略等、代理等,都可以通过设置Site对象来进行配置。

package com.zcf.spider.webmagic;import com.alibaba.fastjson.JSONObject;
import com.zcf.common.config.HttpConfig;
import com.zcf.utils.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Request;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.model.HttpRequestBody;
import us.codecraft.webmagic.processor.PageProcessor;import java.util.*;/*** @Description TODO* @Author zcf* @Date 2020/5/19**/
@Component
public class LiuYanBanProcessor implements PageProcessor {private static final Logger LOG = LoggerFactory.getLogger(LiuYanBanProcessor.class);@Overridepublic void process(Page page) {List<Map<String,Object>> infoList = new ArrayList<>();// 获取返回结果JSONObject result  = JSONObject.parseObject(page.getJson().toString());Boolean flag = (Boolean) result.get("success");if(flag) {List<Map<String,Object>> responseData = (List) result.get("responseData");for (Map<String, Object> map : responseData) {Map<String, Object> info = new HashMap<>();Integer threadsCheckTime = (Integer) map.get("threadsCheckTime"); //时间戳String subject = (String) map.get("subject"); //标题Integer tid = (Integer) map.get("tid"); //文章IDString url = "http://liuyan.people.com.cn/threads/content?tid=" + tid;  //文章链接info.put("eventDate",threadsCheckTime);info.put("subject",subject);info.put("id",tid);info.put("url",url);LOG.info("时间戳的信息:{}",threadsCheckTime);LOG.info("标题的信息:{}",subject);LOG.info("文章ID的信息:{}",tid);LOG.info("文章链接的信息:{}",url);LOG.info("--------------------------------------------------------");infoList.add(info);}Map<String,Object> map = new HashMap<>();map.put("fid",responseData.get(responseData.size()-1).get("fid"));map.put("lastItem",responseData.get(responseData.size()-1).get("tid"));Integer threadsCheckTime = (Integer) responseData.get(responseData.size() - 1).get("threadsCheckTime");Date date1 = DateUtil.timestampToDateBySecond(Long.valueOf(threadsCheckTime));Date date2 = DateUtil.formatDateToDate(new Date());if(DateUtil.compareToDate(date1, date2)){ Request request = page.getRequest();request.setRequestBody(HttpRequestBody.form(map,"utf-8"));page.addTargetRequest(request);LOG.info("开始下一页");}}page.putField("data",infoList);}//配置爬虫信息private Site site = Site.me().setUserAgent(HttpConfig.USER_AGENT).setCharset("utf8").setTimeOut(10 * 1000).setRetryTimes(3).setRetrySleepTime(3000);@Overridepublic Site getSite() {return site;}
}
Pipeline

WebMagic用于保存结果的组件叫做Pipeline。

package com.zcf.spider.webmagic;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import us.codecraft.webmagic.ResultItems;
import us.codecraft.webmagic.Task;
import us.codecraft.webmagic.pipeline.Pipeline;import java.util.List;
import java.util.Map;
import java.util.Set;/*** @Description TODO* @Author zcf* @Date 2020/5/19**/
@Component
public class DataPipeline implements Pipeline {private static final Logger LOG = LoggerFactory.getLogger(DataPipeline.class);@Overridepublic void process(ResultItems resultItems, Task task) {List<Map<String,Object>> data = resultItems.get("data");LOG.info("总数据一共有{}条",data.size());// 后续数据的存储到数据库for (Map<String, Object> datum : data) {Set set = datum.keySet();LOG.info("--------------------------------------------------------");for (Object o : set){LOG.info("数据参数:{}的信息:{}",o,datum.get(o));}}}
}

运行一下,查看一下效果

在这里我想获取的数据都已经获取到了,当然每个页面的解析都不一样。
Jsoup是一个简单的HTML解析器,同时它支持使用CSS选择器的方式查找元素。
Xsoup是基于Jsoup开发的一款XPath解析器。
具体我们也可以参考官网。

WebMagic爬虫相关推荐

  1. java 使用webmagic 爬虫框架爬取博客园数据

    java 使用webmagic 爬虫框架爬取博客园数据存入数据库 学习记录   webmagic简介: WebMagic是一个简单灵活的Java爬虫框架.你可以快速开发出一个高效.易维护的爬虫. ht ...

  2. magicmatch java_签名图片一键批量生成 使用Java的Webmagic爬虫实现

    使用Webmagic爬虫实现的签名档一键生成 实现原理 这里爬取的网址是http://jiqie.zhenbi.com/c/ 然后获取到里面提交数据,提交地址,在对这些数据进行Post提交 解析htm ...

  3. 使用WebMagic爬虫框架爬取暴走漫画

    WebMagic是黄亿华先生开发的一款Java轻量级爬虫框架.我之所以选择WebMagic,因为它非常轻量级,可以学习爬虫的原理,而且用WebMagic非常容易进行功能扩展.也许你会听过另一个爬虫框架 ...

  4. WebMagic 爬虫框架问题描述

    问题描述 ❌Multiple bindings were found on the class path ❌Could not get a resource from the pool ✔️更换为Ht ...

  5. Java爬虫采集电影,java的webmagic爬虫实现爬出某电影网的下载地址

    事先说明不要用这技术,做一些违法的事情,网上玩爬虫的已经有还能多被抓了,此文就是为了学习webmagic 源码地址:https://github.com/smltq/spring-boot-demo/ ...

  6. WebMagic爬虫入门教程(二)一个完整的爬取动漫之家的实例

    (一)前言 我的上一篇博客已经说明如何爬取某一个网页的动漫数据,这里重点说一下一个完整的爬虫实例. 和上一篇文章相比,多了的就是动画种类,日文名什么的. 推荐这个爬取博客的:http://blog.c ...

  7. webmagic ajax,webmagic爬虫对静态页面,动态页面及js请求方式爬取的处理

    webmagic爬取网页数据,[分页爬取内容]见上一篇博文https://segmentfault.com/a/1190000020005655 webmagic的官方文档见: http://webm ...

  8. Webmagic 爬虫框架 爬取马蜂窝、携程旅游、汽车之家游记信息

    WebMagic学习 遇到的问题 Log4j错误 解决:在src目录下添加配置文件 log4j.properties log4j.rootLogger=INFO, stdout, filelog4j. ...

  9. WebMagic爬虫入门教程(三)爬取汽车之家的实例-品牌车系车型结构等

    本文使用WebMagic爬取汽车之家的品牌车系车型结构价格能源产地国别等:java代码 备注,只是根据url变化爬取的,没有使用爬取script页面具体的数据,也有反爬机制,知识简单爬取html标签 ...

最新文章

  1. 云服务器上mysql数据库环境安装配置
  2. repo-话说软件详细设计工具
  3. 总结一些调试的心得,ES7243
  4. docker rabbitmq_使用Docker集成Rabbitmq与安装elasticsearch教程
  5. 运行程序中的服务器错误是什么,登陆一个网站时,出现“/”应用程序中的服务器错误要怎么解决啊?? 爱问知识人...
  6. golang http client 使用gzip_Grpc介绍 — Go-Service To PHP-Client
  7. AE贝塞尔曲线生成插件Bezier Node mac版
  8. 25.构造ICMP数据包
  9. js根据身份证获取性别、年龄、出生日期及根据出生日期获取年龄
  10. 要注意工作中邮件的正式性
  11. 利用Python的sympy包求解一元三次方程
  12. iOS计算器:采用NSDecimalNumber 进行表达式的精准计算(计算字符串数学表达式)【案例:折扣计算器(完整demo源码)】
  13. 集成第三方单点登录JIRA(Colfluence同理)
  14. 95 费解的开关(递推)
  15. windows 多用户使用谷歌浏览器
  16. 2022中国老博会/老龄用品展/智慧养老展/北京老年产业展
  17. JavaFX+Jfoenix 学习笔记(五)--ContextMenu右键菜单
  18. 无法打开文件“libboost_thread-vc120-mt-gd-1_58.lib的解决办法
  19. sql查询当天交易总额最大的用户信息_京东用户行为数据分析(SQL)
  20. Linux 01 Liunx系统介绍

热门文章

  1. sscanf的具体用法
  2. Python format函数
  3. “一张车票,万般无奈”上网购票频频崩溃!12306再次排队等待中...还是技术惹的祸....
  4. 真实的爱情故事。。。
  5. Spring循环依赖产生原理
  6. linux查看防火墙有没关闭了,linux查看防火墙是否关闭的实例方法
  7. 数据结构(十二) -- 树(四) -- 霍夫曼树
  8. flink taskmanager 挂掉 报错No pooled slot available and request to ResourceManager for new slot failed
  9. ssh出现公钥错误问题的解决方法
  10. 平板上pyto软件_在安卓平板上利用随航功能——Twomon SE