大白痴学习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 实现了FilePersistentBase,Pipeline接口,把数据存到文件里,每个URL单独保存到一个页面,以URL的MD5结果作为文件名
主要成员变量
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文件夹,一些实用工具
UrlUtils:url和html的工具
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的更多相关文章
- 大数据学习系列之四 ----- Hadoop+Hive环境搭建图文详解(单机)
引言 在大数据学习系列之一 ----- Hadoop环境搭建(单机) 成功的搭建了Hadoop的环境,在大数据学习系列之二 ----- HBase环境搭建(单机)成功搭建了HBase的环境以及相关使用 ...
- 大数据学习系列之五 ----- Hive整合HBase图文详解
引言 在上一篇 大数据学习系列之四 ----- Hadoop+Hive环境搭建图文详解(单机) 和之前的大数据学习系列之二 ----- HBase环境搭建(单机) 中成功搭建了Hive和HBase的环 ...
- 大数据学习系列之六 ----- Hadoop+Spark环境搭建
引言 在上一篇中 大数据学习系列之五 ----- Hive整合HBase图文详解 : http://www.panchengming.com/2017/12/18/pancm62/ 中使用Hive整合 ...
- 大数据学习系列之七 ----- Hadoop+Spark+Zookeeper+HBase+Hive集群搭建 图文详解
引言 在之前的大数据学习系列中,搭建了Hadoop+Spark+HBase+Hive 环境以及一些测试.其实要说的话,我开始学习大数据的时候,搭建的就是集群,并不是单机模式和伪分布式.至于为什么先写单 ...
- 大数据学习系列之九---- Hive整合Spark和HBase以及相关测试
前言 在之前的大数据学习系列之七 ----- Hadoop+Spark+Zookeeper+HBase+Hive集群搭建 中介绍了集群的环境搭建,但是在使用hive进行数据查询的时候会非常的慢,因为h ...
- 大数据学习之Linux进阶02
大数据学习之Linux进阶 1-> 配置IP 1)修改配置文件 vi /sysconfig/network-scripts/ifcfg-eno16777736 2)注释掉dhcp #BOOTPR ...
- 大数据学习之Linux基础01
大数据学习之Linux基础 01:Linux简介 linux是一种自由和开放源代码的类UNIX操作系统.该操作系统的内核由林纳斯·托瓦兹 在1991年10月5日首次发布.,在加上用户空间的应用程序之后 ...
- 大数据学习:storm流式计算
Storm是一个分布式的.高容错的实时计算系统.Storm适用的场景: 1.Storm可以用来用来处理源源不断的消息,并将处理之后的结果保存到持久化介质中. 2.由于Storm的处理组件都是分布式的, ...
- 大数据学习系列之—HBASE
hadoop生态系统 zookeeper负责协调 hbase必须依赖zookeeper flume 日志工具 sqoop 负责 hdfs dbms 数据转换 数据到关系型数据库转换 大数据学习群119 ...
随机推荐
- 转: 如何实现jQuery的Ajax文件上传
[PHP文件上传] 在开始之前,我觉得是有必要把通WEB上传文件的原理简单说一下的.实际上,在这里不管是PHP,JSP,还是ASP处理上传的文件,其实都是WEB早已把文件上传到服务器了,我们只是运用上 ...
- Android 开发之网易云音乐(或QQ音乐)的播放界面转盘和自定义SeekBar的实现
这个东西我在eoeAndroid上首发的,但没有详细的实现说明:http://www.eoeandroid.com/thread-317901-1-1.html 在csdn上进行详细的说明吧.(同时上 ...
- Java简单记录
XML指令: <?xml version="1.0" encoding="UTF-8" standalone="no" ?> & ...
- week4_motion_of_ball_1(小球运动)——最基本
# Ball motion with an explicit timer import simplegui # Initialize globals width = 600 height = 600 ...
- Python 模块(五)
目录 模块介绍 time &datetime模块 random json & picle 一.模块介绍 在我们日常的程序开发过程中,随着代码越写越多,在单个文件里的代码就会越来越长,越 ...
- Ubuntu上搭建DokuWiki
1.准备工作 1) 安装Apache sudo apt-get install apache2 2)在浏览器中输入http://localhost 如果现实It works则说明Apache安装成功, ...
- html中事件处理中的this和event对象
在用js编写页面事件处理代码时,会经常涉及到this和event对象,但有时在采用不同的事件处理,尤其是在与自定义的对象关联时,这些对象的指向变的有些复杂. 本文来详细介绍下各种场景下 这些对象 真正 ...
- Java学习笔记:内部类/匿名内部类的全面介绍
编写java程序时,一般一个类(或者接口)都是放在一个独立的java文件中,并且类名同文件名(如果类是public的,类名必须与文件名一致:非public得,无强制要求).如果想把多个java类放在一 ...
- php利用iframe实现无刷新文件上传功能
上传原理很简单就是利用表单的打开方式为iframe的name名,这样就可以在当前页面的iframe打来了,实现文件上传,再利用js返回上传结果. form target .在 action 属性中规定 ...
- pojg487-3279电话号码转换(字符映射)
http://poj.grids.cn/practice/2974 注意输入中连字符可以任意添加和删除. 描述企业喜欢用容易被记住的电话号码.让电话号码容易被记住的一个办法是将它写成一个容易记住的单词 ...