lxml基本使用

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

XPath,全称XML Path Language,即XML路径语言,它是一门在XML文档中查找信息的语言,它最初是用来搜寻XML文档的,但是它同样适用于HTML文档的搜索。

XPath的选择功能十分强大,它提供了非常简明的路径选择表达式,另外,它还提供了超过100个内建函数,用于字符串、数值、时间的匹配以及节点、序列的处理等,几乎所有我们想要定位的节点,都可以用XPath来选择

lxml使用流程

lxml 库提供了一个 etree 模块,该模块专门用来解析 HTML/XML 文档,下面简单介绍一下 lxml 库的使用流程:

(1)导入模块

from lxml import etree

(2)创建解析对象
调用etree模块的HTML() 方法来创建HTML解析对象:

parse_html = etree.HTML(html)

HTML()方法能够将HTML标签字符串解析为HTML文件,该方法可以自动修正HTML 文本。

(3)调用xpath表达式
最后使用第二步创建的解析对象调用xpath()方法,完成数据的提取。

r_list = parse_html.xpath('xpath表达式')

xpath常用规则

表达式描述
nodename选取此节点的所有子节点
/从当前节点选取直接子节点
//从当前节点选取子孙节点
.选取当前节点
选取当前节点的父节点
@选取属性
*通配符,选择所有元素节点与元素名
@*选取所有属性
[@attrib]选取具有给定属性的所有元素
[@attrib=‘value’]选取给定属性具有给定值的所有元素
[tag]选取所有具有指定元素的直接子节点
[tag=‘text’]选取所有具有指定元素并且文本内容是text节点

下面结合lxml使用流程和xpath常用规则举几个例子,假定我们要处理的HTML代码如下:

<div class="wrapper">
  <a href="www.biancheng.net/product/" id="site">website product</a>
  <ul id="sitename">
    <li><a href="http://www.biancheng.net/" title="编程帮">编程</a></li>
    <li><a href="http://world.sina.com/" title="新浪娱乐">微博</a></li>
    <li><a href="http://www.baidu.com" title="百度">百度贴吧</a></li>
    <li><a href="http://www.taobao.com" title="淘宝">天猫淘宝</a></li>
    <li><a href="http://www.jd.com/" title="京东">京东购物</a></li>
    <li><a href="http://c.bianchneg.net/" title="C语言中文网">编程</a></li>
    <li><a href="http://www.360.com" title="360科技">安全卫士</a></li>
    <li><a href="http://www.bytesjump.com/" title=字节">视频娱乐</a></li>
    <li><a href="http://bzhan.com/" title="b站">年轻娱乐</a></li>
    <li><a href="http://hao123.com/" title="浏览器">搜索引擎</a></li>
  </ul>
</div>

(1)提取所有a标签内的文本信息

from lxml import etree
# 创建解析对象
parse_html=etree.HTML(html)
# 书写xpath表达式,提取文本最终使用text()
xpath_bds='//a/text()'
# 提取文本数据,以列表形式输出
r_list=parse_html.xpath(xpath_bds)
# 打印数据列表
print(r_list)

(2)获取所有href的属性值

from lxml import etree
# 创建解析对象
parse_html=etree.HTML(html)
# 书写xpath表达式,提取文本最终使用text()
xpath_bds='//a/@href'
# 提取文本数据,以列表形式输出
r_list=parse_html.xpath(xpath_bds)
# 打印数据列表
print(r_list)

(3)获取ul标签下的li标签下的a标签的href属性值

from lxml import etree
# 创建解析对象
parse_html=etree.HTML(html)
# 书写xpath表达式,提取文本最终使用text()
xpath_bds='//ul[@id="sitename"]/li/a/@href'
# 提取文本数据,以列表形式输出
r_list=parse_html.xpath(xpath_bds)
# 打印数据列表
print(r_list)

案例——爬取某一地区所有企业名称

这里有一个网站:http://m.54114.cn/luoyang/。以洛阳为例,里面按行业列出了该地区所有企业的名称。

通过进入不同的行业内查看,我们能发现他的url是有规律的:
http://m.54114.cn/luoyang/hangye1/、http://m.54114.cn/luoyang/hangye2/、……、一直到huangye20。

在翻看不同页的内容时,我们也发现url是有规律的:比如第二页的url是http://m.54114.cn/luoyang/hangye1_p2/,第三页的最后就是p3,依次类推。虽然第一页没有“_p1”的后缀,但是我们按照此规律进行尝试,发现也可以访问,这就简单了。

点进某一行业的页面,有几个东西是我们感兴趣的。首先就是这个标题。

在这里插入图片描述

通过html文档结构,我们能得到其对应的xpath为://div[@class="list_content"]/div[1]/strong/text()

然后就是这个总页数

在这里插入图片描述

总页数是倒数第二个a标签,所以我们能得到其对应的xpath为://div[@class="pagination2"]/a[last()-1]/@title

最后就是我们关心的企业名称

在这里插入图片描述

xpath为://div[@class="list_content"]/div[3]/ul/li/a/text()

最后得到总的爬取脚本:

import requests
from lxml import etree

# url = 'http://m.54114.cn/luoyang/hangye12_p1/'
headers = {
    'User-ASgent':
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36 Edg/119.0.0.0',
    'Host': 'm.54114.cn',
    'Cookie': 'ZDEDebuggerPresent=php,phtml,php3'
}


def get_content(url, xpath):
    response = requests.get(url, headers=headers)
    tree = etree.HTML(response.text)
    target = tree.xpath(xpath)
    return target


for i in range(1, 21):
    url = f'http://m.54114.cn/luoyang/hangye{i}_p1/'
    response = requests.get(url, headers=headers)
    tree = etree.HTML(response.text)
    filename = tree.xpath(
        '//div[@class="list_content"]/div[1]/strong/text()')[0]
    pages = tree.xpath('//div[@class="pagination2"]/a[last()-1]/@title')
    if len(pages) == 0:
        continue
    pages = int(pages[0][1:-1])
    file = open('./luoyang/' + filename + '.txt', 'w')
    for j in range(1, pages + 1):
        url = f'http://m.54114.cn/luoyang/hangye{i}_p{j}/'
        xpath = '//div[@class="list_content"]/div[3]/ul/li/a/text()'
        names = get_content(url, xpath)
        for name in names:
            file.write(name + '\n')
    file.close()

执行完的效果如下

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/149906.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Netty实战专栏 | NIO详解

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a; Netty实战专栏 ✨特色专栏&#xff1a…

C语言之深入指针(二)(详细教程)

C语言之深入指针 文章目录 C语言之深入指针1. 传值调用和传址调用2. 数组名的理解3. 使用指针访问数组3. ⼀维数组传参的本质 1. 传值调用和传址调用 写一个函数用来交换a b的值 传值调用&#xff1a; #include <stdio.h> void Swap1(int x, int y) {int tmp 0;tmp x;…

第十八章 Swing程序设计

Swing用于开发桌面窗体程序&#xff0c;是JDK的第二代GUI框架&#xff0c;其功能比JDK第一代GUI框架AWT更为强大、性能更加优良。但因为Swing技术推出时间太早&#xff0c;其性能、开发效率等不及一些其他流行技术&#xff0c;所以目前市场上大多数桌面窗体程序都不是由Java开发…

rabbitmq 集群搭建

RabbitMQ集群介绍 RabbitMQ集群是一组RabbitMQ节点&#xff08;broker&#xff09;的集合&#xff0c;它们一起工作以提供高可用性和可伸缩性服务。 RabbitMQ集群中的节点可以在同一物理服务器或不同的物理服务器上运行。 RabbitMQ集群的工作原理是&#xff0c;每个节点在一个…

12-使用vue2实现todolist待办事项

个人名片&#xff1a; &#x1f60a;作者简介&#xff1a;一名大二在校生 &#x1f921; 个人主页&#xff1a;坠入暮云间x &#x1f43c;座右铭&#xff1a;懒惰受到的惩罚不仅仅是自己的失败&#xff0c;还有别人的成功。 &#x1f385;**学习目标: 坚持每一次的学习打卡 文章…

Python杂谈--关于iter迭代器的一些讨论

首先我们来看下面一段代码&#xff1a; for i in range(5):print(i) 这是一段非常简单的代码&#xff0c;它会打印出“0-5”这五个数字。 此时在range()迭代器中&#xff0c;它的start为空(默认为无穷小)&#xff0c;stop为5&#xff0c;step为空(默认为1)。 此时我们在看下…

hidl hwbinder和binder混合使用相关的joinThreadPool问题解答

背景&#xff1a; 今天一个学员在群里有个提问如下图&#xff0c;怎么有两个joinThread&#xff0c;会执行么&#xff1f;joinThread不是死循环等待数据吗&#xff1f; /frameworks/av/media/mediaserver/main_mediaserver.cpp 当开始看到这个时候确实也觉得最后的hw的join根本…

电脑篇——将串口映射到远程电脑上

通过Windows自带的远程桌面连接功能&#xff0c;可以通过修改本地资源选项&#xff0c;将本机的串口/端口映射到远程电脑上。 即可将端口映射到远程电脑上。 &#xff08;在远程的电脑的设备管理器中可能不会显示&#xff0c;但是用串口调试相关的工具&#xff0c;是可以找到相…

JVM——类加载器(JDK8及之前,双亲委派机制)

目录 1.类加载器的分类1.实现方式分类1.虚拟机底层实现2.JDK中默认提供或者自定义 2.类加载器的分类-启动类加载器3.类加载器的分类-Java中的默认类加载器4.类加载器的分类-扩展类加载器5.类加载器的分类-类加载器的继承 2.类加载器的双亲委派机制 类加载器&#xff08;ClassLo…

文件上传_白名单、内容校验、竞争上传

服务端校验—后缀名白名单校验 服务端校验—文件内容头校验 竞争上传

ROS 学习应用篇(五)服务Server学习之自定义服务与调用

在之前我学着如何建立一个话题Topic的消息类型&#xff0c;那时候建立了一个msg文件&#xff0c;包括&#xff0c;消息名称和消息数据类型&#xff08;int还是什么之类的。&#xff09;&#xff0c;将其链接到CMakeList&#xff0c;.xml文件补录需要的依赖&#xff0c;CMakeLis…

十九章总结

一.Java绘图类 1.Graphics类 Graphics类是所有图形上下文的抽象基类&#xff0c;它允许应用程序在组件以及闭屏图像上进行绘制。Graphics类封装了Java支持的基本绘图操作所需的状态信息&#xff0c;主要包括颜色、字体、画笔、文本、图像等。 2.Graphics2D类 Graphics2…

Vue3问题:如何实现拼图验证+邮箱登录功能?前后端!

前端功能问题系列文章&#xff0c;点击上方合集↑ 序言 大家好&#xff0c;我是大澈&#xff01; 本文约3500字&#xff0c;整篇阅读大约需要5分钟。 本文主要内容分三部分&#xff0c;第一部分是需求分析&#xff0c;第二部分是实现步骤&#xff0c;第三部分是问题详解。 …

「软件设计」权威领域驱动设计(DDD)简介

「软件设计」权威领域驱动设计(DDD)简介 今天的企业应用程序无疑是复杂的&#xff0c;并依赖一些专门技术&#xff08;持久性&#xff0c;AJAX&#xff0c;Web服务等&#xff09;来完成它们的工作。作为开发人员&#xff0c;我们倾向于关注这些技术细节是可以理解的。但事实是…

一键将CSDN博客文章如何转为Markdown

文章目录 1.在CSDN博文页面点击右键&#xff0c;选择“检查”&#xff08;Google浏览器为例&#xff09;。2.在查看器中搜索article_content&#xff0c;找到对应内容&#xff0c;点击…复制为outerHTML。3.打开网址https://tool.lu/markdown/&#xff0c;点击HTML2MD&#xff…

准备搞OpenStack了,先装一台最新的Ubuntu 23.10

正文共&#xff1a;1113 字 25 图&#xff0c;预估阅读时间&#xff1a;2 分钟 依稀记得前面发了一篇Ubuntu的安装文档&#xff08;66%的经验丰富开发者和69%的学生更喜欢的Ubuntu的安装初体验&#xff09;&#xff0c;当时安装的是20.04.3的版本&#xff0c;现在看来已经是非常…

第一百七十三回 如何创建线性渐变背景

文章目录 1. 概念介绍2. 实现方法3. 代码与效果3.1 示例代码3.2 运行效果 4. 内容总结 我们在上一章回中介绍了"SegmentedButton组件"相关的内容&#xff0c;本章回中将介绍" 如何创建线性渐变背景"。闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. …

医学图像 开源数据整理合集1

本文为医学图像 开源数据整理合集&#xff0c;为科研数据提供方便和检索。 目录 1 NIH database of 100000 Chest X-rays 2 The Cancer Imaging Archive (TCIA) 3 National Institute for Mental Healths (NIMHs) OpenNeuro.org 4 RSNAs Quantitative Imaging Data Wareh…

Git目录不对,即当前文件夹不对应git仓库

报错信息是&#xff1a; fatal: not a git repository (or any of the parent directories): .git 如&#xff1a; 是当前文件夹不对应git仓库&#xff0c;一般在git clone之后&#xff0c;需要进入下一级文件夹才对应仓库。 在文件夹看&#xff0c;本层中没有.git文件夹&…