python lxml模块解析html_用lxml解析HTML

先演示一段获取页面链接代码示例:

#coding=utf-8

from lxml import etree

html = '''

友情链接查询 - 站长工具

Top News

World News only on this page

Ah, and here's some more text, by the way.

... and this is a parsed fragment ...

青少年发展基金会

洛克王国

奥拉星

手机游戏

手机壁纸

4399小游戏

91wan游戏

'''

page = etree.HTML(html.lower().decode('utf-8'))

hrefs = page.xpath(u"//a")

for href in hrefs:

print href.attrib

打印出的结果为:

{'href': 'http://www.cydf.org.cn/', 'target': '_blank', 'rel': 'nofollow'}

{'href': 'http://www.4399.com/flash/32979.htm', 'target': '_blank'}

{'href': 'http://www.4399.com/flash/35538.htm', 'target': '_blank'}

{'href': 'http://game.3533.com/game/', 'target': '_blank'}

{'href': 'http://game.3533.com/tupian/', 'target': '_blank'}

{'href': 'http://www.4399.com/', 'target': '_blank'}

{'href': 'http://www.91wan.com/', 'target': '_blank'}

如果要取得之间的内容,

for href in hrefs:

print href.text

结果为:

青少年发展基金会

洛克王国

奥拉星

手机游戏

手机壁纸

4399小游戏

91wan游戏

使用lxml前注意事项:先确保html经过了utf-8解码,即code = html.decode('utf-8', 'ignore'),否则会出现解析出错情况。因为中文被编码成utf-8之后变成 '/u2541' 之类的形式,lxml一遇到 “/”就会认为其标签结束。

XPATH基本上是用一种类似目录树的方法来描述在XML文档中的路径。比如用“/”来作为上下层级间的分隔。第一个“/”表示文档的根节点(注意,不是指文档最外层的tag节点,而是指文档本身)。比如对于一个HTML文件来说,最外层的节点应该是"/html"。

定位某一个HTML标签,可以使用类似文件路径里的绝对路径,如page.xpath(u"/html/body/p"),它会找到body这个节点下所有的p标签;也可以使用类似文件路径里的相对路径,可以这样使用:page.xpath(u"//p"),它会找到整个html代码里的所有p标签:

World News only on this page

Ah, and here's some more text, by the way.

... and this is a parsed fragment ...

注意:XPATH返回的不一定就是唯一的节点,而是符合条件的所有节点。如上所示,只要是body里的p标签,不管是body的第一级节点,还是第二级,第三级节点,都会被取出来。

如果想进一步缩小范围,直接定位到“

World News only on this page

”要怎么做呢?这就需要增加过滤条件。过滤的方法就是用“[”“]”把过滤条件加上。lxml里有个过滤语法:

p = page.xpath(u"/html/body/p[@style='font-size: 200%']")

或者:p = page.xpath(u"//p[@style='font-size:200%']")

这样就取出了body里style为font-size:200%的p节点,注意:这个p变量是一个lxml.etree._Element对象列表,p[0].text结果为World News only on this page,即标签之间的值;p[0].values()结果为font-size: 200%,即所有属性值。其中 @style表示属性style,类似地还可以使用如@name, @id, @value, @href, @src, @class....

如果标签里面没有属性怎么办?那就可以用text(),position()等函数来过滤,函数text()的意思则是取得节点包含的文本。比如:

hello

world

< /div>中,用"div[text()='hello']"即可取得这个div,而world则是p的text()。函数position()的意思是取得节点的位置。比如“li[position()=2]”表示取得第二个li节点,它也可以被省略为“li[2]”。

不过要注意的是数字定位和过滤 条件的顺序。比如“ul/li[5][@name='hello']”表示取ul下第五项li,并且其name必须是hello,否则返回空。而如果用 “ul/li[@name='hello'][5]”的意思就不同,它表示寻找ul下第五个name为"hello“的li节点。

此外,“*”可以代替所有的节点名,比如用"/html/body/*/span"可以取出body下第二级的所有span,而不管它上一级是div还是p或是其它什么东东。

而 “descendant::”前缀可以指代任意多层的中间节点,它也可以被省略成一个“/”。比如在整个HTML文档中查找id为“leftmenu”的 div,可以用“/descendant::div[@id='leftmenu']”,也可以简单地使用“ //div[@id='leftmenu']”。

text = page.xpath(u"/descendant::*[text()]")表示任意多层的中间节点下任意标签之间的内容,也即实现蜘蛛抓取页面内容功能。以下内容使用text属性是取不到的:

1.无流量站点清理公告  2013-02-22
取不到的内容

2.无流量站点清理公告  2013-02-22

取不到的内容

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值