Selector的使用

news2025/7/12 11:32:55

文章目录

  • Selector 的使用
    • 1.直接使用
    • 2. Scrapy Shell
    • 3.XPath 选择器
    • 4.CSS选择器
    • 5.正则匹配

Selector 的使用

我们之前介绍了利用Beautiful Soup、pyquery 以及正则表达式来提取网页数据的方法,确实非常方便。不过Scrapy提供了自己的数据提取方法,即内置的Selector。

Scrapy 中的Selector 是就是基于 parsel库来构建的、而同时parsel又依赖于lxml,Selector 对parsel进行了封装,使其能更好地与Scrapy结合使用。Selector 支持XPath选择器、CSS选择器以及正则表达式,功能全面,解析速度和准确度非常高。

本节我们就来详细介绍一下 Selector 的用法。

1.直接使用

Selector 其实并不一定非要在Scrapy 中使用,它也是一个可以独立使用的模块。我们可以直接利用Selector这个类来构建一个选择器对象,然后调用它的相关方法(如xpath、css等)来提取数据。例如,针对一段HTML代码,我们可以用如下方式构建Selector对象来提取数据:

from scrapy import Selector

body = '<html><head><title>Hello World</title></head><body></body></html>'
selector = Selector(text=body)
title = selector.xpath('//title/text()').extract_first()
print(title)

运行结果如下:
Hello World
这里没有在 Scrapy 框架中运行,而是把 Scrapy中的Selector 单独拿出来使用了,构建的时候传入text 参数,就生成了一个Selector选择器对象,然后就可以像Scrapy中的解析方式一样,调用xpath、css等方法来提取数据了。

在这里我们查找的是源代码中title内的文本,在XPath 选择器最后加text方法就可以实现文本的提取了。

以上内容就是 Selector 的直接使用方式。同 Beautiful Soup 等库类似,Selector 也是强大的网页解析库。如果方便的话,我们也可以在其他项目中直接使用 Selector 来提取数据。

接下来,我们用实例来详细讲解 Selector 的用法。

2. Scrapy Shell

由于Selector 主要是与Scrapy结合使用,如 Scrapy的回调函数中的参数response 直接调用 xpath或者 css 方法来提取数据,所以在这里我们借助 Scrapy shell 来模拟Scrapy 请求的过程,讲解相关的提取方法。

我们用官方文档的一个样例页面来做演示:https://doc.scrapy.org/en/latest/_static/selectors-sample1.html

开启 Scrapy shell,在命令行输入如下命令:

scrapy shell  https://doc.scrapy.org/en/latest/_static/selectors-sample1.html

我们就进入 Scrapy shell模式了。这个过程其实是Scrapy发起了一次请求,请求的URL就是刚才命令行下输入的URL,把一些可操作的变量传递给我们,如request、response等,如图15-7所示。

image-20221115210740082

Scrapy shell 模式我们可以在命令行模式下输入命令,调用对象的一些操作方法,按下回车之后实时显示结果。这与Python 的命令行交互模式类似。接下来演示的实例都将页面的源码作为分析目标,页面源码如下所示:

<html>
  <head>
    <base href='http://example.com/' />
    <title>Example website</title>
  </head>
  <body>
    <div id='images'>
      <a href='image1.html'>Name: My image 1 <br /><img src='image1_thumb.jpg' alt='image1'/></a>
      <a href='image2.html'>Name: My image 2 <br /><img src='image2_thumb.jpg' alt='image2'/></a>
      <a href='image3.html'>Name: My image 3 <br /><img src='image3_thumb.jpg' alt='image3'/></a>
      <a href='image4.html'>Name: My image 4 <br /><img src='image4_thumb.jpg' alt='image4'/></a>
      <a href='image5.html'>Name: My image 5 <br /><img src='image5_thumb.jpg' alt='image5'/></a>
    </div>
  </body>
</html>

3.XPath 选择器

进入Scrapy Shell 后,我们主要通过操作response 变量进行解析。因为我们解析的是HTML代码,Seector 将自动使用 HTML语法来分析。response 有一个属性selector,我们调用response.selector返回的内容就相当于用response的text构造了一个Selector对象。通过这个Selector对象,我们可以调用如xpath、css等解析方法,向方法传人XPath或CSS选择器参数就可以实现信息的提取。

我们用一个实例感受一下,代码如下所示:

image-20221115211133697

打印的结果的形式是Selector组成的列表,其实它是SelectorList类型,SelectorList和Selector都可以继续调用xpath和css等方法来进一步提取数据。

在上面的例子中,我们提取了a节点。接下来,我们尝试继续调用Xpath来提取a节点内包含的img节点,代码如下所示:

image-20221115212025949

我们获得了a节点里面的所有img节点,结果为5。

值得注意的是,选择器的最前方加.(一个点)代表提取元素内部的数据,如果没有加点,则代表从根节点开始提取。此处我么用./img的提取方式,代表从a节点里进行提取。如果我们此处用//img,则还是从html节点里进行提取。

我们刚才使用 response.selector.xpath 方法对数据进行了提取。Scrapy 提供了两个实用的快捷方法,response.xpath 和 response.css,二者的功能完全等同于 response. selector.xpath 和response.selector.css。

方便起见,后面我们统一直接调用response的xpath 和css方法进行选择。

现在我们得到的是 SelectorList 类型的变量,该变量是由 Selector 对象组成的列表。可以用索引单独取出其中某个Selector元素,代码如下所示:

image-20221115213033030

我们可以像操作列表一样操作这个Selectorlist。

但是现在获取的内容是 Selector 或者 SelectorList类型,并不是真正的文本内容。具体的内容怎么提取呢?

比如我们现在想提取a 节点元素,就可以利用extract方法,代码如下所示:

image-20221115213820848

这里使用了extract方法,我们可以把真实需要的内容获取下来。

我们还可以改写XPath 表达式,来选取节点的内部文本和属性,代码如下所示:

image-20221115214043394

我们只需要再加一层/text()就可以获取节点的内部文本,或者加一层/@href 就可以获取节点的href 属性。其中,@符号后面内容就是要获取的属性名称。

现在,我们可以用一个规则获取所有符合要求的节点,返回的类型是列表类型。

但是这里有一个问题:如果符合要求的节点只有一个,那么返回的结果会是什么呢?我们再用一个实例来感受一下,代码如下所示:

image-20221115215954838

我们用属性限制了匹配的范围,使XPath只可以匹配到一个元素。然后用extract方法提取结果,其结果还是一个列表形式,文本是列表的第一个元素。但很多情况下,我们想要的数据其实就是第个元素内容,这里我们通过加一个索引来获取,代码如下所示:

image-20221115220043318

但是,这个写法很明显是有风险的。一旦 XPath 有问题,extract后的结果可能是一个空列表。如果我们再用索引来获取,就可能导致数组越界。所以,另外一个方法可以专门提取单个元素,它叫作extract_first。我们可以改写上面的例子,相关代码如下:

image-20221115220130381

这样,我们直接利用extract_first 方法将匹配的第一个结果提取出来,同时也不用担心数组越界的问题了。

另外,我们也可以为extract_first 方法设置一个默认值,这样当XPath 规则提取不到内容时,就会直接使用默认值。例如将XPath 改成一个不存在的规则,重新执行代码,代码如下所示:

image-20221115220422307

这里,如果XPath 匹配不到任何元素,调用extract_first 会返回空,也不会报错。

在第二行代码中,我们还传递了一个参数当作默认值,如 Default Image。这样,如果 XPath 匹配不到结果,返回值会使用这个参数来代替,可以看到输出正是如此。

到现在为止,我们了解了Scrapy中的XPath的相关用法,包括嵌套查询、提取内容、提取单个内获取文本和属性等。

4.CSS选择器

接下来,我们看看CSS选择器的用法。

Scrapy的选择器同时还对接了CSS选择器,使用response.css方法就可以使用CSS选择器来选对应的元素了。

例如在上文我们选取了所有的a节点,那么CSS选择器同样可以做到,相关代码如下:

image-20221115220532945

同样,调用extract方法就可以提取节点,代码如下所示:

In [2]: response.css('a').extract()
Out[2]: 
['<a href="image1.html">Name: My image 1 <br><img src="image1_thumb.jpg" alt="image1"></a>','<a href="image2.html">Name: My image 2 <br><img src="image2_thumb.jpg" alt="image2"></a>','<a href="image3.html">Name: My image 3 <br><img src="image3_thumb.jpg" alt="image3"></a>','<a href="image4.html">Name: My image 4 <br><img src="image4_thumb.jpg" alt="image4"></a>','<a href="image5.html">Name: My image 5 <br><img src="image5_thumb.jpg" alt="image5"></a>']

可以看到,用法和Xpath选择是完全一样。

另外,我们也可以进行属性选择和嵌套选择,代码如下所示:

In [3]: response.css('a[href="image1.html"]').extract()
Out[3]: ['<a href="image1.html">Name: My image 1 <br><img src="image1_thumb.jpg" alt="image1"></a>']
In [4]: response.css('a[href="image1.html"] img').extract()
Out[4]: ['<img src="image1_thumb.jpg">']

这里用[href=“image.html”]限定了href属性,可以看到匹配结果就只有一个了。另外如果想查找a节点内的img节点,只需要再加一个空格和img。选择器的写法和标准CSS选择器写法如出一辙。

我们也可以使用extract_first方法提取列表的第一个元素,比如:

In [5]: response.css('a[href="image1.html"] img').extract_first()
Out[5]: '<img src="image1_thumb.jpg">'

接下来的两个用法不太一样。节点的内部文本和属性的获取是这样实现的:

In [6]: response.css('a[href="image1.html"]::text').extract_first()
Out[6]: 'Name: My image 1 '

In [7]: response.css('a[href="image1.html"] img::attr(src)').extract_first()
Out[7]: 'image1_thumb.jpg'

获取文本和属性需要用::text和::attr的写法,而其他库如 Beautiful Soup或 pyquery 都有单独的方法。

另外,CSS选择器和XPath选择器一样,能够嵌套选择。我们可以先用XPath选择器选中所有a节点,再利用CSS 选择器选中 img 节点,然后用 XPath 选择器获取属性。我们用一个实例来感受一下,代码如下所示:

image-20221115223557410

我们成功获取了所有img节点的src属性。

因此,我们可以随意使用xpath 和css方法,二者自由组合实现嵌套查询,它们是完全兼容的。

5.正则匹配

Scrapy的选择器还支持正则匹配。比如在示例的a节点中,文本类似于Name:My image 1,现在我们只想把 Name:后面的内容提取出来,就可以借助re方法,代码实现如下:

image-20221115224101315

我们给re方法传了一个正则表达式,其中(.*)就是要匹配的内容,输出的结果就是正则表达式匹配的分组,结果会依次输出。

如果同时存在两个分组,那么结果依然会被按序输出,代码如下所示:

image-20221115224458893

类似extract_first方法,re_first方法可以选取列表的第一个元素,用法如下:

image-20221115224417358

不论正则匹配了几个分组,结果都会等于列表的第一个元素。

值得注意的是,response对象不能直接调用re和re_first方法。如果想要对全文进行正则匹配,可以先调用Xpath方法再正则匹配,代码如下所示:

image-20221115225104438

通过上面的例子我们可以看到,直接调用re方法会提示没有re属性。但是这里首先调用xpath(‘.’)选中全文,然后调用了re和re_first方法,就可以进行正则匹配了。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[附源码]java毕业设计社区志愿者服务系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

传输中的差错检验技术

差错检验 在网络传输过程数据难免会产生错误&#xff0c;需要使用差错检验技术进行纠错&#xff0c;可靠传输技术避免错误的发生 1 术语 比特差错 误码率BER 差错检验码 2 奇偶校验&#xff08;不会采用&#xff09; 在待发送的数据后面添加1位奇偶校验位&#xff0c;使整…

MyBatis基于XML的详细使用-参数、返回结果 处理

1、参数的取值方式 在xml文件中编写sql语句的时候有两种取值的方式&#xff0c;分别是#{}和${}。 注意:这里推荐使用#{}的方式,可以有效的防止sql注入问题。 2、select的参数传递 1.单个参数&#xff1a; 不管多少个参数最好在参数前加上param注解,为其取一个别名 2.多个参数…

[网络工程师]-传输层协议-TCP拥塞控制

TCP拥塞控制的概念是&#xff1a;每个源端判断当前网络中有多少可用容量&#xff0c;从而知道它可以安全完成传送的分组数。拥塞控制解释防止过多的数据注入网络&#xff0c;避免网络中间设备&#xff08;路由器、交换机等&#xff09;过载而发生拥塞。拥塞控制是一个全局性的过…

数据结构系列学习(九) - 循环队列(Circular_Queue)

目录 引言&#xff1a; 学习&#xff1a; 循环队列设计背景&#xff1a; 利用顺序表的思维对队列进行探讨&#xff1a; 解决方案的思考&#xff1a; 循环队列中循环的体现&#xff1a; 循环队列的要点&#xff1a; 第一个难点&#xff1a; 第二个难点&#xff1a; 第三…

Verilog 显示任务($display, $write, $strobe, $monitor)

Verilog 中主要用以下 4 种系统任务来显示&#xff08;打印&#xff09;调试信息&#xff1a;$display, $write, $strobe, $monitor。 $display $display 使用方法和 C 语言中的 printf 函数非常类似&#xff0c;可以直接打印字符串&#xff0c;也可以在字符串中指定变量的格…

7. 微服务之Docker自动化部署

7.1 Docker 介绍 Docker 是一个快速交付应用、运行应用的技术&#xff1a; 可以将程序及其依赖、运行环境一起打包为一个镜像&#xff0c;可以迁移到任意Linux操作系统运行时利用沙箱机制形成隔离容器&#xff0c;各个应用互不干扰启动、移除都可以通过一行命令完成&#xff…

华清远见:驱动点灯第N回目

1.在串口工具进行输入&#xff1a; echo 1 > /dev/myled0 ---->led1灯点亮 echo 0 > /dev/myled0 ---->led1灯熄灭 echo 1 > /dev/myled1 ---->led1灯点亮 echo 0 > /dev/myled1 ---->led1灯熄灭 echo 1 > /dev/myled2 ---->led1灯点亮 ec…

力扣刷题day52|84. 柱状图中最大的矩形

文章目录84. 柱状图中最大的矩形思路动态规划单调栈84. 柱状图中最大的矩形 力扣题目链接 给定 n 个非负整数&#xff0c;用来表示柱状图中各个柱子的高度。每个柱子彼此相邻&#xff0c;且宽度为 1 。 求在该柱状图中&#xff0c;能够勾勒出来的矩形的最大面积。 示例 1: …

空间域图像增强处理-含Labview程序

⭕⭕ 目 录 ⭕⭕✳️ 一、引言✳️ 二、领域图像增强实例分析✳️ 2.1 线性滤波实例分析✳️ 2.2 非线性滤波实例分析✳️ 2.3 Canny边缘检测✳️ 三、Labview程序获取✳️ 一、引言 图像在其采集或传递过程中常会受到各种噪声的影响&#xff0c;这会导致其中包含的重要信息很…

忘机工尺谱 - 快速打谱软件

引言 为了实现高效快速打谱&#xff0c;我实现了一种词谱分离的输入方案&#xff0c;解决了当前工尺谱平台打谱过程频繁切换输入法和频繁点击鼠标等问题&#xff0c;大大提高了打谱效率。同时借鉴了Markdown编辑器”所见即所得“的思想&#xff0c;输入的同时可以见到排版后的…

java线程控制

java线程控制的语法很多 这里我们主要说以下三个方法 我们先新建一个包 包下建立两个类 customException 线程类 参考代码如下 public class customException extends Thread {public String name;public customException(){}public void run(){for(int i 0;i < 100;i)…

逆变器电力计量仪表可安装在分布式光伏运维云平台、光伏变电站

安科瑞 李可欣 1、概述 AcrelCloud-1200分布式光伏运维云平台通过监测光伏站点的逆变器设备&#xff0c;气象设备以及摄像头设备、帮助用户管理分散在各地的光伏站点。主要功能包括&#xff1a;站点监测&#xff0c;逆变器监测&#xff0c;发电统计&#xff0c;逆变器一次图&…

解决找不到依赖项的问题(根源直接解决)

&#xff08;文章最后&#xff0c;我会介绍一个万能解决方法&#xff09; 问题&#xff1a; 原因&#xff1a; &#xff08;1&#xff09;可能是你的本地仓库里没有该依赖项。 &#xff08;2&#xff09;如果有的话&#xff0c;可能是没有更新同步到idea 解决方法&#xff1…

基于Springboot+mybatis+mysql+html教育培训中心教学系统

基于Springbootmybatismysqlhtml教育培训中心教学系统一、系统介绍二、功能展示1.用户登陆2.用户注册3.个人中心4.人员信息管理5.课程管理6.缴费管理7.学生考勤管理8.器材管理9.问题管理&#xff08;学生、老师&#xff09;一、系统介绍 系统主要功能&#xff1a; 管理员&…

第五届“传智杯”全国大学生计算机大赛(练习赛)[传智杯 #5 练习赛] 时钟

[传智杯 #5 练习赛] 时钟 题目描述 你有一个电子钟&#xff0c;可以显示 0:00 到 23:59 之间的所有时间&#xff0c;以数字的形式显示。其中小时是 0 到 23&#xff08;0 时会显示一个 0&#xff0c;而 1 到 9 时不会显示前导 0&#xff09;&#xff0c;分钟是 00 到 59&…

矩阵分析与计算学习记录-矩阵函数

本章重点内容&#xff1a; 矩阵函数的定义和计算 矩阵函数的导数和积分&#xff1a;导数定义和性质、对矩阵变量的导数、矩阵函数的积分及其性质 利用矩阵函数求解线性常系数微分方程&#xff1a;一阶线性常系数微分方程、n阶线性常系数微分方程 1. 矩阵函数的定义和计算 1…

前端面试总结

自我检查&#xff1a; 1、 vue有哪些常用的指令 2、 v-if和v-show的区别? v-show 控制的哪个css元素?v-if和v-show初始条件都为false的时候哪个会加载? 3、 3.Vue常用的修饰符? .sync 怎么在子组件触发修改父组件属性的值?具体是$emit哪个事件触发修改? .sync 的原理有了…

栈的应用----括号匹配问题

1.题目 括号匹配 给定一个只包括 ‘(’&#xff0c;‘)’&#xff0c;‘{’&#xff0c;‘}’&#xff0c;‘[’&#xff0c;‘]’ 的字符串 s &#xff0c;判断字符串是否有效。 有效字符串需满足&#xff1a; 左括号必须用相同类型的右括号闭合。 左括号必须以正确的顺序闭合…

Linux常见指令与shell理解

Linux常用指令与shell理解 文章目录Linux常用指令与shell理解1. ls指令2. cd指令3. pwd命令4. touch指令5. mkdir指令6. rmdir和rm指令7. man指令8. cp指令9. mv指令10. cat与tac指令11. more指令12. less指令13. head指令14. tail指令15. 时间指令16. Cal指令17. find指令18. …