欢迎关注【无量测试之道】公众号,
Python编程学习资源干货、
Python+Appium框架APP的UI自动化、
Python+Selenium框架Web的UI自动化、
Python+Unittest框架API自动化、


文章下方有公众号二维码,可直接微信扫一扫关注即可。

一、基本概念说明

Scrapy数据解析主要有两个大类:xpath() 和 css() ,今天这篇文章主要讲解xpath如何解析我们想获取的页面数据。同时Scrapy还给我们提供自己的数据解析方法,即Selector(选择器),Selector是一个可独立使用的模块,我们可以用Selector类来构建一个选择器对象,然后调用它的相关方法如xpaht(), css()等来提取数据,它的常用写法如下:

1 response.selector.css() #这里的response就是我们请求页面返回的响应
2 response.selector.xpath()#可简写为(因为这两个解析的方法太通用了,所以就直接在response上面支持了这两个解析方法)
3 response.css()
4 response.xpath()
5 其中response.xpath() 这个数据解析方法是今天的主角。

Scrapy Shell 主要用于测试Scrapy项目中命令是否生效,可在bash下直接执行,这里我们通过使用Scrapy Shell来验证学习选择器提取网页数据,使用的是在windows下 cmd 命令行下执行此命令 scrapy shell http://lab.scrapyd.cn/page/1/ 来演示。

 

二、Scrapy Shell 提取数据演示

win+r 输入 cmd 回车—》进入到windows 交互命令行界面,输入:

 1  
 2 C:\Users\tdcengineer>scrapy version
 3 d:\program files\python36\lib\site-packages\scrapy\utils\project.py:94: ScrapyDeprecationWarning: Use of environment variables prefixed with SCRAPY_ to override settings is deprecated. The following environment variables are currently defined: HOME
 4 ScrapyDeprecationWarning
 5 Scrapy 2.2.0
 6 如果此命令执行不成功,就需要自己去配置环境变量了。
 7  
 8 执行如下命令:
 9 C:\Users\tdcengineer>scrapy shell http://lab.scrapyd.cn/page/1/ 
10 这是返回的信息:
11 [s] Available Scrapy objects:
12 [s] scrapy scrapy module (contains scrapy.Request, scrapy.Selector, etc)
13 [s] crawler <scrapy.crawler.Crawler object at 0x00000270455E3CC0>
14 [s] item {}
15 [s] request <GET http://lab.scrapyd.cn/page/1/>
16 [s] response <200 http://lab.scrapyd.cn/page/1/>
17 [s] settings <scrapy.settings.Settings object at 0x0000027046A3A240>
18 [s] spider <DefaultSpider 'default' at 0x27046d51320>
19 [s] Useful shortcuts:
20 [s] fetch(url[, redirect=True]) Fetch URL and update local objects (by default, redirects are followed)
21 [s] fetch(req) Fetch a scrapy.Request and update local objects
22 [s] shelp() Shell help (print this help)
23 [s] view(response) View response in a browser
24 >>>

 

Step1:  // 与 / 的使用,//表示文档下面的所有节点元素,/ 表示取当前节点的下一级元素
http://lab.scrapyd.cn/page/1/ 以下是本页面的网页源代码片段:

Python 爬虫之Scrapy《中》_python

1 >>> response.xpath("//body")  #加粗的地方注意一下,它就是取了body下面的所有元素,后面进行了省略展示,返回的是Selector 对象,并存放在list 里面。
2 [<Selector xpath='//body' data='<body>\n<!--[if lt IE 8]>\n <div cla...'>]
3  
4 >>> response.xpath("//body/header")  #注意页面源代码加粗内容与以下的加粗内容是一致的,我要取的就是body下面的header 元素。
5 [<Selector xpath='//body/header' data='<header id="header" class="clearfix">...'>]
6  
7 >>> response.xpath("//body/header/div/div/div/a")
8 [<Selector xpath='//body/header/div/div/div/a' data='<a id="logo" href="http://lab.scrapyd...'>]

 

Step2:  [] 相当于用来确定其中一个元素的位置,这个选择序号不是从 1 开始的,而是从 0 开始编号的

1 >>> response.xpath("//body/header/div/div/div/a")[0] #返回的不再是列表了,可以与上面的命令对比一下
2 <Selector xpath='//body/header/div/div/div/a' data='<a id="logo" href="http://lab.scrapyd...'>

 

Step3:  . 符号的使用,使用”.”表示当前节点元素,使用 xpath 可以连续调用,如果前一个 xpath 返回一个Selector 的列表,那么这个列表可以继续调用 xpath,功能是为每个列表元素调用 xpath,最后结果是全部元素调用 xpath 的汇总。

1 >>> response.xpath("//body/header/div/div/div").xpath("./a")
2 [<Selector xpath='./a' data='<a id="logo" href="http://lab.scrapyd...'>]

 

Step4:  text() 它可以得到一个 Selector 元素包含的文本值,文本值节点对象也是一个Selector 对象,可以再通过 extract()获取文本值。

1  
2 >>> response.xpath("//body/header/div/div/div").xpath("./a/text()")
3 [<Selector xpath='./a/text()' data='SCRAPY爬虫实验室 - SCRAPY中文网提供'>]

 

Step5:  "@attrName"得到一个 Selector 元素的 attrName 属性节点对象,属性节点对象也是一个 Selector 对象,通过 extract()获取属性值

1 >>> response.xpath("//body/header/div/div/div/p[@class='description']")
2 [<Selector xpath="//body/header/div/div/div/p[@class='description']" data='<p class="description">scrapy中文网:scra...'>]

 

Step6:  get() and getall() #都具有将xpath提取到的数据从Selector转换为unicode的作用,只不过get()返回字符串,getall()返回的是一个列表

1  
2 >>> response.xpath("//body/header/div/div/div/p[@class='description']").get()
3 '<p class="description">scrapy中文网:scrapy中文文档、scrapy教程、scrapy实战应有尽有,是你学习python爬虫的好去处!</p>'
4 >>>
5 >>> response.xpath("//body/header/div/div/div/p[@class='description']").getall()
6 ['<p class="description">scrapy中文网:scrapy中文文档、scrapy教程、scrapy实战应有尽有,是你学习python爬虫的好去处!</p>']

 

Step7:  *and @*,使用星号"*"代表任何 Element 节点,使用"@*"代表任何属性

>>> response.xpath("//body/header/*/div")#表示搜索//body/header的孙子节点div,中间隔开一层任何元素
[<Selector xpath='//body/header/*/div' data='<div class="row">\n <div cl...'>]
 
>>> response.xpath("//body/header/div/div[@*='row']/div/a") #表示搜索任何包含属性的//body/header/div/div元素下面的/div/a
[<Selector xpath="//body/header/div/div[@*='row']/div/a" data='<a id="logo" href="http://lab.scrapyd...'>]

 

Step8:  element/parent::*选择 element 的父节点,这个节点只有一个

1 >>> response.xpath("//body/header/div/parent::*")
2 [<Selector xpath='//body/header/div/parent::*' data='<header id="header" class="clearfix">...'>]

 

Step9:  following-sibling and preceding-sibling 使用"element/folllowing-sibling::"搜索 element 后面的同级的所有兄弟节点,使用"element/preceding-sibling::"搜索 element 前面的同级的所有兄弟节点

1 >>> response.xpath("//body/header/div/div/div/following-sibling::*")
2 [<Selector xpath='//body/header/div/div/div/following-sibling::*' data='<div class="col-mb-12">\n ...'>]
3  
4 >>> response.xpath("//body/header/div/div/div/preceding-sibling::*")
5 [<Selector xpath='//body/header/div/div/div/preceding-sibling::*' data='<div class="site-name col-mb-12 col-9...'>]

总结:今天的分享主要是讲到了如何解析页面元素并提取出来,使用了非常多的方式去获取,在“Python 爬虫之Scrapy《上》”文章里面也是用了本文中提到的提取方式,大家可以回过来去再看看。

备注:我的个人公众号已正式开通,致力于测试技术的分享,包含:大数据测试、功能测试,测试开发,API接口自动化、测试运维、UI自动化测试等,微信搜索公众号:“无量测试之道”,或扫描下方二维码:

Python 爬虫之Scrapy《中》_搜索_02

 添加关注,让我们一起共同成长!