`

Hpricot笔记

    博客分类:
  • Ruby
阅读更多
Hpricot::Doc的search方法返回一个Hpricot::Elements对象(Hpricot::Elem对象的集合),方法的参数可以是XPath或者CSS选择器。
require 'open-uri'
require 'hpricot'
doc=Hpricot(open('http://www.tianya.cn/publicforum/content/free/1/1455739.shtml'))
content = doc.search("#pageDivTop")
puts content

search方法也可以直接用除号代替
require 'open-uri'
require 'hpricot'
doc=Hpricot(open('http://www.tianya.cn/publicforum/content/free/1/1455739.shtml'))
content = doc/"#pageDivTop"
puts content

果然这玩意越看越像jQuery。。
Hpricot::Doc的at方法返回匹配选择器的第一个元素,并包装为Hpricot::Elem对象。Elements和Elem对象也都有这个方法。

Hpricot::Elem对象有[]方法,参数是字符串,可以取得元素的各个属性值,例如:
img=doc.at('img')
img['src'] #第1个img元素的src值


Elem对象还有个attributes方法,返回Hpricot::Attributes对象,这个对象也有[]方法,上面的代码也可以改写为:
img=doc.at('img')
img.attributes['src'] #第1个img元素的src值


Doc对象、Elem对象和Elements对象都有inner_html和to_html方法。

Elements对象的first方法返回集合中第1个Elem对象,elements[0]的作用和first方法相同。

还可以在Elements对象中继续进行搜索,如:
imgs=doc/"img"
google_logo=imgs/"#googleLogo"
divs=doc/"div"
spans=divs/"span"
#更简单的方法
spans=doc/"div span"


甚至可以在Elem对象中搜索:
divs=doc/"div"
spans=divs[0]/'span'


Elements有个any?方法,如果Elements#size为0,Elements#any?返回false,反之则返回true。

Elem对象有一个set_attribute方法,用来改变对象的某个属性值:
require 'open-uri'
require 'hpricot'
doc=Hpricot(open('http://www.tianya.cn/publicforum/content/free/1/1455739.shtml'))
divs=doc/'div'
divs.each do |div|
  div.set_attribute :class, "newClass"
  puts div['class']
end

下面这段代码的效果是一样的:
require 'open-uri'
require 'hpricot'
doc=Hpricot(open('http://www.tianya.cn/publicforum/content/free/1/1455739.shtml'))
divs=doc/'div'
divs.each do |div|
  div['class']= "newClass"
  puts div['class']
end

还有个更简单的方法——通过Elements的set方法来为其中的所有Elem设置属性值:
require 'open-uri'
require 'hpricot'
doc=Hpricot(open('http://www.tianya.cn/publicforum/content/free/1/1455739.shtml'))
divs=doc/'div'
divs.set(:class=>"newClass")
divs.each do |div|
  puts div['class']
end

但是要注意:只有Elem可以用set_attribute和[]来修改属性值,只有Elements可以用set方法修改属性值。

每个Elem对象都有一个css_path和xpath方法

接下来是Elements对象的几个常用方法的详解:
引用
at( expression, &block )

Find a single element which matches the CSS or XPath expression. If a block is given, the matching element is passed to the block and the original set of Elements is returned.

doc=Hpricot(<<html
<div id="div1">
  <span id="span1">1</span>
  <span>2</span>
</div>
<div id="div2">
  <span>3</span>
  <input type="text" id="input1" value="haliluya"/>
</div>
html
)

t=doc.search('div').at('span') do |span|
  puts span.inner_text
end
puts t
#输出:
#1
#2
#3
#<div id="div1">
#  <span id="span1">1</span>
#  <span>2</span>
#</div>

从结果可以看出,似乎带block的at方法的返回值并不是所谓的“the original set of Elements”,这里是这个版本的bug还是文档写错了?或者是我理解错了?另外要注意的是,带block的at方法只在Elements对象中起作用,Doc对象和Elem对象只能简单的调用不带block的at方法,加block不起作用。
引用
search( expression, &block )

Finds all elements which match the CSS or XPath expression. If a block is given, the matching elements are passed to the block, in turn, and the original set of Elements is returned.

Elements对象的search方法带block的情况下的返回值倒是“the original set of Elements”了。
引用
append( html_string )

Add HTML from html_string within each element, to the end of each element’s content.

引用
prepend( html_string )

Add HTML from html_string with each element, to the beginning of each element’s content.

引用
wrap( html_string )

Wraps each element in the set inside the element created by html_string. If more than one element is found in the html_string, Hpricot locates the deepest spot inside the first element.

doc.search("a[@href]").wrap(%{<div class="link"><div class="link_inner"></div></div>})


This code wraps every link on the page inside a div.link and a div.link_inner nest.

这里特别记一下,我一开始以为wrap方法不起作用,后来发现是我搞错了,我最初写的代码是这样的:
doc=Hpricot(<<html
<div id="div1">
  <span id="span1">1</span>
  <span>2</span>
</div>
<div id="div2">
  <span>3</span>
  <input type="text" id="input1" value="haliluya"/>
</div>
html
)

divs=doc/'div'
divs.wrap "<p></p>" #可以简单的写作divs.wrap "<p>",再试试divs.wrap "<p><h>"
puts divs

输出结果中没发现有任何变化。后来发现after方法存在同样的问题,再仔细想了想,divs变量保存的是那两个div元素,wrap上去的东西在div的外面,输出divs当然看不到外面的变化了,如果这时候输出doc变量,就可以看见变化了。

Elem对象有个swap方法,swap的作用是把该元素原来的内容用新字符串(可以是html也可以是普通字符串)替换掉:
doc=Hpricot(<<html
<div id="div1">
  <span id="span1">1</span>
  <span>2</span>
</div>
<div id="div2">
  <span>3</span>
  <input type="text" id="input1" value="haliluya"/>
</div>
html
)

divs=doc/'div'
divs.first.swap("<p>p</p>")
puts divs
puts "======="
puts doc

从结果中可以看到,swap之后,直接输出divs变量看不出任何变化,输出doc变量就可以看到变化了。估计是因为一般swap的操作都是一次性的吧。。
Elements的remove方法用于从文档中删除所有Elements中包含的元素。
# Remove all elements in this list from the document which contains them.
doc = Hpricot("<html>Remove this: <b>here</b></html>")
doc.search("b").remove
doc.to_html
# => "<html>Remove this: </html>"

Elements和Elem都有一个after方法(我试了一下,其实还有一个before方法,当然,作用跟after是相对的),用于在指定元素的后面添加字符串(可以是html代码,也可以是普通字符串)。
doc=Hpricot(<<html
<div id="div1">
  <span id="span1">1</span>
  <span>2</span>
</div>
<div id="div2">
  <span>3</span>
  <input type="text" id="input1" value="haliluya"/>
</div>
html
)

divs=doc/'div'
divs.after "<a href='#'/>"
puts doc

Elem的next方法返回下一个节点,不跳过文本节点。
next_sibling返回下一个节点,跳过文本节点。
相对的有previous和previous_sibling
require 'hpricot'

doc=Hpricot(<<HTML
<TABLE cellspacing=0 border=0 width=100% >
  <TR>
    <TD>
      <font size=-1 color=green><br>
      <center>
        <div id="tianyaBrandSpan1"></div>
        <div id="adsp_content_banner_3" style="background-color:#F5F9FA;padding:10px 0 0 0;"></div>
        <div id="adsp_content_adtopic"></div>
        <div id="adsp_content_banner_1" style="background-color:#F5F9FA"></div>
      </center>
    </TD>
  </TR>
</table>
HTML
)

puts doc.at('#tianyaBrandSpan1').next #一个包含了空行的文本节点(Hpricot::Text)
puts doc.at('#tianyaBrandSpan1').next_sibling #id为adsp_content_banner_3的div节点

CSS选择器还算熟悉,就不记了,详见:http://wiki.github.com/hpricot/hpricot/hpricot-css-search
http://wiki.github.com/hpricot/hpricot/supported-css-selectors
最后:
引用
The CSS selectors are almost always easier to write and cleaner to combine. In addition, XPath support is pretty limited at present.

睡觉睡觉。
分享到:
评论
1 楼 Enn 2010-04-07  
  USEAGE上它非要写成 node.attributes['href']还好看了这篇文章 不过这个不支持[:href]的格式

相关推荐

    笔记记录分享-笔记记录分享网站-笔记记录分享网站源码-笔记记录分享网站java代码-基于springboot的笔记记录分享网站

    笔记记录分享-笔记记录分享网站-笔记记录分享网站源码-笔记记录分享网站java代码-笔记记录分享网站设计与实现-基于springboot的笔记记录分享网站-基于Web的笔记记录分享网站设计与实现-笔记记录分享项目-笔记记录...

    微信小程序 云笔记 (源码)

    微信小程序 云笔记 (源码)微信小程序 云笔记 (源码)微信小程序 云笔记 (源码)微信小程序 云笔记 (源码)微信小程序 云笔记 (源码)微信小程序 云笔记 (源码)微信小程序 云笔记 (源码)微信小程序 云笔记 (源码)微信小...

    狂神SpringBoot笔记+源码

    狂神SpringBoot笔记+源码 狂神SpringBoot笔记+源码 狂神SpringBoot笔记+源码 狂神SpringBoot笔记+源码 狂神SpringBoot笔记+源码 狂神SpringBoot笔记+源码 狂神SpringBoot笔记+源码 狂神SpringBoot笔记+源码 狂神...

    小程序源码 云笔记 (代码+截图)

    小程序源码 云笔记 (代码+截图)小程序源码 云笔记 (代码+截图)小程序源码 云笔记 (代码+截图)小程序源码 云笔记 (代码+截图)小程序源码 云笔记 (代码+截图)小程序源码 云笔记 (代码+截图)小程序源码 云笔记 (代码+...

    有道云笔记如何调整窗口大小?.docx

    有道云笔记窗口大小调整技巧 在使用有道云笔记时,调整窗口大小是非常重要的操作。合理的窗口大小设置可以提高工作效率和阅读体验。本文将介绍如何调整有道云笔记的窗口大小,提高笔记编辑和阅读体验。 一、调整...

    2020谷粒商城笔记资料,文档课件笔记+源代码(基础篇+高级篇

    2020谷粒商城笔记资料,谷粒商城2020文档课件笔记+源代码(基础篇+高级篇) 谷粒商城2020文档课件笔记+源代码(基础篇+高级篇) 2020谷粒商城笔记资料(基础篇+高级篇) 尚硅谷谷粒商城笔记,很全。基础篇,高级篇...

    基于SSM框架+mysql搭建的云笔记系统(仿有道云笔记)源码.zip

    基于SSM框架+mysql搭建的云笔记系统(仿有道云笔记)源码.zip基于SSM框架+mysql搭建的云笔记系统(仿有道云笔记)源码.zip基于SSM框架+mysql搭建的云笔记系统(仿有道云笔记)源码.zip基于SSM框架+mysql搭建的云笔记...

    大物上册手写笔记.pdf

    【大物上册手写笔记.pdf】是一份来自西电大学的高质量物理学习资料,主要涵盖了大学物理上册的内容。这份笔记由一位期末成绩达到90分以上的同学编写,因此具有很高的参考价值,适合学生在期末复习时使用。笔记内容...

    为知笔记4.2.476免登录

    《为知笔记4.2.476免登录——本地存储与便捷知识管理》 为知笔记,全称为“WizNote”,是一款受到广大用户喜爱的个人知识管理工具。其4.2.476版本提供了免登录的功能,这对于那些希望在不登录账户的情况下仅进行...

    狂神笔记,b站狂神说课程笔记大全(最新)

    b站狂神说课程笔记大全,每个部分都有 狂神说java系列笔记(java基础+javaweb+ssm+微服务)全套 狂神说上课笔记未删减 Java基础到技术升级 1、JavaSE:Java入门 2、JavaSE:基础语法 3、JavaSE:流程控制 4、JavaSE...

    为知笔记开源项目程序源码,实现云笔记功能需要自己搭建服务器

    为知笔记开源项目程序源码,实现云笔记功能需要自己搭建服务器 为知笔记开源项目程序源码,实现云笔记功能需要自己搭建服务器 为知笔记开源项目程序源码,实现云笔记功能需要自己搭建服务器 为知笔记开源项目程序...

    Java相关课程系列笔记之九Servlet学习笔记

    Java相关课程系列笔记之一Java学习笔记 Java相关课程系列笔记之四JDBC学习笔记 Java相关课程系列笔记之六HTML学习笔记 Java相关课程系列笔记之七CSS学习笔记 Java相关课程系列笔记之八JavaScript学习笔记 Java相关...

    基于SSM框架+mysql搭建的云笔记系统(仿有道云笔记)源码+项目说明.zip

    基于SSM框架+mysql搭建的云笔记系统(仿有道云笔记)源码+项目说明.zip 基于SSM框架+mysql搭建的云笔记系统(仿有道云笔记)源码+项目说明.zip 基于SSM框架+mysql搭建的云笔记系统(仿有道云笔记)源码+项目说明.zip...

    oracle adg安装个人笔记

    oracle adg安装个人笔记oracle adg安装个人笔记oracle adg安装个人笔记oracle adg安装个人笔记oracle adg安装个人笔记oracle adg安装个人笔记oracle adg安装个人笔记oracle adg安装个人笔记oracle adg安装个人笔记...

    2022吴恩达机器学习笔记汇总(共10章节).zip

    2022吴恩达机器学习笔记汇总(共10章节).zip2022吴恩达机器学习笔记汇总(共10章节).zip2022吴恩达机器学习笔记汇总(共10章节).zip2022吴恩达机器学习笔记汇总(共10章节).zip2022吴恩达机器学习笔记汇总(共10章节).zip...

    软考中级笔记,系统集成项目管理工程师笔记.zip

    软考中级笔记,本人自己学习过程中记录的笔记内容。 课程学的是马老师的课程。参照此笔记默认有马老师的教程,或已对课本知识点内容有基础认识,本笔记也只是作为后期知识巩固和做题时辅助使用,前期肯定比较粗,...

    杨超线代笔记.pdf

    杨超线代笔记.pdf杨超线代笔记.pdf杨超线代笔记.pdf杨超线代笔记.pdf杨超线代笔记.pdf杨超线代笔记.pdf杨超线代笔记.pdf杨超线代笔记.pdf杨超线代笔记.pdf杨超线代笔记.pdf杨超线代笔记.pdf杨超线代笔记.pdf杨超线代...

    高手笔记 软件开发软件使用笔记

    高手笔记 软件开发软件使用笔记 本资源是关于高手笔记 软件开发软件使用笔记的知识点总结。主要讲解了如何构建带内存错误检查的 gcc,以及 QEMU 的使用笔记。 一、构建带内存错误检查的 gcc 高手笔记软件开发软件...

    docker笔记笔记笔记笔记笔记笔记

    docker笔记笔记笔记笔记笔记笔记

Global site tag (gtag.js) - Google Analytics