Lxml 解析网页用法笔记

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/z690798364/article/details/79960358

用python的urllib2库实现的获取到网页数据之后,使用lxml对获取的网页进行数据抓取。

1.导入包 from lxml import etree

2.page = etree.HTML(html) 或者 page = etree.HTML(html.decode('utf-8'))

3.对Element对象(page)使用xpath筛选,返回一个列表(里面的元素也是Element)

举例:

<html>
  <head>
    <meta name="content-type" content="text/html; charset=utf-8" />
    <title>示例</title>    
  </head>
  <body>
    <h1 class="cl1">测试内容一</h1>
    <p style="font-size: 200%">测试内容二</p>
    测试内容三
    <p>测试内容四</p>
    <a href="http://www.baidu.com/"  target="_blank">百度</a> 
    <a href="http://www.google.com" target="_blank">谷歌</a>
    <a href="http://www.ali.com" target="_blank">阿里</a> 
    <a href="http://game.tencent.com" target="_blank"><img src='www.baidu.com'/>腾讯</a>
    <a href="http://game.sina.com" target="_blank"><img src='www.baidu.com'/>新浪</a>
    <a href="http://www.huawei.com" target="_blank"><img src='www.baidu.com'/>华为</a> 
    <a href="http://www.xiaomi.com" target="_blank"><img src='www.baidu.com'/>小米</a>

  </body>
</html>

解析html

from lxml import etree
page = etree.HTML(html.decode('utf-8'))

获取标签

# a标签
tags = page.xpath(u'/html/body/a')
print(tags)  
# html 下的 body 下的所有 a
# 结果[<Element a at 0x34b1f08>, ...]

/html  整个网页的根目录

/html/body/a  获取整个网页<body>标签下所有<a>标签

//a  获取html下所有a标签,在本例中功能同上(所有a标签都放在body下,别的地方没有)

/descendant::a  等价于 //a   descendant::前缀可纸袋任意多层中间节点,也可以省略成一个“ /”

/html/body/*/a  表示取出body下第二级的所有a标签,不管它的上级是什么标签,‘*’可以代表所有的节点名

获取head里面的标签要特别一点 比如//html/head/*  或者//html/head/title

获取节点(标签)属性:

for taga in tags:
    print(taga.attrib)    
    # 获取属性: {'target': '_blank', 'href': 'http://www.ali.com'}
    print(taga.get('href'))
    # 获取某一属性:http://www.ali.com
    print(taga.text)
    # 获取文本: 阿里

利用属性筛选标签

# 直接定位到<h1 class="cl1">测试内容一</h1>
hs = page.xpath("//h1[@class='heading']")
for h in hs:
    print(h.values())
    print(h.text)
    # 打印结果:
    # ['heading']
    # 测试内容一

属性可以写@name,@id,@value,@src,@href...

如果没有属性,也可以使用text()(表示标签内包含的内容)和positon()(获取节点的位置)

示例:

a[position()=2] 表示取得第二个a节点,可以被省略为a[2]

需要注意数字定位和过滤条件的顺序

/body/a[5][@name='hello'] 表示取下第五个a标签,并且name必须是hello,否则为空

/body/a[@name='hello'][5] 表示取body下第五个name为hello的a标签

preceding-sibling::和 following-sibling::

preceding-sibling::前缀表示同一层的上一个节点

following-sibling::前缀表示同一层的下一个节点

示例

//body//following-sibling::a  同层下一个a标签
//body/h1/preceding-sibling::*  所有h1上所有h1同级的子标签

tail获取特殊内容

<a href="http://game.tencent.com" target="_blank"><img src='www.baidu.com'/>腾讯</a>

‘腾讯’两个字在<img/>和</a>标签中间,正常使用text是获取不到内容的,需要使用taga.tail.strip()来获取内容

   tail的意思是结束节点前面的内容,就是<img/>和</a>标签中间的内容


如果script与style标签之间的内容影响解析页面,或者页面很不规则,可以使用lxml.html.clean模块。模块 lxml.html.clean 提供 一个Cleaner 类来清理 HTML 页。它支持删除嵌入或脚本内容、 特殊标记、 CSS 样式注释或者更多。

  cleaner = Cleaner(style=True, scripts=True,page_structure=False, safe_attrs_only=False)
  print cleaner.clean_html(html)


  注意,page_structure,safe_attrs_only为False时保证页面的完整性,否则,这个Cleaner会把你的html结构与标签里的属性都给清理了。使用Cleaner类要十分小心,小心擦枪走火。
  忽略大小写可以:

page = etree.HTML(html)
  keyword_tag = page.xpath("//meta[translate(@name,'ABCDEFGHJIKLMNOPQRSTUVWXYZ', 'abcdefghjiklmnopqrstuvwxyz')='keywords']")




阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页