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是一个抽象类,它只有一个方法:

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中,贴一下代码了:

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要好得多了,基本每个类都对应一个真实的概念抽象,可能以后会在这方面下点工夫。

Jsoup代码解读之一-概述

Jsoup代码解读之一-概述 今天看到一个用python写的抽取正文的东东,美滋滋的用Java实现了一番,放到了webmagic里,然后发现Jsoup里已经有了…觉得自己各种不靠谱啊!算了,静下心来学 ...

Jsoup代码解读之二-DOM相关对象

Jsoup代码解读之二-DOM相关对象   之前在文章中说到,Jsoup使用了一套自己的DOM对象体系,和Java XML API互不兼容.这样做的好处是从XML的API里解脱出来,使得代码精炼了很多 ...

Jsoup代码解读之六-防御XSS攻击

Jsoup代码解读之八-防御XSS攻击 防御XSS攻击的一般原理 cleaner是Jsoup的重要功能之一,我们常用它来进行富文本输入中的XSS防御. 我们知道,XSS攻击的一般方式是,通过在页面输入 ...

Jsoup代码解读之四-parser

Jsoup代码解读之四-parser 作为Java世界最好的HTML 解析库,Jsoup的parser实现非常具有代表性.这部分也是Jsoup最复杂的部分,需要一些数据结构.状态机乃至编译器的知识.好 ...

Jsoup代码解读之三-Document的输出

Jsoup代码解读之三-Document的输出   Jsoup官方说明里,一个重要的功能就是output tidy HTML.这里我们看看Jsoup是如何输出HTML的. HTML相关知识 分析代码前 ...

如何判断一个DOM元素正在动画,一个CSS“阻塞”JS的例子

一般情况下CSS不会直接影响JS的程序逻辑,但是以CSS实现动画的话,这个便不太确定了,这个故事发生在与UED迁移全局样式的过程. 曾经我有一段实现弹出层隐藏动画的代码是这个样子的: if (this ...

转:Selenium之CSS Selector定位详解

CSS selector定位 CSS(Cascading Style Sheets)是一种语言,它被用来描述 HTML 和 XML 文档的样式.  百度输入框:

css selector

文章一: http://www.jb51.net/css/68287.html 去年我学jQuery的时候,曾经做过一点选择器(selector)的笔记,今天是CSS的选择器,以后还有一部分xPath ...

Xpath 和Css Selector使用

Xpath是xml的路径语言,就是通过元素的路径来查找标签元素. Xpath直接在火狐浏览器的firebug中练习,49版本一下的火狐才能用firebug插件. Xpath的使用方法 注://*    ...

随机推荐

css样式注意

CSS3 font-face定义的字体使用时有时候用引号,有时候不用,很奇怪,如 @font-face{ font-family: Roboto-Black; src: url('../package ...

通过内省机制设置JavaBean

一.步骤: 1)使用PropertyDescriptor类获取属性描述者对象 //pd引用Student的name属性 PropertyDescriptor pd = new PropertyDesc ...

网易云课堂_C++程序设计入门(上)_第4单元:物以类聚 – 对象和类_第4单元作业【3】- 在线编程(难度:难)

1 在本单元作业[1]和作业[2]的基础上,创建一个MyRectangle类,并在main函数中创建类的实例.(10分) 题目难度: 难 题目内容: Screen类: 与作业[2]要求完全相同. 如果 ...

WGS84、GCJ-02(火星坐标)、百度坐标,Web墨卡托坐标

GCJ-02坐标系统(火星坐标)简介:http://blog.csdn.net/giswens/article/details/8775121(存档:http://mapbd.com/cms/2012 ...

Videojs视频插件在React中的应用

1.介绍video.js视频插件 1.1 简单介绍 Video.js是一个通用的在网页上嵌入视频播放器的JS库,支持电脑端和移动端.Video.js自动检测浏览器对Html5的支持情况,如果不支持Ht ...

Servlet学习应该注意的几点

一.Servlet生命周期(即运行过程) (1)初始阶段,调用init()方法 (2)响应客户请求阶段,调用service()方法.由service()方法根据提交方式不同执行doGet()或doPo ...

poj 3764 The xor-longest Path (01 Trie)

链接:http://poj.org/problem?id=3764 题面: The xor-longest Path Time Limit: 2000MS   Memory Limit: 65536K ...

SQL 查找重复记录

CREATE TABLE product( ID INT IDENTITY(1,1) PRIMARY KEY NOT NULL, Pid INT NOT NULL, Pname VARCHAR(50) ...

Python 关于数组矩阵变换函数numpy.nonzero(),numpy.multiply()用法

1.numpy.nonzero(condition),返回参数condition(为数组或者矩阵)中非0元素的索引所形成的ndarray数组,同时也可以返回condition中布尔值为True的值索引 ...

JS形参与实参问题

JavaScript的参数传递也都是采用值传递的方式进行传值. (1)     通过实参调用函数的时候,传入函数里的是实参的副本而不是实参,因此在函数里面修改参数值并不会对实参造成影响. 例如:将全局 ...

jsoup获得css,Jsoup代码解读之五-实现一个CSS Selector相关推荐

  1. Jsoup代码解读之七-实现一个CSS Selector

    转载自    Jsoup代码解读之七-实现一个CSS Selector 当当当!终于来到了Jsoup的特色:CSS Selector部分.selector也是我写的爬虫框架webmagic开发的一个重 ...

  2. css游戏代码_介绍CSSBattle-第一个CSS代码搜寻游戏

    css游戏代码 by kushagra gour 由kushagra gour 介绍CSSBattle-第一个CSS代码搜寻游戏 (Introducing CSSBattle - the first ...

  3. Jsoup代码解读之五-parser(中)

    转载自    Jsoup代码解读之五-parser(中) 上一篇文章讲到了状态机和词法分析的基本知识,这一节我们来分析Jsoup是如何进行词法分析的. 代码结构 先介绍以下parser包里的主要类: ...

  4. webapck将css 打包后单独提取到一个css文件中

    webpack4 提倡, 一旦用了这个, 不能使用style-loader 以及css module 安装 npm install --save-dev mini-css-extract-plugin ...

  5. jquery如何去掉css,jQuery教程之jQuery去掉一个CSS属性

    本篇文章探讨了jQuery教程之jQuery去掉一个CSS属性,希望阅读本篇文章以后大家有所收获,帮助大家对相关内容的理解更加深入. < 1.什么事JQ? 一个优秀的js库,大型开发必备 2.J ...

  6. html与css重置代码,发个自己的CSS重置基础代码

    关于css的重置代码有很多,也有不少人写过适合不同站点的重置代码,这里发个浩子平时使用的额方法. 代码如下: /* haozi / hao.chen@qq.com / 2011.06.15 */ bo ...

  7. html css 网页代码案例,案例1-HTML使用css+div设计简单网页(62页)-原创力文档

    至此就完成了"About"网页的制作,依此类推,修改html中body的类为services/portfolio/contact制作相应html文件并分别保存.在css文件中添加各 ...

  8. css图标代码 星,15个纯CSS实现的响应式土豪金星球类应用动画图标

    CSS 语言: CSSSCSS 确定 div { position: absolute; box-sizing: border-box; margin: 0; padding: 0; border: ...

  9. 【浏览器】缩放是缩放CSS像素(缩放比例为1时,一个CSS像素等于一个屏幕像素)

    At zoom level 100% one CSS pixel is exactly equal to one device pixel

最新文章

  1. 性能指标:QPS、TPS、RT、吞吐量
  2. android yuv加水印_Android Camera添加预览水印
  3. 单例模式在JDK 应用的源码分析||单例模式注意事项和细节说明
  4. junit测试@注解
  5. 整合tomcat的一些配置
  6. php检查图片大小,如何利用Javascript函数检查图片大小
  7. 听说,99%的数学家都算不出这道题
  8. Android之父深入解析Android
  9. Maven: Could not transfer artifact xxx from/to xxx
  10. C 语言会比 C++ 快?
  11. 检查Linux服务器性能的关键十条命令
  12. 计算机基础应用网络统考题库,2016年9月网络教育《计算机应用基础》统考模拟试题及答案 (1)...
  13. 最简单的使用nginx实现动静分离
  14. 09.html使用iframe、embed查看pdf不显示(未解决),使用pdf.js预览pdf
  15. 【Copy攻城狮日志】借助Taro暴改Nideshop实现电商支付宝小程序雏形
  16. 让天底下没有难接的支付|支付宝网银直连转账到银行卡对接故事续集 支付对接不是一个单纯技术问题 网银直连转账到银行卡开通方式揭晓
  17. 用python批量修改图片名称!超级简单
  18. 【笔试】京东数据分析暑期实习
  19. 普乐蛙小型5d电影设备|5d电影动感电影体验馆|VR景区影院设备
  20. java中的反射详解

热门文章

  1. Centos 7下查看当前目录大小及文件个数
  2. mysqldumpslow mysql慢日志分析工具
  3. docker中部署Redis
  4. Python 之字符串常用方法
  5. C和C++中struct和typedef struct的异同
  6. Javaweb基础——Servlet
  7. 一篇文章全方位了解:static main final
  8. 百度地图手机和电脑不一致_如何解决电脑显色和印刷色不一致的问题
  9. 鸿蒙系统第一次出现,华为鸿蒙系统第三“用户”出现?没想到是它
  10. python随机取列表元素_python random从集合中随机选择元素