介绍一下Mojolicious的DOM选择器Mojo::DOM和它的Mojo::UserAgent(比较Web::Scraper)

最近正好又需要做页面分析,以前全是用AnyEvent::HTTP和Web::Scraper。这次试了试Mojo::DOM和Mojo::UserAgent。
先说结论,我的试用结论是:如果程序不和web沾边,只是个页面分析或文件处理程序,那还是前者好。否则的话可以考虑Mojo.

先说Mojo::DOM和Mojo::UserAgent的优点:
Mojo::DOM做的这个dom选择器在一些时候是非常方便的
读入HTML以后可以精确定位需要的元素或是用回调的方式遍历。

  1. my $dom = Mojo::DOM->new($html_string);
  2. $dom->find(‘p[id]‘)->each(sub { say shift->{id} });

复制代码


配合Mojo::UserAgent使用的时候就更方便了。Mojo::UserAgent有丰富的功能,但如果你不想用那些,你可以就把它当成一个
wget(http client)用。它不但支持同步get也支持非阻塞get网页。而且和Mojo::DOM整合的很好。比如:

  1. my $ua = Mojo::UserAgent->new;
  2. my $title = $tx->res->dom->at(‘head title‘)->text;

复制代码

当把这一切放到Mojolicious web框架里的时候就更美好了,因为都是一个作者写的,整合性就非常好。以前要兴师动众的工作现在2,3行代码就完成了。

以上看着都很美好了,我说些在我看来的缺点。
1. 不支持XPATH。
我很熟悉XPATH,但很不幸,不支持XPATH。虽然很多东西都可以用mojo的方式实现,但我还是能说出一些我常用但没实现的东西。并且我猜测因为
此,效率也会差很多。由于Web::Scraper是用xpath,并且可以用XML::LibXML来解析html/xml,XML::LibXML是
目前所有DOM方式中最快的(libxml2 >
expat)。所以我认为一个纯perl写的非xpath方式的DOM选择器的效率是不足以做大规模数据分析的。(仅是猜测)

2. 可能是我的使用习惯,页面复杂的时候我还是更喜欢用Web::Scraper
用过Web::Scraper的人都知道,你需要先用xpath写一个符合某类页面的统一规则,然后用这一整套规则去分析一类页面。页面信息复杂的时候这
一套规则可能几十甚至上百行。而用Mojo::DOM就只能用好多find->each和perl回调函数裹在一起,不方便调试,写页面分析规则的
人还必须得会perl。

3. 没法用Coro::rouse_cb和Coro::rouse_wait了。

  1. my $coro = async {
  2. http_get "http://www.example.com/", Coro::rouse_cb;
  3. my ($data, $header) = Coro::rouse_wait;
  4. print Dumper $header;
  5. };

复制代码

上面的这个可以。下面的这个就不行了。

  1. my $coro = async {
  2. my $ua = Mojo::UserAgent->new;
  3. $ua->get(‘http://www.example.com/‘ => Coro::rouse_cb);
  4. my ($ua2, $tx) = Coro::rouse_wait;
  5. my $title = $tx->res->dom->at(‘head title‘)->text;
  6. print "$title\n";
  7. };

复制代码

www.hwmqh.com/gggbdf
www.hwmqh.com/gbdfgfw
www.hwmqh.com/gbdfkhw
www.hwmqh.com/gbdfsh
www.hwmqh.com/gbdfsjxz
www.hwmqh.com/gbdfylsjxz
www.hwmqh.com/gbdfwfm
www.hwmqh.com/gbdfdtkh
www.hwmqh.com/gbdfhy
www.hwmqh.com/gbdfrhkh
www.hwmqh.com/gbdfzdl
www.hwmqh.com/gbdfw
www.hwmqh.com/gbdfdtkmdl
www.hwmqh.com/gbdfglw
www.hwmqh.com/gbdfxjw
www.hwmqh.com/gbdfwtkhzx
www.hwmqh.com/gbdfwtdhkh
www.hwmqh.com/gbdfwkh
www.hwmqh.com/gbdfwthykh
www.hwmqh.com/gbdftgy
www.hwmqh.com/gbdfylwz
www.hwmqh.com/gbdfzmzc
www.hwmqh.com/gbdfbjl
www.hwmqh.com/gbdfylyq
www.hwmqh.com/mdgbdfrqrh
www.hwmqh.com/gbdfmdyjm
www.hwmqh.com/mdgbdfaqm
www.hwmqh.com/gbdfkmdl
www.hwmqh.com/gbdfxwz
www.hwmqh.com/gbdfwtzx
www.hwmqh.com/gbdfdms
www.hwmqh.com/gbdfzc
www.hwmqh.com/gbdfsy
www.hwmqh.com/gbdfwzx
www.hwmqh.com/gbdfzj
www.hwmqh.com/gbdfdz
www.rhliv.com/gbdf
www.rhliv.com/gbdfkh
www.rhliv.com/gbdfylw
www.rhliv.com/gbdfyl
www.rhliv.com/gbdfhykh
www.rhliv.com/1659988_comgbdf
www.rhliv.com/gbdfdhtz
www.rhliv.com/gbdfylpt
www.rhliv.com/gbdfshy
www.rhliv.com/gbdfzxkh
www.rhliv.com/gbdfgw
www.rhliv.com/gbdfwt
www.rhliv.com/gbdfylc
www.rhliv.com/gbdfdl
www.rhliv.com/gbdfxc
www.rhliv.com/gbdfyldl
www.rhliv.com/gbdfkhbl
www.rhliv.com/gbdfylkh
www.rhliv.com/gbylgbdf
www.rhliv.com/gggbdfylc
www.rhliv.com/gbdfsjzmdl
www.rhliv.com/gbdfylfl
www.rhliv.com/gbdfzmnyq
www.rhliv.com/gbdfyj
www.rhliv.com/gbdfxmf
www.rhliv.com/szdmdgbdf
www.rhliv.com/mdgbdf
www.rhliv.com/gbdfdhkh
www.rhliv.com/gbdfdlkh
www.rhliv.com/gbdfwtkh
www.rhliv.com/gbdfkh1581260
www.rhliv.com/gbdfylhbwz
www.rhliv.com/gbdfyq
www.rhliv.com/sygbdfyl
www.rhliv.com/gbdfylzmyq
www.rhliv.com/gbdfylyflm
www.rhliv.com/gbdfylcznl
www.rhliv.com/gbdfwz
www.rhliv.com/gbdftz
www.rhliv.com/gbdfdh
www.rhliv.com/gbdfsj
www.rhliv.com/gggbdf
www.rhliv.com/gbdfgfw
www.rhliv.com/gbdfkhw
www.rhliv.com/gbdfsh
www.rhliv.com/gbdfsjxz
www.rhliv.com/gbdfylsjxz
www.rhliv.com/gbdfwfm
www.rhliv.com/gbdfdtkh
www.rhliv.com/gbdfhy
www.rhliv.com/gbdfrhkh
www.rhliv.com/gbdfzdl
www.rhliv.com/gbdfw
www.rhliv.com/gbdfdtkmdl
www.rhliv.com/gbdfglw
www.rhliv.com/gbdfxjw
www.rhliv.com/gbdfwtkhzx
www.rhliv.com/gbdfwtdhkh
www.rhliv.com/gbdfwkh
www.rhliv.com/gbdfwthykh
www.rhliv.com/gbdftgy
www.rhliv.com/gbdfylwz
www.rhliv.com/gbdfzmzc
www.rhliv.com/gbdfbjl
www.rhliv.com/gbdfylyq
www.rhliv.com/mdgbdfrqrh
www.rhliv.com/gbdfmdyjm
www.rhliv.com/mdgbdfaqm
www.rhliv.com/gbdfkmdl
www.rhliv.com/gbdfxwz
www.rhliv.com/gbdfwtzx
www.rhliv.com/gbdfdms
www.rhliv.com/gbdfzc
www.rhliv.com/gbdfsy
www.rhliv.com/gbdfwzx
www.rhliv.com/gbdfnyqb
www.rhliv.com/gbdfzj
www.rhliv.com/gbdfdz
www.bbilo.com/gbdf
www.bbilo.com/gbdfkh
www.bbilo.com/gbdfylw
www.bbilo.com/gbdfyl
www.bbilo.com/gbdfhykh
www.bbilo.com/1659988_comgbdf
www.bbilo.com/gbdfylpt
www.bbilo.com/gbdfshy
www.bbilo.com/gbdfzxkh
www.bbilo.com/gbdfgw
www.bbilo.com/gbdfwt
www.bbilo.com/gbdfylc
www.bbilo.com/gbdfdl
www.bbilo.com/gbdfxc
www.bbilo.com/gbdfyldl
www.bbilo.com/gbdfkhbl
www.bbilo.com/gbdfylkh
www.bbilo.com/gggbdfylc
www.bbilo.com/gbdfsjzmdl
www.bbilo.com/gbdfylfl
www.bbilo.com/gbdfzmnyq
www.bbilo.com/gbdfyj
www.bbilo.com/gbdfxmf
www.bbilo.com/szdmdgbdf
www.bbilo.com/mdgbdf
www.bbilo.com/gbdfdhkh
www.bbilo.com/gbdfwtkh
www.bbilo.com/gbdfkh1581260
www.bbilo.com/gbdfylhbwz
www.bbilo.com/gbdfyq
www.bbilo.com/gbdfylzmyq
www.bbilo.com/gbdfylyflm
www.bbilo.com/gbdfylcznl
www.bbilo.com/gbdfwz
www.bbilo.com/gbdftz
www.bbilo.com/gbdfdh
www.bbilo.com/gbdfsj
www.bbilo.com/gggbdf
www.bbilo.com/gbdfgfw
www.bbilo.com/gbdfkhw
www.bbilo.com/gbdfsh
www.bbilo.com/gbdfsjxz
www.bbilo.com/gbdfylsjxz
www.bbilo.com/gbdfwfm
www.bbilo.com/gbdfhy
www.bbilo.com/gbdfzdl
www.bbilo.com/gbdfw
www.bbilo.com/gbdfdtkmdl
www.bbilo.com/gbdfglw
www.bbilo.com/gbdfxjw
www.bbilo.com/gbdfwtkhzx
www.bbilo.com/gbdfwtdhkh
www.bbilo.com/gbdfwkh
www.bbilo.com/gbdfwthykh
www.bbilo.com/gbdftgy
www.bbilo.com/gbdfylwz
时间: 2024-11-10 11:30:40

介绍一下Mojolicious的DOM选择器Mojo::DOM和它的Mojo::UserAgent(比较Web::Scraper)的相关文章

[ jquery 过滤器 is(expr | jqObj | ele | function) ] 此方法用于在选择器的基础之上根据选择器、DOM元素或 jQuery 对象来检测匹配元素集合,如果有,则返回true

根据选择器.DOM元素或 jQuery 对象来检测匹配元素集合,如果其中至少有一个元素符合这个给定的表达式就返回true. 如果没有元素符合,或者表达式无效,都返回'false'. '''注意:'''在jQuery 1.3中才对所有表达式提供了支持.在先前版本中,如果提供了复杂的表达式,比如层级选择器(比如 + , ~ 和 > ),始终会返回true 实例: <!DOCTYPE html> <html lang='zh-cn'> <head> <title&

jQuery 选择器和dom操作

JQuery选择器 1.基本选择器 基本选择器是JQuery中最常用的选择器,也是最简单的选择器,它通过元素id.class 和标签名来查找DOM元素.这个非常重要,下面的内容都是以此为基础,逐级提高的. 1).“$(“#id”)”,获取id指定的元素,id是全局唯一的,所以它只有一个成员. 2).“$(“.class”)”,获取class指定的元素,不同的元素可以具有相同的class属性,所以它可能具有多个成员. 3).“$(“element”)”,获取element(元素名,比如div.ta

DOM选择器

dom选择器 直接查找 document.getElementById('i1') 间接查找: 文本内容操作: innerText 仅文本 innerHTML 全内容 value <input type="text" value="python"/> 获取单钱标签中的值 select 获取选中的value <select id="xx"></select> <options></opacity

JavaScript DOM 选择器 querySelector

W3C的规范与库中的实现 querySelector:return the first matching Element node within the node’s subtrees. If there is no such node, the method must return null .(返回指定元素节点的子树中匹配selector的集合中的第一个,如果没有匹配,返回null) querySelectorAll:return a NodeList containing all of t

选择器,DOM操作,事件

选择器,DOM操作,事件javascript事件:onclick,ondlbclickonmousedown,onmouseuponmouseover,onmouseoutonkeydown,onkeyuponblur,onfocusonchange Jquery事件,与JavaScript 事件相似,只是把on去掉.click(function(){});focus(function(){}); 1.click,dblclick事件:案例:换背景(用缩略图换背景,单击轮转换背景)特别: tog

DOM扩展:DOM API的进一步增强[总结篇-下]

本文承接<DOM扩展:DOM API的进一步增强[总结篇-上]>,继续总结DOM扩展相关的功能和API. 3.6 插入标记 DOM1级中的接口已经提供了向文档中插入内容的接口,但是在给文档插入大量HTML标记的时候操作还是很繁杂的,每次插入一个元素,不仅要调用创建元素和文本节点的接口,还要调用appendChild等向文档中添加元素的接口,而且在添加时还要按照正确的顺序.而如果使用插入标记的方法,直接向文档中插入HTML字符串,由执行环境自动解析HTML字符串并创建相应的节点并添加到文档中,这

【DOM】1.DOM优化

1.JS include :DOM BOM ECMA 2.Browser 分别独立实现dom & JS as if two isolated islands 3.JS操作DOM from the island to the other one 4.DOM性能 The bridges between islands,charge everytime passing by 尽量减少过桥次数 5.innerHTML vs dom method webkit:eg, chrome, dom>inne

dom core,html dom,css dom,jquery 中的dom操作

前端开发中为达到某种目的,往往有很多方法:dom core,html dom,jquery; dom core/jquery主要通过函数调用的方式(getAttribute("属性名")/attr("属性名"))获取属性值, html dom一般利用属性的形式(element.属性名)获取对应属性值,形式相对简洁.此外,针对于css相关的对象,还有css dom 前端开发中的节点有三种:元素节点:文本节点和属性节点 js一般对于dom core和html dom都支

走进DOM:HTML DOM

DOM(Document Object Model)即文档对象模型.针对HTML和XML 文档的API(应用程序接口). DOM描绘了一个层次化的节点树,执行开发者加入.移除和改动页面的某一部分.当然这样说有些笼统.咱们接着往下看. 一.认识DOM DOM 中的三个字母.D(文档)能够理解为整个Web载入的网页文档.O(对象)能够理解为类似window对象之类的东西.能够调用属性和方法,这里我们说的是document对象:M(模型)能够理解为网页文档的树型结构. 通过 JavaScript,您能