Python 爬虫之Scrapy《中》
欢迎关注【无量测试之道】公众号,回复【领取资源】,
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/ 以下是本页面的网页源代码片段:
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自动化测试等,微信搜索公众号:“无量测试之道”,或扫描下方二维码:
添加关注,让我们一起共同成长!