Scrapy进阶知识点总结(二)——选择器Selectors
1. Selectors选择器
在抓取网页时,您需要执行的最常见任务是从HTML源提取数据。有几个库可用于实现此目的,例如:
- BeautifulSoup是Python程序员中非常流行的Web抓取库,它基于HTML代码的结构构造Python对象,并且相当好地处理坏标记,但它有一个缺点:它很慢。
- lxml是一个XML解析库(也可以解析HTML),它使用基于ElementTree的pythonic API 。(lxml不是Python标准库的一部分。)
Scrapy带有自己的提取数据机制。它们被称为选择器,因为它们“选择”由XPath或CSS表达式指定的HTML文档的某些部分。
XPath是一种用于在XML文档中选择节点的语言,也可以与HTML一起使用。CSS是一种将样式应用于HTML文档的语言。它定义选择器以将这些样式与特定HTML元素相关联。
Selector是基于lxml来构建的,支持XPath选择器、CSS选择器以及正则表达式,功能全面,解析速度和准确度非常高。
2. 选择器使用
1.通过response响应对象属性.selector构建选择器实例
response.selector.xpath('//span/text()').get()
使用XPath和CSS查询响应非常常见,响应包括另外两个快捷方式:response.xpath()和response.css():
>>> response.xpath('//span/text()').get()
'good'
>>> response.css('span::text').get()
'good'
2.直接使用Selectors构建
从HTML文本构造
>>> from scrapy.selector import Selector
>>> body = '<html><body><span>good</span></body></html>'
>>> Selector(text=body).xpath('//span/text()').get()
'good'
从响应构造
>>> from scrapy.selector import Selector
>>> from scrapy.http import HtmlResponse
>>> response = HtmlResponse(url='http://example.com', body=body)
>>> Selector(response=response).xpath('//span/text()').get()
'good'
3. CSS选择器
基础选择器
| 选择器 | 含义 |
| * | 通用元素选择器,匹配页面任何元素(这也就决定了我们很少使用) |
| #id | id选择器,匹配特定id的元素 |
| .class | 类选择器,匹配class包含(不是等于)特定类的元素 |
| element | 标签选择器 根据标签选择元素 |
| [attr] | 属性选择器 根据元素属性去选择 |
组合选择器
| 选择器 | 示例 | 示例说明 | 含义 |
| elementE,elementF | div,p | 选择所有<div>元素和<p>元素 | 多元素选择器,用”,分隔,同时匹配元素E或元素F |
| elementE elementF | div p | 选择<div>元素内的所有<p>元素 | 后代选择器,用空格分隔,匹配E元素所有的后代(不只是子元素、子元素向下递归)元素F |
| elementE>elementF | div>p | 选择所有父级是 <div> 元素的 <p> 元素 | 子元素选择器,用”>”分隔,匹配E元素的所有直接子元素 |
| elementE+elementF | div+p | 选择所有紧接着<div>元素之后的<p>元素 | 直接相邻选择器,匹配E元素之后的相邻的同级元素F |
| elementE~elementF | p~ul | 选择p元素之后的每一个ul元素 | 普通相邻选择器,匹配E元素之后的同级元素F(无论直接相邻与否) |
| .class1.class2 | .user.login | 匹配如<div class="user login">元素 | 匹配类名中既包含class1又包含class2的元素 |
CSS选择器是前端的基础,以上只给了比较重要的内容,具体CSS选择器内容可以去w3school参考
Scrapy中CSS选择器的拓展
根据W3C标准,CSS选择器不支持选择文本节点或属性值。但是在Web抓取环境中选择这些是非常重要的,Scrapy(parsel)实现了一些非标准的伪元素
- 要选择文本节点,使用
::text - 选择属性值,用
::attr(name) name是指你想要的价值属性的名称
#没有用::text,对selectors对象使用get方法后,返回的是匹配的html元素
>>> response.css('title').get()
<title>Example website</title>
#使用::text就是返回标签内的文本
>>> response.css('title::text').get()
'Example website'
#<a href='image1.html'>Name: My image 1 <br /><img src='image1_thumb.jpg' /></a> 使用a::attr(href)可以提取属性
>>>response.css('a::attr(href)').get()
'image1.html'
4. XPath
XPath,全称 XML Path Language,即 XML 路径语言,它是一门在XML文档中查找信息的语言。XPath 最初设计是用来搜寻XML文档的,但是它同样适用于 HTML 文档的搜索。
1.XPath 使用路径表达式在 XML 文档中选取节点。节点是通过沿着路径或者 step 来选取的。 下面列出了最有用的路径表达式
| 表达式 | 描述 |
|---|---|
| nodename | 选取此节点的所有子节点。 |
| / | 从根节点选取。 |
| // | 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。 |
| . | 选取当前节点。 |
| .. | 选取当前节点的父节点。 |
| @ | 选取属性。 |
举例如下
| 路径表达式 | 结果 |
|---|---|
| bookstore | 选取 bookstore 元素的所有子节点。 |
| /bookstore |
选取根元素 bookstore。 注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径! |
| bookstore/book | 选取属于 bookstore 的子元素的所有 book 元素。 |
| //book | 选取所有 book 子元素,而不管它们在文档中的位置。 |
| bookstore//book | 选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置。 |
| //@lang | 选取名为 lang 的所有属性。 |
2.谓语用来查找某个特定的节点或者包含某个指定的值的节点。谓语被嵌在方括号中。
| 路径表达式 | 结果 |
|---|---|
| /bookstore/book[1] | 选取属于 bookstore 子元素的第一个 book 元素。 |
| /bookstore/book[last()] | 选取属于 bookstore 子元素的最后一个 book 元素。 |
| /bookstore/book[last()-1] | 选取属于 bookstore 子元素的倒数第二个 book 元素。 |
| /bookstore/book[position()<3] | 选取最前面的两个属于 bookstore 元素的子元素的 book 元素。 |
| //title[@lang] | 选取所有拥有名为 lang 的属性的 title 元素。 |
| //title[@lang='eng'] | 选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性。 |
| /bookstore/book[price>35.00] | 选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00。 |
| /bookstore/book[price>35.00]/title | 选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00。 |
3.选取未知节点
| 通配符 | 描述 |
|---|---|
| * | 匹配任何元素节点。 |
| @* | 匹配任何属性节点。 |
| node() | 匹配任何类型的节点。 |
实例如下:
| 路径表达式 | 结果 |
|---|---|
| /bookstore/* | 选取 bookstore 元素的所有子元素。 |
| //* | 选取文档中的所有元素。 |
| //title[@*] | 选取所有带有属性的 title 元素。 |
同样scrapy也给XPath拓展了方法,使用.//text()可以选择文本
摘自https://www.w3school.com.cn/xpath/xpath_syntax.asp
5. .xpath()和.css()方法
css(query)
应用给定的CSS选择器并返回一个SelectorList实例。(SelectorList实例可以理解为Selector组成的list)
query 是一个包含要应用的CSS选择器的字符串。
在后台,CSS查询使用cssselect库和run .xpath()方法转换为XPath查询 。
>>> response.css("link")
[<Selector xpath='descendant-or-self::link' data='<link rel="alternate" type="text/html" h'>,
<Selector xpath='descendant-or-self::link' data='<link rel="next" type="application/atom+'>,
...
xpath(query, namespaces=None, **kwargs)
查找与xpath匹配的节点query,并将结果作为SelectorList实例返回, 并将所有元素展平。List元素也实现了Selector接口。
query 是一个包含要应用的XPATH查询的字符串。
namespaces是一个可选的映射(dict),用于注册的人的附加前缀。相反,这些前缀不会保存以供将来调用。
>>> response.xpath("//link")
[<Selector xpath='//link' data='<link rel="alternate" type="text/html" h'>,
<Selector xpath='//link' data='<link rel="next" type="application/atom+'>,
...
串联查询
由于css()与xpath()方法返回SelectorList实例,并且SelectorList实例也有与Selector对象相同的方法(SelectorList实例的方法可以理解为list中所有Selector遍历执行),所以可以在返回结果上继续查询
response.css(".quote").css("small")
#这个就是先查找出所有class=quote的元素,然后在这些元素中查找small标签元素
6. .get()与.getall()
get()
以unicode字符串返回第一个真实的数据,没有css xpath拓展方法(::text ::attr //text()),就返回匹配的html元素数据
getall()
以unicode字符串list返回所有数据,其它同get()一样
默认返回值
如果没有匹配到元素则返回None,但是可以提供默认返回值作为参数,以代替None
>>> response.xpath('//div[@id="not-exists"]/text()').get(default='not-found')
'not-found'
.get() .getall()与extract() extract_first()
SelectorList.get()与SelectorList.extract_first()实际是一样的,同理SelectorList.getall()与SelectorList.extract()相同
7. Selector其他属性方法
.attrib
返回底层元素的属性字典
>>> response.css('img').attrib['src']
'image1_thumb.jpg'
re(regex,replace_entities = True )
Selector还有一种.re()使用正则表达式提取数据的方法。但是,与 .xpath()或 .css()不同,.re()返回unicode字符串列表。所以你不能构造嵌套的.re()调用。
>>> response.xpath('//a[contains(@href, "image")]/text()').re(r'Name:\s*(.*)')
['My image 1',
'My image 2',
'My image 3',
'My image 4',
'My image 5']
Scrapy进阶知识点总结(二)——选择器Selectors的更多相关文章
- Scrapy进阶知识点总结(一)——基本命令与基本类(spider,request,response)
一.常见命令 scrapy全局命令可以在任何地方用,项目命令只能在项目路径下用 全局命令: 项目命令: startproject crawl genspider check settings list ...
- Scrapy进阶知识点总结(三)——Items与Item Loaders
一.Items 抓取的主要目标是从非结构化源(通常是网页)中提取结构化数据.Scrapy蜘蛛可以像Python一样返回提取的数据.虽然方便和熟悉,但Python缺乏结构:很容易在字段名称中输入拼写错误 ...
- Scrapy进阶知识点总结(六)——中间件详解
概述 查看scrapy官网的框架图,可以看出中间件处于几大主要组件之间,类似于生产流水线上的加工过程,将原料按照不同需求与功能加工成成品 其中4,5处于下载器与引擎之间的就是下载中间件,而spider ...
- Scrapy进阶知识点总结(五)——Settings
1.设置优先级 Scrapy中有不同层次的设置,其类型以及优先级如下(从高到低): 1.命令行命令中指定的设置 2.每个spider中的设置 3.scrapy项目中settings.py设置 4.命令 ...
- Scrapy进阶知识点总结(四)——Item Pipeline
Item Pipeline Item Pipeline调用发生在Spider产生Item之后.当Spider解析完Response之后,Item就会传递到Item Pipeline,被定义的Item ...
- scrapy爬虫学习系列二:scrapy简单爬虫样例学习
系列文章列表: scrapy爬虫学习系列一:scrapy爬虫环境的准备: http://www.cnblogs.com/zhaojiedi1992/p/zhaojiedi_python_00 ...
- scrapy基本使用(二)
scrapy基本使用(二) 参考链接: http://scrapy-chs.readthedocs.io/zh_CN/0.24/intro/tutorial.html#id5 scrapy基本使用(一 ...
- js进阶 10-8 伪类选择器有哪几类(自己不用,永远不是自己的)
js进阶 10-8 伪类选择器有哪几类(自己不用,永远不是自己的) 一.总结 一句话总结:自己不用,永远不是自己的. 0.学而不用,却是为何? 自己不用,永远不是自己的,有需求的时候要想到它,然后操作 ...
- 网页爬虫--scrapy进阶
本篇将谈一些scrapy的进阶内容,帮助大家能更熟悉这个框架. 1. 站点选取 现在的大网站基本除了pc端都会有移动端,所以需要先确定爬哪个. 比如爬新浪微博,有以下几个选择: www.weibo.c ...
随机推荐
- python编程基础之三十五
系统的魔术方法:系统的魔术方法特别多,但是也都特别容易懂,简单的讲就是对系统的内置函数进行重写,你需要什么效果就重写成什么样, 比如说len()方法针对的对象本来没有自定义类的对象,但是当你重写了__ ...
- 主动降噪(Active Noise Control)
智能耳机 人机交互 智能声学终端 智能耳机 智能音箱 智能听力器 喇叭单体 动圈喇叭 新材料 DLC 石墨烯 陶瓷单位 吸音材料 智能芯片 阵列式麦克风 声纹传感器 演算法 降噪算法 智能听力保护 A ...
- 毕业设计过程中的一些学习Android网站
安卓巴士:http://www.apkbus.com/CSDN:(下载资源)http://www.csdn.net/?ref=toolbar博客园:http://www.cnblogs.com/极客学 ...
- 超级好用的 Java 数据可视化库:Tablesaw
本文适合刚学习完 Java 语言基础的人群,跟着本文可了解和使用 Tablesaw 项目.示例均在 Windows 操作系统下演示 本文作者:HelloGitHub-秦人 HelloGitHub 推出 ...
- C# 委托 (一)—— 委托、 泛型委托与Lambda表达式
C# 委托 (一)—— 委托. 泛型委托与Lambda表达式 2018年08月19日 20:46:47 wnvalentin 阅读数 2992 版权声明:此文乃博主之原创.鄙人才疏,望大侠斧正.此 ...
- [POJ2248] Addition Chains 迭代加深搜索
Addition Chains Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 5454 Accepted: 2923 ...
- python中使用logging将日志写入文件或输出到控制台
import logging import os class Logger: def __init__(self, name=__name__): # 创建一个loggger self.__name ...
- 10.Linux用户权限
1.权限基本概述 1. 什么是权限? 我们可以把它理解为操作系统对用户能够执行的功能所设立的限制,主要用于约束用户能对系统所做的操作,以及内容访问的范围,或者说,权限是指某个特定的用户具有特定的系统资 ...
- Gitlab CI 集成 Kubernetes 集群部署 Spring Boot 项目
在上一篇博客中,我们成功将 Gitlab CI 部署到了 Docker 中去,成功创建了 Gitlab CI Pipline 来执行 CI/CD 任务.那么这篇文章我们更进一步,将它集成到 K8s 集 ...
- JavaScript 实用技巧
1数组中删除重复 let arr = [1,2,4,3,6,4] Array.from(new Set(arr)) // es6中 .from()[1,2,4,3,6] [...new Set(arr ...