Scrapy Selector选择器

一般我们爬取的内容的html网页,并且从网页中获取我们想要的数据。Scrapy提供了Selectors(选择器)通过xpath和css等方式,选取指定的元素

Selector

Selector构造器需要text或者TextResponse参数。Selector类提供了xpath,css,re三种方式选取元素。

  • xpath() 返回SelectorList 实例
  • css() 返回SelectorList 实例
  • re() 返回匹配的Unicode字符串列表

为了处理方便 为response提供了selector属性。由于经常使用xpath和css,所以提供了简化的方式来调用这两个方法。

response.xpath("")  //response.selector.xpath("")
response.css("")   //response.selector.css("")
SelectorList

SelectorList 类是内建 list 类的子类,其列表元素实现了 Selector 的接口

  • xpath() 对列表中的每个元素调用 .xpath() 方法,返回结果为另一个单一化的 SelectorList 。
  • css() 对列表中的各个元素调用 .css() 方法,返回结果为另一个单一化的 SelectorList
  • re() 对列表中的各个元素调用 .re() 方法,返回结果为单一化的unicode字符串列表。
  • extract() 对列表中的各个元素调用 .extract() 方法,返回结果为单一化的unicode字符串列表
Xpath元素定位
1.xpath选取元素

xpath: xml 路径表达式用于在xml文档中选取节点。它是w3c的标准也可以用来选取HTML元素,因为HTML可以看作xml的子集。
最常用的路径表达式:

  • nodeName :选取该节点下的所有子节点。
    1. bookstore 选取bookstore元素下的所有子节点
  • /: 从根节点选取,以”/”开始的为绝对路径
    1. /bookstore 选取根元素bookstore
  • //: 选择所有匹配的元素(相对路径。
    1. //book 选取所有的book子元素
  • .:选取当前节点
  • ..:选取当前节点的父节点
  • @:选取属性 例: //@class选属性名为class的所有属性值
  • text() :获取元素的文本内容
  • contains : 获取包含xx的元素
    1. //div[contains(@class,'clear')] 。 选取包含class属性并且属性值为clear的所有div元素
    2. //h1[contains(text(),'python')] 。获取包含文本“python”的所有h1元素
  • starts-with:以什么开头
    1. //input[starts-with(@name,'pass')] 。 name属性以pass开头的所有input元素
    2. //p[starts-with(text(),'P')] 。 内容以P开头的所有p元素。
  • ends-width:以什么结尾
    1. //input[ends-with(@name,'word')]

上面被[]括起来的内容称之为谓语,谓语用来查找某个特定的节点或者包含某个指定的值的节点。

2.XPath 轴

轴可定义相对于当前节点的节点集。

  • ancestor 选取当前节点的所有先辈(父、祖父等)。
  • ancestor-or-self 选取当前节点的所有先辈(父、祖父等)以及当前节点本身。
  • attribute 选取当前节点的所有属性。
  • child 选取当前节点的所有子元素。
  • descendant 选取当前节点的所有后代元素(子、孙等)。
  • descendant-or-self 选取当前节点的所有后代元素(子、孙等)以及当前节点本身。
  • following 选取文档中当前节点的结束标签之后的所有节点。
  • following-sibling 选取当前节点之后的所有兄弟节点
  • namespace 选取当前节点的所有命名空间节点。
  • parent 选取当前节点的父节点。
  • preceding 选取文档中当前节点的开始标签之前的所有节点。
  • preceding-sibling 选取当前节点之前的所有同级节点。
  • self 选取当前节点。
  • child::book 选取当前元素所有的book子节点
  • attribute::lang 选取当前节点的lang属性
  • child:: * 选取当前节点的所有子节点
  • child::text() 选取当前节点的所有文本子节点
  • descendant:: book 当前节点所有book后代元素

轴元素需要配合::使用,以后跟条件选择或者*

有一个案例比较全的xpath案例网站

css定位

开发人员来对css一定不陌生(ps:我是比较不喜欢调样式什么的)。在Scrapy的选择其中也提供了css的元素选择方式。一般而言使用css会比xpath书写更简单,这对于有过开发基础的人来说入门更简单,也可以加深自己对css选择器的运用。而且jquery中的元素选择sizzle其实源于css选择器。


选择器        例子                    例子描述   
.class      //.intro    选择 class="intro" 的所有元素。
#id         //  #firstname  选择 id="firstname" 的所有元素。
*           //* 选择所有元素。
element      //p    选择所有 <p> 元素。
element,element   //div,p   选择所有 <div> 元素和所有 <p> 元素。
element element    //div p  选择 <div> 元素内部的所有 <p> 元素。
element>element    //div>p  选择父元素为 <div> 元素的所有 <p> 元素。
element+element    //div+p  选择紧接在 <div> 元素之后的所有 <p> 元素。
[attribute]        //[target]   选择带有 target 属性所有元素。
[attribute=value]   //[target=_blank]   选择 target="_blank" 的所有元素。
[attribute~=value] //[title~=flower]  选择 title 属性包含单词 "flower" 的所有元素。
[attribute|=value]  //[lang|=en]    选择 lang 属性值以 "en" 开头的所有元素。  
:link              //a:link 选择所有未被访问的链接。
:visited           //a:visited  选择所有已被访问的链接。
:active           //a:active    选择活动链接。
:hover            //a:hover 选择鼠标指针位于其上的链接。
:focus           //input:focus  选择获得焦点的 input 元素。
:first-letter    //p:first-letter   选择每个 <p> 元素的首字母。
:first-line      //p:first-line 选择每个 <p> 元素的首行。
:first-child    //p:first-child 选择属于父元素的第一个子元素的每个 <p> 元素。   
:before         //p:before  在每个 <p> 元素的内容之前插入内容。    
:after          //p:after   在每个 <p> 元素的内容之后插入内容。    
:lang(language) //p:lang(it)    选择带有以 "it" 开头的 lang 属性值的每个 <p> 元素。
element1~element2  //p~ul 选择前面有 <p> 元素的每个 <ul> 元素。
[attribute^=value]  //a[src^="https"]   选择其 src 属性值以 "https" 开头的每个 <a> 元素。
[attribute$=value]	//a[src$=".pdf"] 选择其 src 属性以 ".pdf" 结尾的所有 <a> 元素。
[attribute*=value]  //a[src*="abc"] 选择其 src 属性中包含 "abc" 子串的每个 <a> 元素。
:first-of-type  //p:first-of-type   选择属于其父元素的首个 <p> 元素的每个 <p> 元素。   
:last-of-type   //p:last-of-type    选择属于其父元素的最后 <p> 元素的每个 <p> 元素。
:only-of-type   //p:only-of-type    选择属于其父元素唯一的 <p> 元素的每个 <p> 元素。
:only-child    //p:only-child   选择属于其父元素的唯一子元素的每个 <p> 元素。   
:nth-child(n)   //p:nth-child(2)    选择属于其父元素的第二个子元素的每个 <p> 元素。
:nth-last-child(n)  //p:nth-last-child(2)   同上,从最后一个子元素开始计数。    
:nth-of-type(n)   //p:nth-of-type(2)    选择属于其父元素第二个 <p> 元素的每个 <p> 元素。
:nth-last-of-type(n) //p:nth-last-of-type(2)    同上,但是从最后一个子元素开始计数。
:last-child   //p:last-child    选择属于其父元素最后一个子元素每个 <p> 元素。   
:root         //:root   选择文档的根元素。   
:empty      //p:empty   选择没有子元素的每个 <p> 元素(包括文本节点)。
:target     //#news:target  选择当前活动的 #news 元素。
:enabled    //input:enabled 选择每个启用的 <input> 元素。 
:disabled   //input:disabled    选择每个禁用的 <input> 元素
:checked    //input:checked 选择每个被选中的 <input> 元素。
:not(selector)  //:not(p)   选择非 <p> 元素的每个元素。
::selection  //::selection  选择被用户选取的元素部分。

其中后代选择器我经常弄错,现在梳理以下

<body>
    <div id="div1"> 
        <div id="div2">
            <div id="div3">
                xxxxxx

            </div>
            <ul>
            </ul>
            <div id="div4">

            </div>
        </div>
    </div>
</body>
后代元素

选取位于element1 下的所有element2 元素。包括子元素和后代元素

element1 element2   //body  div   选区所有div元素
子元素

与后代选择器相比,子元素选择器只能选择作为某元素子元素的元素。自匹配子元素不匹配后代元素

element > element
兄弟元素

相邻兄弟选择器可选择紧接在另一元素后的元素,且二者有相同父元素。

element + element

该选择器匹配出现在 element1 后面的所有 element2,两中元素具有相同的父元素

element1~element2

例子:
1. 获取一个页面所有的链接的方式

1)  //a/@href   
2)  //a/attribute::href 
3)  a::attr(href) 

2.选取名字为username的输入框的值

1) //input[contains(@name,'username')]/text()
2) input[name*='username']::text

猜你喜欢

转载自blog.csdn.net/yamadeee/article/details/79959669