lxml是python的一个解析库,支持HTML和XML的解析,支持XPath解析方式,而且解析效率非常高

1.lxml的安装

pip install lxml

2.导入lxml 的 etree 库

 from lxml import etree

3.利用etree.HTML,将字符串转化为Element对象,Element对象具有xpath的方法,返回结果的列表,能够接受bytes类型的数据和str类型的数据。

from lxml import etree
html = etree.HTML(response.text)
ret_list = html.xpath("xpath字符串")

也可以这样使用:

from lxml import etree
htmlDiv = etree.HTML(response.content.decode())
hrefs = htmlDiv.xpath("//h4//a/@href")

4.把转化后的element对象转化为字符串,返回bytes类型,etree.tostring(element)

假设我们现有如下的html字符换,尝试对他进行操作:

<div> <ul>
<li class="item-1"><a href="link1.html">first item</a></li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-inactive"><a href="link3.html">third item</a></li>
<li class="item-1"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a> # 注意,此处缺少一个 </li> 闭合标签
</ul> </div>

代码示例:

from lxml import etree
text = ''' <div> <ul> <li class="item-1"><a href="link1.html">first item</a></li> <li class="item-1"><a href="link2.html">second item</a></li> <li class="item-inactive"><a href="link3.html">third item</a></li> <li class="item-1"><a href="link4.html">fourth item</a></li> <li class="item-0"><a href="link5.html">fifth item</a> </ul> </div> '''html = etree.HTML(text)
print(type(html)) handeled_html_str = etree.tostring(html).decode()
print(handeled_html_str)

输出结果:

<class 'lxml.etree._Element'>
<html><body><div> <ul> <li class="item-1"><a href="link1.html">first item</a></li> <li class="item-1"><a href="link2.html">second item</a></li> <li class="item-inactive"><a href="link3.html">third item</a></li> <li class="item-1"><a href="link4.html">fourth item</a></li> <li class="item-0"><a href="link5.html">fifth item</a> </li></ul> </div> </body></html>

可以发现,lxml确实能够把确实的标签补充完成,但是请注意lxml是人写的,很多时候由于网页不够规范,或者是lxml的bug。
即使参考url地址对应的响应去提取数据,任然获取不到,这个时候我们需要使用etree.tostring的方法,观察etree到底把html转化成了什么样子,即根据转化后的html字符串去进行数据的提取。

5.lxml的深入练习

from lxml import etree
text = ''' <div> <ul> <li class="item-1"><a href="link1.html">first item</a></li> <li class="item-1"><a href="link2.html">second item</a></li> <li class="item-inactive"><a href="link3.html">third item</a></li> <li class="item-1"><a href="link4.html">fourth item</a></li> <li class="item-0"><a href="link5.html">fifth item</a> </ul> </div> '''html = etree.HTML(text)#获取href的列表和title的列表
href_list = html.xpath("//li[@class='item-1']/a/@href")
title_list = html.xpath("//li[@class='item-1']/a/text()")#组装成字典
for href in href_list:item = {}item["href"] = hrefitem["title"] = title_list[href_list.index(href)]print(item)

输出为:

{'href': 'link1.html', 'title': 'first item'}
{'href': 'link2.html', 'title': 'second item'}
{'href': 'link4.html', 'title': 'fourth item'}

6.lxml模块的进阶使用

返回的是element对象,可以继续使用xpath方法,对此我们可以在后面的数据提取过程中:先根据某个标签进行分组,分组之后再示例如下:

from lxml import etree
text = ''' <div> <ul> <li class="item-1"><a>first item</a></li> <li class="item-1"><a href="link2.html">second item</a></li> <li class="item-inactive"><a href="link3.html">third item</a></li> <li class="item-1"><a href="link4.html">fourth item</a></li> <li class="item-0"><a href="link5.html">fifth item</a> </ul> </div> '''html = etree.HTML(text)li_list = html.xpath("//li[@class='item-1']")
print(li_list)

结果为:

[<Element li at 0x11106cb48>, <Element li at 0x11106cb88>, <Element li at 0x11106cbc8>]数据的提取

可以发现结果是一个element对象,这个对象能够继续使用xpath方法
先根据li标签进行分组,之后再进行数据的提取

from lxml import etree
text = ''' <div> <ul> <li class="item-1"><a>first item</a></li> <li class="item-1"><a href="link2.html">second item</a></li> <li class="item-inactive"><a href="link3.html">third item</a></li> <li class="item-1"><a href="link4.html">fourth item</a></li> <li class="item-0"><a href="link5.html">fifth item</a> </ul> </div> '''#根据li标签进行分组
html = etree.HTML(text)
li_list = html.xpath("//li[@class='item-1']")#在每一组中继续进行数据的提取
for li in li_list:item = {}item["href"] = li.xpath("./a/@href")[0] if len(li.xpath("./a/@href"))>0 else Noneitem["title"] = li.xpath("./a/text()")[0] if len(li.xpath("./a/text()"))>0 else Noneprint(item)

结果是:

{'href': None, 'title': 'first item'}
{'href': 'link2.html', 'title': 'second item'}
{'href': 'link4.html', 'title': 'fourth item'}

7.案列:贴吧极速版:


代码如下:

import requests
from lxml import etreeclass TieBaSpider:def __init__(self, tieba_name):#1. start_urlself.start_url= "http://tieba.baidu.com/mo/q---C9E0BC1BC80AA0A7CE472600CDE9E9E3%3AFG%3D1-sz%40320_240%2C-1-3-0--2--wapp_1525330549279_782/m?kw={}&lp=6024".format(tieba_name)self.headers = {"User-Agent": "Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Mobile Safari/537.36"}self.part_url = "http://tieba.baidu.com/mo/q---C9E0BC1BC80AA0A7CE472600CDE9E9E3%3AFG%3D1-sz%40320_240%2C-1-3-0--2--wapp_1525330549279_782"def parse_url(self,url): #发送请求,获取响应# print(url)response = requests.get(url,headers=self.headers)return response.contentdef get_content_list(self,html_str): #3. 提取数据html = etree.HTML(html_str)div_list = html.xpath("//body/div/div[contains(@class,'i')]")content_list = []for div in div_list:item = {}item["href"] = self.part_url+div.xpath("./a/@href")[0]item["title"] = div.xpath("./a/text()")[0]item["img_list"] = self.get_img_list(item["href"], [])content_list.append(item)#提取下一页的url地址next_url = html.xpath("//a[text()='下一页']/@href")next_url = self.part_url + next_url[0] if len(next_url)>0 else Nonereturn content_list, next_urldef get_img_list(self,detail_url, img_list):#1. 发送请求,获取响应detail_html_str = self.parse_url(detail_url)#2. 提取数据detail_html = etree.HTML(detail_html_str)img_list += detail_html.xpath("//img[@class='BDE_Image']/@src")#详情页下一页的url地址next_url = detail_html.xpath("//a[text()='下一页']/@href")next_url = self.part_url + next_url[0] if len(next_url)>0 else Noneif next_url is not None: #当存在详情页的下一页,请求return self.get_img_list(next_url, img_list)#else不用写img_list = [requests.utils.unquote(i).split("src=")[-1] for i in img_list]return img_listdef save_content_list(self,content_list):#保存数据for content in content_list:print(content)def run(self): #实现主要逻辑next_url = self.start_urlwhile next_url is not None:#1. start_url#2. 发送请求,获取响应html_str = self.parse_url(next_url)#3. 提取数据content_list, next_url = self.get_content_list(html_str)#4. 保存self.save_content_list(content_list)#5. 获取next_url,循环2-5if __name__ == '__main__':tieba = TieBaSpider("每日中国")tieba.run()

python中lxml模块的使用相关推荐

  1. python sys模块作用_浅谈Python中的模块

    模块 为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,很多编程语言都采用这种组织代码的方式.在Python中,一个.py文件就称之为一个模块(Mod ...

  2. python中Scipy模块求取积分

    python中Scipy模块求取积分的方法: SciPy下实现求函数的积分的函数的基本使用,积分,高等数学里有大量的讲述,基本意思就是求曲线下面积之和. 其中rn可认为是偏差,一般可以忽略不计,wi可 ...

  3. python中的time库安装步骤-python中time模块需要安装么

    time是python自带的模块,用于处理时间问题,提供了一系列的操作时间的函数. time模块中时间表现的格式主要有三种:(推荐学习:Python视频教程) timestamp时间戳,是以秒表示从& ...

  4. 关于python中requests模块导入问题-python中requests模块的使用方法

    本文实例讲述了python中requests模块的使用方法.分享给大家供大家参考.具体分析如下: 在HTTP相关处理中使用python是不必要的麻烦,这包括urllib2模块以巨大的复杂性代价获取综合 ...

  5. python哪里下载import包-详解python中的模块及包导入

    python中的导入关键字:import 以及from import 1.import import一般用于导入包以及模块. 不过有个小问题: (1)当导入的是模块的时候是可以直接可以使用模块内的函数 ...

  6. python中copy模块的使用,深拷贝和浅拷贝

    python中copy模块的使用,深拷贝和浅拷贝 文章目录: 一.copy模块的介绍 1.copy模块 二.copy模块的使用 拓展说明: 1.id( )函数的使用 2.is和== 的区别 pytho ...

  7. python中的模块和包

    模块 一 什么是模块 模块就是一组功能的集合体,可以通过导入模块来复用模块的功能. 比如我在同一个文件夹定义两个.py文件,分别命名为A.py和B.py,那么可以通过在A文件里通过import B来使 ...

  8. python中pyecharts模块全局配置_python中pyecharts模块的使用示例

    python中pyecharts模块的使用示例 发布时间:2020-11-24 09:28:53 来源:亿速云 阅读:66 作者:小新 小编给大家分享一下python中pyecharts模块的使用示例 ...

  9. Python中collections模块

    目录 Python中collections模块:模块实现了特定目标的容器,以提供Python标准内建容器 dict.list.set.tuple 的替代选择. Counter:字典的子类,提供了可哈希 ...

最新文章

  1. linux命令rname,linux的rename命令
  2. bd9.1 MySQL 常见问题
  3. 【面试必备】济南初级java培训
  4. mysql 备份 第三方工具_Mysql第三方备份工具Xtrabackup使用说明
  5. windows 下phpstudy 升级mysql版本5.7
  6. ML之MIC:利用某数据集计算机最大信息系数MIC并可视化MIC矩阵热图及其代码实现
  7. ad16不能去除铺铜_电镀废水去除重金属的方法
  8. 对于一些作用域自己的理解,望能帮助某人
  9. 《软件需求》读后感02
  10. display:inline-block 间隙
  11. devgis分享 只分享有价值的东西!http://download.csdn.net/user/devgis
  12. Arduino教程 初体验之点亮自带LED灯(含管脚图)
  13. 计算机硬盘根目录是什么,解决方案:硬盘根目录是什么意思?它存储在哪里?...
  14. netty服务器怎么推送消息,我来学Netty之推送消息给客户端
  15. Portal是什么东东
  16. 群晖download station中添加BT搜索引擎
  17. upset图形如何理解
  18. java三层架构实现登录_用户登录——三层架构
  19. J-Link各版本驱动的下载
  20. DHU Matlab Experiment【5】作业记录_第五章、第六章

热门文章

  1. Spring Schedule关闭订单
  2. php 删除硬链接,为什么要用软链接硬链接
  3. Python MongoDB--PyMongo
  4. HX720/HX711 数据采集及处理姿态解析(公式及源码)
  5. 常用软件滤波算法---摘自:FeoTech
  6. Session执行机制与原理
  7. DOM基本操作(二:对节点的操作)
  8. java实现int类型数组元素拷贝
  9. Struts框架原理分析之我见
  10. DOM——创建节点及节点属性与内部插入append()和appendTo()