Jsoup代码解读之七-实现一个CSS Selector
转载自 Jsoup代码解读之七-实现一个CSS Selector
当当当!终于来到了Jsoup的特色:CSS Selector部分。selector也是我写的爬虫框架webmagic开发的一个重点。附上一张street fighter的图,希望以后webmagic也能挑战Jsoup!
select机制
Jsoup的select包里,类结构如下:
在最开始介绍Jsoup的时候,就已经说过NodeVisitor
和Selector
了。Selector
是select部分的对外facade,而NodeVisitor
则是遍历树的底层API,CSS Selector也是根据NodeVisitor
实现的遍历。
Jsoup的select核心是Evaluator
。Selector所传递的表达式,会经过QueryParser
,最终编译成一个Evaluator
。Evaluator
是一个抽象类,它只有一个方法:
<!-- lang: java -->
public abstract boolean matches(Element root, Element element);
注意这里传入了root,是为了某些情况下对树进行遍历时用的。
Evaluator的设计简洁明了,所有的Selector表达式单词都会编译到对应的Evaluator。例如#xx
对应Id
,.xx
对应Class
,[]
对应Attribute
。这里补充一下w3c的CSS Selector规范:http://www.w3.org/TR/CSS2/selector.html
当然,只靠这几个还不够,Jsoup还定义了CombiningEvaluator
(对Evaluator进行And/Or组合),StructuralEvaluator
(结合DOM树结构进行筛选)。
这里我们可能最关心的是,“div ul li”这样的父子结构是如何实现的。这个的实现方式在StructuralEvaluator.Parent
中,贴一下代码了:
<!-- lang: java -->
static class Parent extends StructuralEvaluator {public Parent(Evaluator evaluator) {this.evaluator = evaluator;}public boolean matches(Element root, Element element) {if (root == element)return false;Element parent = element.parent();while (parent != root) {if (evaluator.matches(root, parent))return true;parent = parent.parent();}return false;}
}
这里Parent包含了一个evaluator
属性,会根据这个evaluator去验证所有父节点。注意Parent是可以嵌套的,所以这个表达式"div ul li"最终会编译成And(Parent(And(Parent(Tag("div")),Tag("ul")),Tag("li")))
这样的Evaluator组合。
select部分比想象的要简单,代码可读性也很高。经过了parser部分的研究,这部分应该算是驾轻就熟了。
关于webmagic的后续打算
webmagic是一个爬虫框架,它的Selector是用于抓取HTML中指定的文本,其机制和Jsoup的Evaluator非常像,只不过webmagic暂时是将Selector封装成较简单的API,而Evaluator直接上了表达式。之前也考虑过自己定制DSL来写一个HTML,现在看了Jsoup的源码,实现能力算是有了,但是引入DSL,实现只是一小部分,如何让DSL易写易懂才是难点。
其实看了Jsoup的源码,精细程度上比webmagic要好得多了,基本每个类都对应一个真实的概念抽象,可能以后会在这方面下点工夫。
下篇文章将讲最后一部分:白名单及HTML过滤机制。
最后依然附上这系列文章和代码的github地址:https://github.com/code4craft/jsoup-learning
Jsoup代码解读之七-实现一个CSS Selector相关推荐
- jsoup获得css,Jsoup代码解读之五-实现一个CSS Selector
Jsoup代码解读之七-实现一个CSS Selector 当当当!终于来到了Jsoup的特色:CSS Selector部分.selector也是我写的爬虫框架webmagic开发的一个重点.附上一张s ...
- Jsoup代码解读之一-概述
转载自 Jsoup代码解读之一-概述 今天看到一个用python写的抽取正文的东东,美滋滋的用Java实现了一番,放到了webmagic里,然后发现Jsoup里已经有了-觉得自己各种不靠谱啊!算了 ...
- Jsoup代码解读之二-DOM相关对象
转载自 Jsoup代码解读之二-DOM相关对象 之前在文章中说到,Jsoup使用了一套自己的DOM对象体系,和Java XML API互不兼容.这样做的好处是从XML的API里解脱出来,使得代码精炼 ...
- Jsoup代码解读之三-Document的输出
转载自 Jsoup代码解读之三-Document的输出 Jsoup官方说明里,一个重要的功能就是***output tidy HTML***.这里我们看看Jsoup是如何输出HTML的. HTML ...
- Jsoup代码解读之四-parser(上)
转载自 Jsoup代码解读之四-parser(上) 作为Java世界最好的HTML 解析库,Jsoup的parser实现非常具有代表性.这部分也是Jsoup最复杂的部分,需要一些数据结构.状态机乃至 ...
- Jsoup代码解读之五-parser(中)
转载自 Jsoup代码解读之五-parser(中) 上一篇文章讲到了状态机和词法分析的基本知识,这一节我们来分析Jsoup是如何进行词法分析的. 代码结构 先介绍以下parser包里的主要类: ...
- Jsoup代码解读之六-parser(下)
转载自 Jsoup代码解读之六-parser(下) 最近生活上有点忙,女儿老是半夜不睡,精神状态也不是很好.工作上的事情也谈不上顺心,有很多想法但是没有几个被认可,有些事情也不是说代码写得好就行的 ...
- css游戏代码_介绍CSSBattle-第一个CSS代码搜寻游戏
css游戏代码 by kushagra gour 由kushagra gour 介绍CSSBattle-第一个CSS代码搜寻游戏 (Introducing CSSBattle - the first ...
- Python 中 xpath 语法 与 lxml 库解析 HTML/XML 和 CSS Selector
The lxml.etree Tutorial :https://lxml.de/tutorial.html python3 解析 xml:https://www.cnblogs.com/deadwo ...
最新文章
- ImportError: No module named _tkinter, please install the python-tk package ubuntu运行tkinter错误
- 关于项目重构,知道真相的程序员眼泪笑了出来
- mysql 百度地图插件_GitHub - huizhong/grafana-baidumap-panel: Grafana 百度地图插件
- nusoap php 7,nusoap-用php的NuSoap 访问webservice遇到的问题。
- python plt.plot bar 设置绘图尺寸大小
- 移动开发解决方案之玩转输入框
- python基础语法(一)
- Zigbee学习计划暂停
- 2018-2019-1 20165320 《信息安全系统设计基础》第八周学习总结
- mysql函数commit_phpmysqli_commit()函数和mysqli_autocommit()函数比较
- split函数 在oracle,oracle的split函数
- Windows及Linux系统下--adb驱动安装及问题总结
- 蓝牙协议分析工具Wireshark/Frontline/Ellisys的使用
- 小程序中自定义图片预览功能
- linux给文件夹加密码,如何使用linux命令给文件上锁?linux命令文件加密方法
- win7啊,我的纠结,ip啊
- uni app 零基础小白到项目实战-1
- 组织结构图插件_一个简单直接的组织结构图插件
- linux c语言 ppt,Linux下C语言编程.ppt
- 连续两年蝉联冠今Topday“2015年度优秀供应商”
热门文章
- 40. 组合总和 II021(回溯法)
- C++未定义行为-数组越界
- android 语音助手官网,breeno语音助手最新版
- c语言case怎么输入字母,如何使用switch case语句将字母转换为数字
- 数据结构---模式匹配
- 2019-03-18-算法-进化(实现strStr())
- Educational Codeforces Round 76 (Rated for Div. 2) F. Make Them Similar 折半搜索
- 【NOI2019】回家路线【无后效性dp状态设计】【斜率优化】
- P2480 [SDOI2010]古代猪文(数论好题)
- HDU - 2204 Eddy‘s爱好(尚未完全解决)