人生苦短,我用 Python

前文传送门:

小白学 Python 爬虫(1):开篇

小白学 Python 爬虫(2):前置准备(一)基本类库的安装

小白学 Python 爬虫(3):前置准备(二)Linux基础入门

小白学 Python 爬虫(4):前置准备(三)Docker基础入门

小白学 Python 爬虫(5):前置准备(四)数据库基础

小白学 Python 爬虫(6):前置准备(五)爬虫框架的安装

小白学 Python 爬虫(7):HTTP 基础

小白学 Python 爬虫(8):网页基础

小白学 Python 爬虫(9):爬虫基础

小白学 Python 爬虫(10):Session 和 Cookies

小白学 Python 爬虫(11):urllib 基础使用(一)

小白学 Python 爬虫(12):urllib 基础使用(二)

小白学 Python 爬虫(13):urllib 基础使用(三)

小白学 Python 爬虫(14):urllib 基础使用(四)

小白学 Python 爬虫(15):urllib 基础使用(五)

小白学 Python 爬虫(16):urllib 实战之爬取妹子图

小白学 Python 爬虫(17):Requests 基础使用

小白学 Python 爬虫(18):Requests 进阶操作

小白学 Python 爬虫(19):Xpath 基操

小白学 Python 爬虫(20):Xpath 进阶

小白学 Python 爬虫(21):解析库 Beautiful Soup(上)

小白学 Python 爬虫(22):解析库 Beautiful Soup(下)

小白学 Python 爬虫(23):解析库 pyquery 入门

小白学 Python 爬虫(24):2019 豆瓣电影排行

小白学 Python 爬虫(25):爬取股票信息

小白学 Python 爬虫(26):为啥买不起上海二手房你都买不起

小白学 Python 爬虫(27):自动化测试框架 Selenium 从入门到放弃(上)

小白学 Python 爬虫(28):自动化测试框架 Selenium 从入门到放弃(下)

小白学 Python 爬虫(29):Selenium 获取某大型电商网站商品信息

小白学 Python 爬虫(30):代理基础

小白学 Python 爬虫(31):自己构建一个简单的代理池

小白学 Python 爬虫(32):异步请求库 AIOHTTP 基础入门

小白学 Python 爬虫(33):爬虫框架 Scrapy 入门基础(一)

小白学 Python 爬虫(34):爬虫框架 Scrapy 入门基础(二)

引言

我们之前有介绍过通过 pyquery 、 Beautiful Soup 、 lxml 来提取网页数据。

但是在 Scrapy 中,同样也提供了自己独有的数据提取方式,即 Selector(选择器)。Selector 是基于 lxml 来构建的,支持 XPath 选择器、CSS 选择器以及正则表达式,功能全面,解析速度和准确度非常高。

独立使用

Scrapy Selectors 是 Parsel 库的包装。包装的目的是提供与 Scrapy Response 对象的更好的集成。

Parsel 是一个独立的 Web 抓取库,无需 Scrapy 即可使用。它在后台使用 lxml 库,并在 lxml API 之上实现了一个简单的 API 。这意味着 Scrapy 选择器的速度和解析精度与 lxml 非常相似。

我们可以写一个简单的示例代码来测试一下 Selectors 的单独使用。

from scrapy import Selector

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

执行结果如下:

Hello Python

这个简单的示例我们并没有在 Scrapy 框架中执行,而是把 Scrapy 中的 Selector 单独拿出来使用了。

Selector 的使用同其他解析库类似,如果方便的话,我们也可以在其他项目中直接使用 Selector 来提取数据。

Scrapy Shell

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

这里我们借助官方文档的示例进行演示。

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

为了完整起见,以下是其完整的HTML代码:

<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' /></a>
<a href='image2.html'>Name: My image 2 <br /><img src='image2_thumb.jpg' /></a>
<a href='image3.html'>Name: My image 3 <br /><img src='image3_thumb.jpg' /></a>
<a href='image4.html'>Name: My image 4 <br /><img src='image4_thumb.jpg' /></a>
<a href='image5.html'>Name: My image 5 <br /><img src='image5_thumb.jpg' /></a>
</div>
</body>
</html>

首先,让我们开启 Scrapy shell,在命令行输入如下命令:

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

这时,我们进入了 Scrapy Shell 模式,其实就是 Scrapy 发起了一次请求,然后把一些可操作的变量传递给我们:

Xpath 选择器

目前我们在 Scrapy shell 之中,这里我们主要操作的对象是 response 。

response 有一个属性是 selector ,我们可以通过调用 response.selector.xpath 对数据进行获取,同时, Scrapy 为我们提供了两个更加简洁的方法, response.xpath() 和 response.css() ,这两个方法完全等同于 response.selector.xpath() 和 response.selector.css() 。

出于写法上的简便考虑,小编后续的代码将全部使用 response.xpath() 和 response.css() 。

首先,我们简单的获取一下 a 标签:

>>> result = response.xpath('//a')
>>> result
[<Selector xpath='//a' data='<a href="image1.html">Name: My image ...'>,
<Selector xpath='//a' data='<a href="image2.html">Name: My image ...'>,
<Selector xpath='//a' data='<a href="image3.html">Name: My image ...'>,
<Selector xpath='//a' data='<a href="image4.html">Name: My image ...'>,
<Selector xpath='//a' data='<a href="image5.html">Name: My image ...'>] >>> type(result)
<class 'scrapy.selector.unified.SelectorList'>

这里我们获取到的结果是由 Selector 组成的列表: SelectorList 。

它的类型是 scrapy.selector.unified.SelectorList

SelectorList 和 Selector 都可以继续调用 xpath() 和 css() 等方法来进一步提取数据。

接着上面的例子,我们继续尝试获取 a 标签中的 img 标签:

>>> result.xpath('./img')
[<Selector xpath='./img' data='<img src="image1_thumb.jpg">'>,
<Selector xpath='./img' data='<img src="image2_thumb.jpg">'>,
<Selector xpath='./img' data='<img src="image3_thumb.jpg">'>,
<Selector xpath='./img' data='<img src="image4_thumb.jpg">'>,
<Selector xpath='./img' data='<img src="image5_thumb.jpg">'>]

这里我们获取到了所有的 a 标签中的 img 标签。

注意: 选择器的最前方加 .,这代表提取元素内部的数据,如果没有加点,则代表从根节点开始提取。

此处我们用了./img 的提取方式,则代表从 a 节点里进行提取。如果此处我们用 //img ,则还是从 html 节点里进行提取。

现在我们已经获得了 Selector 类型的节点 a ,如果我们想要将 a 节点元素提取出来,可以使用 extract() 方法,如下:

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

这里我们如果想要获得内容的文本内容,可以使用 /text() ,如果想要获取 href 属性的内容可以使用 /@href

我们来看一个完整的示例:

>>> response.xpath('//a[@href="image1.html"]/text()').extract()
['Name: My image 1 ']

这里我们限制的结果,只查到的一条数据,很多情况下我们都会获得多条数据,这时如果想获取第一个元素的内容,可以使用索引的方式,如下:

>>> response.xpath('//a/text()').extract()[0]
'Name: My image 1 '

这样其实有一点点的小问题,如果当前我们需要的列表为空,这里直接会产生数组越界的异常。

Scrapy 为我们提供了另一个方法 extract_first() ,专门用来解决这个问题,上面的示例可以改写成下面的样子:

>>> response.xpath('//a/text()').extract_first()
'Name: My image 1 '

同时我们也可以为 extract_first() 方法设置一个默认值参数,这样当 XPath 规则提取不到内容时会直接使用默认值。

>>> response.xpath('//a[@href="image1"]/text()').extract_first('Default')
'Default'

CSS 选择器

我们接着看 CSS 选择器,还是上面的示例,小编这里就不多 BB 了,直接上示例:

>>> response.css('a')
[<Selector xpath='descendant-or-self::a' data='<a href="image1.html">Name: My image ...'>,
<Selector xpath='descendant-or-self::a' data='<a href="image2.html">Name: My image ...'>,
<Selector xpath='descendant-or-self::a' data='<a href="image3.html">Name: My image ...'>,
<Selector xpath='descendant-or-self::a' data='<a href="image4.html">Name: My image ...'>,
<Selector xpath='descendant-or-self::a' data='<a href="image5.html">Name: My image ...'>]

我们同样可以进行属性选择和嵌套选择:

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

接下来获取文本值和属性值的方法稍有区别:

>>> response.css('a[href="image1.html"]::text').extract()
['Name: My image 1 ']
>>> response.css('a[href="image1.html"] img::attr(src)').extract()
['image1_thumb.jpg']

获取文本和属性需要用 ::text::attr() 的写法。

当然,我们的 CSS 选择器和 Xpath 选择器一样可以嵌套选择,一个简单的小示例感受下:

>>> response.xpath('//a').css('img').xpath('@src').extract()
['image1_thumb.jpg', 'image2_thumb.jpg', 'image3_thumb.jpg', 'image4_thumb.jpg', 'image5_thumb.jpg']

Selector 选择器就先介绍到这里了,更多的内容和用法可以参考官方文档:https://docs.scrapy.org/en/latest/topics/selectors.html

本文没什么代码,所以示例代码就不放了。

小白学 Python 爬虫(35):爬虫框架 Scrapy 入门基础(三) Selector 选择器的更多相关文章

  1. 小白学 Python 爬虫(36):爬虫框架 Scrapy 入门基础(四) Downloader Middleware

    人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...

  2. 小白学 Python 爬虫(37):爬虫框架 Scrapy 入门基础(五) Spider Middleware

    人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...

  3. 小白学 Python 爬虫(38):爬虫框架 Scrapy 入门基础(六) Item Pipeline

    人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...

  4. 小白学 Python 爬虫(40):爬虫框架 Scrapy 入门基础(七)对接 Selenium 实战

    人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...

  5. 小白学 Python 爬虫(41):爬虫框架 Scrapy 入门基础(八)对接 Splash 实战

    人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...

  6. 小白学 Python 爬虫(34):爬虫框架 Scrapy 入门基础(二)

    人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...

  7. 小白学 Python 数据分析(4):Pandas (三)数据结构 DataFrame

    在家为国家做贡献太无聊,不如跟我一起学点 Python 人生苦短,我用 Python 前文传送门: 小白学 Python 数据分析(1):数据分析基础 小白学 Python 数据分析(2):Panda ...

  8. 小白学 Python 数据分析(18):Matplotlib(三)常用图表(上)

    人生苦短,我用 Python 前文传送门: 小白学 Python 数据分析(1):数据分析基础 小白学 Python 数据分析(2):Pandas (一)概述 小白学 Python 数据分析(3):P ...

  9. 小白学 Python 爬虫(33):爬虫框架 Scrapy 入门基础(一)

    人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...

随机推荐

  1. 给博客添加rss订阅

    如果是自己搭建博客,有一个问题是如何写一篇新的文章就可以告诉读者,你写了一篇新的?一个简单方法是使用 rss ,RSS订阅是站点用来和其他站点之间共享内容的一种简易方式,即Really Simple ...

  2. 让 AE 输出 MPEG

    最近在做视频后期处理,但是我发现 AE 的文件都很大,大概一个 10 分钟视频 10G ,所以有什么办法让他输出的文件变小?一个方法是使用 MPEG 输出. 本文告诉大家如何让 AE 输出 MPEG ...

  3. CSS属性Display(显示)和Visibility(可见性)

    隐藏一个元素可以通过把display属性设置为“none”,或把visibility属性设置为“hidden”.但是请注意,这两种方法会产生不同的效果. Visibility:hidden可以隐藏某个 ...

  4. pytorch更新

    Pytorch如何更新版本与卸载,使用pip,conda更新卸载Pytorch 2018年05月22日 07:33:52 醉雨轩Y 阅读数 19047   今天我们主要汇总如何使用使用ubuntu,C ...

  5. jq实现简单手风琴效果

    文章地址:https://www.cnblogs.com/sandraryan/ 利用slideUp slideDown动画 <!DOCTYPE html> <html lang=& ...

  6. java NIO之HelloWorld

    Java NIO(New IO)是从Java 1.4版本开始引入的一个新的IO API,可以替代标准的Java IO API,以便提高传输速度.但实际上,在最新的JDK中旧的I/0包已经使用NIO重新 ...

  7. 微信小程序下拉刷新真机无法弹回

    在下拉函数里加上这句wx.stopPullDownRefresh(); /** * 页面相关事件处理函数--监听用户下拉动作 */ onPullDownRefresh: function () { v ...

  8. JS划重点——类和对象的不正经阐述

    JS划重点--类和对象的不正经阐述 /在JS 类里面函数也是一个对象,那么要创建一个对象就需要一个类,这个类可以由这个对牛逼的对象-函数来实现/ /首先是普罗大众都会的 工厂模式来创建一类/ func ...

  9. H3C 寻找邻居

  10. 定位问题 vue+element-ui+easyui(兼容性)

    项目背景:靠近浏览器窗口的各个方向(左上.下.左.右)都有不同的模态框悬浮于窗口,这里针对于底部组件定位的选择(主要针对pc端垂直方向上的定位) 1.百分比:easyui的window窗口定位方式:设 ...