摘要 webmagic 学习 从头

刚刚开始学,很多东西可能理解错了,还请各位指教

一些基本类:

Request包含要爬行的url和一些附加信息,是Page的一个成员变量

主要成员变量

String  url

Map<String, Object>  extras 存储附加信息

long  priority  优先级 值越大越优先

主要方法

Request(String url) { this.url = url; }构造函数

Request  setPriority(long  priority)  设置优先级需要PriorityScheduler管理

Object  getExtra(String key)获取想要的附加信息 通过key在map里寻找

Request  putExtra(String key, Object value) 添加一组附加信息

ResultItems包含抓取的结果,是Page类的一个成员变量,并且要在pipeline中处理

主要成员变量

Map<String, Object> fields  是HashMap

Request  request;

boolean  skip 是否要跳过这条结果,跳过了就不会被pipeline处理

主要方法

<T> T get(String key)  通过key获取相应值

Map<String, Object>  getAll() { return fields; }

ResultItems  put(String key, T value) 给当前对象添加一对值就是field添加记录

Request  getRequest() { return request; }

Page包含页面抽取的结果和要去取的URL

主要成员变量

Request  request;  主要就是url对象

ResultItems  resultItems  抓取的结果,用于持久化

Html  html;

String  rawText;

Selectable  url;

Int  statusCode;

List<Request>  targetRequests

主要方法

Selectable  getUrl(){ return url;  } 获取当前页url

Html  getHtml()获取当前页内容

ResultItems  getResultItems(){return resultItems; }获得抓取的结果以在Pipeline持久化里使用

void  putField(String, Object)保存抓取的结果

void  addTargetRequests(List<String>  requests) 添加url 去抓取

void  addTargetRequests(List<String>  requests, long priority) 添加url 去抓取

void  addTargetRequest(String  requestString) 添加url 去抓取

void  addTargetRequest(Request request) 添加request 去抓取

Site:包含爬虫的一些配置

主要成员变量

String  domain;

List<Request>  startRequests = new ArrayList<Request>();  爬虫开始的url

Map<String, String>  cookies = new LinkedHashMap<String, String>();

Map<String, String>  headers = new HashMap<String, String>()

String  userAgent;

String  charset;

int  sleepTime = 5000;

int  retryTimes = 0;

int  cycleRetryTimes = 0;

int  timeOut = 5000;

HttpHost  httpProxy

主要方法

Site me() { return new Site(); } 新生成一个Site

Site  addCookie(String name, String value)  说明Add a cookie with domain

Site  setDomain(String domain) 设置Site的domain

Site  addStartRequest(Request  startRequest) 添加一条url到开始集里

Site  addHeader(String key, String value) 为下载器设置一个http头

Task  toTask()转换为一个Task

Task:标识不同任务的接口(是个interface),没有成员变量

主要方法

String  getUUID() 获取一个task的唯一ID

Site    getSite()  获取一个task的Site

Spider:爬虫入口,包含Downloader   Scheduler  PageProcessor  and  Pipeline

主要成员变量

Downloader  downloader;

List<Pipeline>  pipelines = new ArrayList<Pipeline>();

Scheduler  scheduler = new QueueScheduler();

PageProcessor  pageProcessor;

List<Request>  startRequests;

Site  site;

String  uuid;

Logger logger = Logger.getLogger(getClass());

int  threadNum = 1;

主要方法

Spider  create(PageProcessor pageProcessor) 创建一个爬虫

Spider  startUrls(List<String> startUrls)添加开始集合 也就是给startRequests赋值

Spider  startRequest(List<Request>  startRequests) 添加开始集合,给startRequests赋值

Spider  scheduler(Scheduler scheduler)  设置scheduler(url管理器),给scheduler赋值

Spider  setScheduler(Scheduler scheduler) 设置scheduler(url管理器) ,给scheduler赋值

Spider  pipeline(Pipeline pipeline) 设置pipeline(持久化),给pipelines队列添加一条

Spider  addPipeline(Pipeline pipeline) 设置pipeline(持久化),给pipelines队列添加一条

Spider  clearPipeline() 清空pipeline

Spider  downloader(Downloader downloader) 设置downloader(下载器),给downloader赋值

Spider  setDownloader(Downloader downloader)设置downloader,给downloader赋值

void  test(String... urls) 该方法只抓取一个单独的页面,用于测试抽取效果

void  processRequest(Request request){  //核心处理流程

Page page = downloader.download(request, this);

pageProcessor.process(page);

extractAndAddRequests(page);

for (Pipeline pipeline : pipelines)

pipeline.process(page.getResultItems(), this);

}

一个简单例子

Spider.create(new SimplePageProcessor("http://my.oschina.net/",

"http://my.oschina.net/*blog/*")).run()

如果想把结果存到文件里怎么办呢?

Spider.create(new  SimplePageProcessor("http://my.oschina.net/",

"http://my.oschina.net/*blog/*")) .pipeline(new FilePipeline("/data/temp/webmagic/")).run();

使用FileCacheQueueScheduler在文件中存取url和游标以便关闭后重新继续开始

Spider.create(new SimplePageProcessor("http://my.oschina.net/",

"http://my.oschina.net/*blog/*"))

.scheduler(new FileCacheQueueScheduler("/data/temp/webmagic/cache/")).run();

webmagic四大模块代码解析

downloader文件件夹  ,download一般不用管

Downloader是一个接口

主要方法

Page  download(Request request, Task task);下载页面并存到Page对象

void  setThread(int threadNum); 设置线程数

HttpClientDownloader 继承Downloader接口

主要成员变量

Logger  logger = Logger.getLogger(getClass());

Map<String, CloseableHttpClient>  httpClients = new HashMap<String, CloseableHttpClient>();

HttpClientGenerator  httpClientGenerator = new HttpClientGenerator();

主要方法

Html  download(String url)  下载html

Html  download(String url, String charset)

Page  download(Request request, Task task) 实现接口方法

 

HttpClientGenerator 这个类是HttpClient产生器,就是工厂

主要成员变量

PoolingHttpClientConnectionManager  connectionManager;

主要方法

CloseableHttpClient   generateClient(Site site)

CloseableHttpClient   getClient(Site site)

HttpClientGenerator  setPoolSize(int poolSize)

void  generateCookie(HttpClientBuilder httpClientBuilder, Site site)

目前有几个Downloader的实现:

HttpClientDownloader

集成了Apache HttpClient的Downloader。Apache HttpClient(4.0后整合到HttpCompenent项目中)是强大的Java http下载器,它支持自定义HTTP头(对于爬虫比较有用的就是User-agent、cookie等)、自动redirect、连接复用、cookie保留、设置代理等诸多强大的功能。

SeleniumDownloader(这个文件里没有)

对于一些Javascript动态加载的网页,仅仅使用http模拟下载工具,并不能取到页面的内容。这方面的思路有两种:一种是抽丝剥茧,分析js的逻辑,再用爬虫去重现它;另一种就是:内置一个浏览器,直接获取最后加载完的页面。webmagic-selenium包中整合了Selenium到SeleniumDownloader,可以直接进行动态载页面的抓取。使用selenium需要安装一些native的工具,具体步骤可以参考作者的博文使用Selenium来抓取动态加载的页面

PageProcessor文件夹,页面分析及链接抽取,是我们使用的关键

PageProcessor是一个接口,用于定制爬虫,可定制启动url和一些设置,如何发现要抓取的url,数据要如何提取和存储

主要方法

void  process(Page page); 处理Page对象,提取URL,提取数据并存储

Site  getSite() 获取site 的一些设置信息

通过编写一个实现PageProcessor接口的类,就可以定制一个自己的爬虫,比如

public  class  GithubRepoPageProcesser implements  PageProcessor {

private  Site  site = Site.me().setRetryTimes(3).setSleepTime(100); //一些设置信息

@Override

public void  process(Page  page) { //通过正则表达式和Xpath来抓取

//要抓取的链接需要显示地添加

page.addTargetRequests(page.getHtml().links().regex("(https://github\\.com/\\w+/\\w+)").all());

//抓取规则

page.putField("author", page.getUrl().regex("https://github\\.com/(\\w+)/.*").toString());

page.putField("name", page.getHtml().xpath("//h1[@class='entry-title public']/strong/a/text()").toString());//text()仅当前标签文本,Text()包含子标签中的所有文本,allText()也包含子标签

if (page.getResultItems().get("name")==null){  page.setSkip(true);  } //skip this page

page.putField("readme", page.getHtml().xpath("//div[@id='readme']/tidyText()"));

}

@Override

public Site  getSite() {

return site;

}

public  static  void  main(String[]  args) {

Spider.create(new GithubRepoPageProcesser()).addUrl("https://github.com/code4craft").thread(5).run();

}

}

几种抓取方式

1.java正则表达式:这个不多讲 .  []  ()  等

2.Jsoup支持jquery中css selector的方式选取元素 :

String content = "blabla"; Document doc = JSoup.parse(content);  Elements links = doc.select("a[href]");

3. HtmlCleaner支持XPath的方式选取元素:

4.Xpath: tagNode.evaluateXPath("//a/@href ")

5.CSS选择:$("a[href]").attr("href")

webmagic主要实现了CSS Selector、XPath和正则表达式三种抓取方式,其实现放在Selector文件下

Scheduler文件夹,URL管理 主要有两个实现QueueScheduler和FileCacheQueueScheduler

 

Scheduler是一个接口,实现它可以管理要抓取的URL,还可以去重复

主要方法

void push(Request request, Task task)  添加一个要抓取的url

Request poll(Task task)  取出一个URL来爬行

 

QueueScheduler继承Scheduler接口,一个简单的内存队列,速度较快,并且是线程安全的

主要成员变量

Logger  logger = Logger.getLogger(getClass());

BlockingQueue<Request>  queue = new LinkedBlockingQueue<Request>();

Set<String>  urls = new HashSet<String>();

主要方法

void  push(Request request, Task task)  往queue里边添加一个request

Request  poll(Task task)  从queue里边弹出一个request

PriorityScheduler继承Scheduler接口,是一个文件队列,它可以用于耗时较长的下载任务,在任务中途停止后,下次执行仍然从中止的URL开始继续爬取。

主要成员变量

Logger  logger = Logger.getLogger(getClass());

BlockingQueue<Request>  noPriorityQueue = new  LinkedBlockingQueue<Request>();

Set<String>  urls = new HashSet<String>();

主要方法

void  push(Request request, Task task) 添加一个request

Request  poll(Task task) 弹出一个request

Pipeline文件夹,用于后续处理和持久化 主要有四个实现

Pipeline是一个接口,用于持久化  离线处理  只有一个方法

  主要方法

void  process(ResultItems resultItems, Task  task) 从resultItems通过get(key)得到数据

CollectorPipeline<T>也是一个接口,且继承了Pipeline,新增了一个方法

主要方法

List<T>  getCollected(); 获取收集到的所有信息

ConsolePipeline 实现了Pipeline接口,把结果输出到控制台

public void process(ResultItems resultItems, Task task) {

System.out.println("get page: " + resultItems.getRequest().getUrl());

for (Map.Entry<String, Object> entry : resultItems.getAll().entrySet()) {

System.out.println(entry.getKey() + ":\t" + entry.getValue());

}

}

ResultItemsCollectorPipeline实现了CollectorPipeline<T>接口

主要成员变量

List<ResultItems>  collector = new  ArrayList<ResultItems>();

主要方法

public  synchronized  void  process(ResultItems resultItems, Task task) {

collector.add(resultItems);

}

public  List<ResultItems>  getCollected() {

return collector;

}

FilePipeline 实现了FilePersistentBasePipeline接口,把数据存到文件里,每个URL单独保存到一个页面,以URLMD5结果作为文件名

主要成员变量

Logger  logger = Logger.getLogger(getClass());

主要方法

FilePipeline() {  setPath("/data/webmagic/");  } 默认构造函数 设置了存储路径

FilePipeline(String  path) {  setPath(path);  } 自定义存储路径

void  process(ResultItems resultItems, Task task)

selector文件夹,算是PageProcessor的扩展吧,因为要集合很多选取方式

 

Selectable:接口 可选的文本

Selectable  xpath(String xpath);使用xpath选择

Selectable  $(String selector);  使用CSS选择

Selectable  $(String selector, String attrName); 使用CSS选择

Selectable  css(String selector); 使用CSS选择

Selectable  css(String selector, String attrName); 使用CSS选择

Selectable  regex(String regex);使用正则表达式选择group默认为1

Selectable  regex(String regex, int group); 使用正则表达式选择

Selectable  replace(String regex, String replacement);

Selectable  smartContent(); 选取smart content

Selectable  links(); 选取所有链接

PlainText:实现了Selectable接口

PlainText(List<String> strings)

PlainText(String text)

PlainText  create(String text)

Selectable  select(Selector selector, List<String> strings)

Selectable  selectList(Selector selector, List<String> strings)

Html:继承了PlainText

主要成员变量

Logger  logger = Logger.getLogger(getClass());

Document  document; 存储解析过的文档

boolean  init = false;

主要方法:给出新增的方法

Html(List<String> strings)

Html(String text)

Html(Document document)

void   initDocument() 简单的初始化方法

Html  create(String text)

String  selectDocument(Selector selector)

List<String>  selectDocumentForList(Selector selector)

String  getText()

Document  getDocument()

Selectors:一个抽象类

RegexSelector  regex(String expr)        RegexSelector  regex(String expr, int group)

CssSelector  $(String expr)              CssSelector  $(String expr, String attrName)

XpathSelector  xpath(String expr)        XsoupSelector  xsoup(String expr)

AndSelector  and(Selector... selectors)    OrSelector  or(Selector... selectors)

SmartContentSelector  smartContent()

Selector:接口,文本抽取器 就两个方法

String  select(String text) 抽取单条结果,若有多个,只有第一个被选择

List<String>  selectList(String text) 抽取所有结果

ElementSelector:接口   针对html elements

String select(Element element);

List<String> selectList(Element element);

RegexSelector:实现Selector接口,使用正则表达式抽取

主要成员变量

String  regexStr;

Pattern  regex;

int  group = 1;

主要方法

RegexSelector(String regexStr, int group)构造

RegexSelector(String regexStr)构造

String  select(String text)重写

List<String>  selectList(String text)重写

RegexResult  selectGroup(String text)

List<RegexResult>  selectGroupList(String text)

XpathSelector:实现Selector接口,使用Xpath抽取

主要成员变量

String  xpathStr;

主要成员方法

XpathSelector(String xpathStr)

String  select(String text)重写

List<String>  selectList(String text)重写

ReplaceSelector:实现Selector接口,重置选择器

主要成员变量

String  regexStr;

String  replacement;

Pattern  regex;

主要成员方法

ReplaceSelector(String regexStr, String replacement)

String  select(String text)重写

List<String>  selectList(String text)重写

AndSelector:实现Selector接口,所有选择器以管道式安排,后一个用前一个的结果

主要成员变量

List<Selector>  selectors = new ArrayList<Selector>()

主要成员方法

AndSelector(Selector... selectors)

AndSelector(List<Selector> selectors)

String  select(String text)重写

List<String>  selectList(String text)重写

OrSelector:实现Selector接口,所有提取器独自工作,提取的结果将会整合起来

主要成员变量

List<Selector>  selectors = new ArrayList<Selector>()

主要成员方法

OrSelector(Selector... selectors)

OrSelector(List<Selector> selectors)

String  select(String text)重写

List<String>  selectList(String text)重写

OrSelector:实现Selector接口,所有提取器独自工作,提取的结果将会整合起来

主要成员变量

List<Selector>  selectors = new ArrayList<Selector>()

主要成员方法

OrSelector(Selector... selectors)

OrSelector(List<Selector> selectors)

String  select(String text)重写

List<String>  selectList(String text)重写

BaseElementSelector:抽象类 继承于Selector, ElementSelector

String  select(String text)重写

List<String>  selectList(String text)重写

CssSelector:继承BaseElementSelector   CSS selector. Based on Jsoup

主要成员变量

String  selectorText;

String  attrName;

主要成员方法

CssSelector(String selectorText)

CssSelector(String selectorText, String attrName)

String getValue(Element element)

String  select(String text)重写

List<String>  selectList(String text)重写

XsoupSelector:继承BaseElementSelector   XPath selector based on Xsoup

主要成员变量

XPathEvaluator xPathEvaluator;

主要成员方法

XsoupSelector(String xpathStr)

String  select(String text)重写

List<String>  selectList(String text)重写

例如,我已经下载了一个页面,现在要抽取某个区域的所有包含"blog"的链接,我可以这样写:

String content = "blabla"; //content是用别的爬虫工具抽取到的正文

List<String>  links = Html.create(content)

.$("div.title")  //css 选择,Java里虽然很少有$符号出现,不过貌似$作为方法名是合法的

.xpath("//@href")  //提取链接

.regex(".*blog.*") //正则匹配过滤

.all(); //转换为string列表

utils文件夹,一些实用工具

UrlUtilsurlhtml的工具

  Pattern patternForProtocal = Pattern.compile("[\\w]+://")

Pattern patternForCharset = Pattern.compile("charset\\s*=\\s*['\"]*([^\\s;'\"]*)");

Pattern patternForHref = Pattern.compile("(<a[^<>]*href=)[\"']{0,1}([^\"'<>\\s]*)[\"']{0,1}", Pattern.CASE_INSENSITIVE);

String canonicalizeUrl(String url, String refer)

String getHost(String url)

String removeProtocol(String url)

String getDomain(String url)

String fixAllRelativeHrefs(String html, String url)

List<Request> convertToRequests(Collection<String> urls)

List<String> convertToUrls(Collection<Request> requests)

String getCharset(String contentType)

ThreadUtils

  ExecutorService newFixedThreadPool(int threadSize)

NumberUtils:抽象类

  int compareLong(long o1, long o2)

FilePersistentBase:文件持久化的基本对象

String path

String PATH_SEPERATOR = "/"

String getPath()

void checkAndMakeParentDirecotry(String fullName)

File getFile(String fullName)

void setPath(String path)

EnvironmentUtil

   String USE_XSOUP = "xsoup"

boolean useXsoup()

void  setUseXsoup(boolean useXsoup)

大白痴学习webmagic的更多相关文章

  1. 大数据学习系列之四 ----- Hadoop+Hive环境搭建图文详解(单机)

    引言 在大数据学习系列之一 ----- Hadoop环境搭建(单机) 成功的搭建了Hadoop的环境,在大数据学习系列之二 ----- HBase环境搭建(单机)成功搭建了HBase的环境以及相关使用 ...

  2. 大数据学习系列之五 ----- Hive整合HBase图文详解

    引言 在上一篇 大数据学习系列之四 ----- Hadoop+Hive环境搭建图文详解(单机) 和之前的大数据学习系列之二 ----- HBase环境搭建(单机) 中成功搭建了Hive和HBase的环 ...

  3. 大数据学习系列之六 ----- Hadoop+Spark环境搭建

    引言 在上一篇中 大数据学习系列之五 ----- Hive整合HBase图文详解 : http://www.panchengming.com/2017/12/18/pancm62/ 中使用Hive整合 ...

  4. 大数据学习系列之七 ----- Hadoop+Spark+Zookeeper+HBase+Hive集群搭建 图文详解

    引言 在之前的大数据学习系列中,搭建了Hadoop+Spark+HBase+Hive 环境以及一些测试.其实要说的话,我开始学习大数据的时候,搭建的就是集群,并不是单机模式和伪分布式.至于为什么先写单 ...

  5. 大数据学习系列之九---- Hive整合Spark和HBase以及相关测试

    前言 在之前的大数据学习系列之七 ----- Hadoop+Spark+Zookeeper+HBase+Hive集群搭建 中介绍了集群的环境搭建,但是在使用hive进行数据查询的时候会非常的慢,因为h ...

  6. 大数据学习之Linux进阶02

    大数据学习之Linux进阶 1-> 配置IP 1)修改配置文件 vi /sysconfig/network-scripts/ifcfg-eno16777736 2)注释掉dhcp #BOOTPR ...

  7. 大数据学习之Linux基础01

    大数据学习之Linux基础 01:Linux简介 linux是一种自由和开放源代码的类UNIX操作系统.该操作系统的内核由林纳斯·托瓦兹 在1991年10月5日首次发布.,在加上用户空间的应用程序之后 ...

  8. 大数据学习:storm流式计算

    Storm是一个分布式的.高容错的实时计算系统.Storm适用的场景: 1.Storm可以用来用来处理源源不断的消息,并将处理之后的结果保存到持久化介质中. 2.由于Storm的处理组件都是分布式的, ...

  9. 大数据学习系列之—HBASE

    hadoop生态系统 zookeeper负责协调 hbase必须依赖zookeeper flume 日志工具 sqoop 负责 hdfs dbms 数据转换 数据到关系型数据库转换 大数据学习群119 ...

随机推荐

  1. (C)高级排序法

    1.快速排序法 //方法1 从大到小 #include <iostream.h> void run(int* pData,int left,int right) { int i,j; in ...

  2. 字符串操作函数<string.h>相关函数strcpy,strcat,等源码。

    首先说一下源码到底在哪里找. 我们在文件中包含<cstring>时,如果点击右键打开文档, 会打开cstring,我们会发现路径为: D:\Program Files\visual stu ...

  3. 链接分析算法之:SALSA算法

    链接分析算法之:SALSA算法 SALSA算法的初衷希望能够结合PageRank和HITS算法两者的主要特点,既可以利用HITS算法与查询相关的特点,也可以采纳PageRank的“随机游走模型”,这是 ...

  4. Codeforces Round #198 (Div. 2) B. Maximal Area Quadrilateral

    B. Maximal Area Quadrilateral time limit per test 1 second memory limit per test 256 megabytes input ...

  5. 《Android第一行代码》笔记

    学习Android开发差点儿相同有两年时间了.期间也做了大大小小的一些项目.近来抽出闲暇想把Android基础强化一下,之前在网上看到了郭霖郭大神的几篇博客.从中受益不少.于是花了近一周时间看完了郭神 ...

  6. c++特殊函数

    C++中NULL不能写作小写,NULL的值为零,也可以写作0 在自己写的复制构造函数中不改变原对象,所以传进来的参数可以设为const类型的,这样可以保证传进来的对象不被改变 比如A(const A ...

  7. CentOS 6.4安装(超级详细图解教程)

    链接地址:http://www.osyunwei.com/archives/5855.html CentOS 6.4安装(超级详细图解教程) 附:CentOS 6.4下载地址 32位:http://m ...

  8. Android短信拦截和电话拦截

    MainActivity: package com.wyl.bctest; import android.support.v7.app.ActionBarActivity; import androi ...

  9. [转] 8张图学习javascript

    学习的道路就是要不断的总结归纳,好记性不如烂笔头,so,下面将po出8张javascript相关的思维导图. 思维导图小tips:思维导图又叫心智图,是表达发射性思维的有效的图形思维工具 ,它简单却又 ...

  10. 用C语言打印出三角函数

    在网上看到一个实例,是用C 中的* 打印出三角函数cos #include<stdio.h> #include<math.h> int main() { double y; i ...