Scrapy基本概念——Selectors

一、Selector的基本使用

Selector,主要是Response用来提取数据的。当Spider的Request得到Response之后,Spider可以使用Selector提取Response中的有用的数据。使用.selector()代码如下:

>>> response.selector.xpath('//span/text()').get()
'good'

1、XPath和CSS

Selector可以使用两种方式提取数据,XPath和CSS。XPath是在XML文档中选择节点的语言,在HTML文档中也适用。CSS是应用在HTML文档样式中的语言,可以选择具有某些样式的节点。使用.xpath()和.css()代码如下:

提取元素的文本

>>> response.xpath('//span/text()').get()
'good'
>>> response.css('span::text').get()
'good'

提取元素的属性

>>> response.xpath('//base/@href').get()
'http://example.com/'
>>> response.css('base::attr(href)').get()
'http://example.com/'
>>> response.css('base').attrib['href']
'http://example.com/'

可以省去.selector(),使用快捷语法。由于.xpath()和.css()返回的是新的Selector列表,如果需要提取出最终的数据,还需要使用.get()和.getall()得到。

>>> response.xpath('//title/text()').getall()
['Example website']
>>> response.xpath('//title/text()').get()
'Example website'

2、RE

Selector还可以使用正则表达式提取数据,Regular Expression。不过与.xpath()和.css()不同的是,.re()返回的是字符串列表,.re_first()返回的是字符串。

>>> 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']
 >>> response.xpath('//a[contains(@href, "image")]/text()').re_first(r'Name:\s*(.*)')
'My image 1'

二、xpath语法&xpath例子

xpath语法

表达式

描述

nodename

选取此节点的所有子节点。

/

从根节点选取。

//

从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。

.

选取当前节点。

..

选取当前节点的父节点。

@

选取属性。

*

匹配任何元素节点。

@*

匹配任何属性节点。

node()

匹配任何类型的节点。

|

选取若干路径

xpath例子



    
        Harry Potter
        29.99
    
    
        Learning XML
        39.95
    

路径表达式

结果(选取节点)

bookstore

选取 bookstore 元素的所有子节点。

/bookstore

选取根元素 bookstore。

注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径!

bookstore/book

选取属于 bookstore 的子元素的所有 book 元素。

//book

选取所有 book 子元素,而不管它们在文档中的位置。

bookstore//book

选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置。

//@lang

选取名为 lang 的所有属性。

路径表达式

结果(谓语)

/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。

路径表达式

结果(选取未知节点)

/bookstore/*

选取 bookstore 元素的所有子元素。

//*

选取文档中的所有元素。

//title[@*]

选取所有带有属性的 title 元素。

三、css语法&css例子

选择器

例子

例子描述

.class

.intro

选择 class="intro" 的所有元素。

.class1.class2

.name1.name2

选择 class 属性中同时有 name1 和 name2 的所有元素。

.class1 .class2

.name1 .name2

选择作为类名 name1 元素后代的所有类名 name2 元素。

#id

#firstname

选择 id="firstname" 的元素。

*

*

选择所有元素。

element

p

选择所有

元素。

element.class

p.intro

选择 class="intro" 的所有

元素。

element,element

div, p

选择所有

元素和所有

元素。

element element

div p

选择

元素内的所有

元素。

element>element

div > p

选择父元素是

的所有

元素。

element+element

div + p

选择紧跟

元素的首个

元素。

element1~element2

p ~ ul

选择前面有

元素的每个

    元素。

[attribute]

[target]

选择带有 target 属性的所有元素。

[attribute=value]

[target=_blank]

选择带有 target="_blank" 属性的所有元素。

[attribute~=value]

[title~=flower]

选择 title 属性包含单词 "flower" 的所有元素。

[attribute|=value]

lang|=en]

选择 lang 属性值以 "en" 开头的所有元素。

[attribute^=value]

a[href^="https"]

选择其 src 属性值以 "https" 开头的每个 元素。

[attribute$=value]

a[href$=".pdf"]

选择其 src 属性以 ".pdf" 结尾的所有 元素。

[attribute*=value]

a[href*="abc"]

选择其 href 属性值中包含 "abc" 子串的每个 元素。

:empty

p:empty

选择没有子元素的每个

元素(包括文本节点)。

:first-child

p:first-child

选择属于父元素的第一个子元素的每个

元素。

::first-letter

p::first-letter

选择每个

元素的首字母。

::first-line

p::first-line

选择每个

元素的首行。

:first-of-type

p:first-of-type

选择属于其父元素的首个

元素的每个

元素。

:last-child

p:last-child

选择属于其父元素最后一个子元素每个

元素。

:last-of-type

p:last-of-type

选择属于其父元素的最后

元素的每个

元素。

:not(selector)

:not(p)

选择非

元素的每个元素。

:nth-child(n)

p:nth-child(2)

选择属于其父元素的第二个子元素的每个

元素。

:nth-last-child(n)

p:nth-last-child(2)

同上,从最后一个子元素开始计数。

:nth-of-type(n)

p:nth-of-type(2)

选择属于其父元素第二个

元素的每个

元素。

:nth-last-of-type(n)

p:nth-last-of-type(2)

同上,但是从最后一个子元素开始计数。

:only-of-type

p:only-of-type

选择属于其父元素唯一的

元素的每个

元素。

:only-child

p:only-child

选择属于其父元素的唯一子元素的每个

元素。

:root

:root

选择文档的根元素。

四、re语法&re例子

re语法

字符

描述

\

将下一个字符标记为一个特殊字符、或一个原义字符、或一个向后引用、或一个八进制转义符。例如,“n”匹配字符“n”。“\n”匹配一个换行符。串行“\\”匹配“\”而“\(”则匹配“(”。

^

匹配输入字符串的开始位置。如果设置了RegExp对象的Multiline属性,^也匹配“\n”或“\r”之后的位置。

$

匹配输入字符串的结束位置。如果设置了RegExp对象的Multiline属性,$也匹配“\n”或“\r”之前的位置。

*

匹配前面的子表达式零次或多次。例如,zo*能匹配“z”以及“zoo”。*等价于{0,}。

+

匹配前面的子表达式一次或多次。例如,“zo+”能匹配“zo”以及“zoo”,但不能匹配“z”。+等价于{1,}。

?

匹配前面的子表达式零次或一次。例如,“do(es)?”可以匹配“does”或“does”中的“do”。?等价于{0,1}。

{n}

n是一个非负整数。匹配确定的n次。例如,“o{2}”不能匹配“Bob”中的“o”,但是能匹配“food”中的两个o。

{n,}

n是一个非负整数。至少匹配n次。例如,“o{2,}”不能匹配“Bob”中的“o”,但能匹配“foooood”中的所有o。“o{1,}”等价于“o+”。“o{0,}”则等价于“o*”。

{n,m}

m和n均为非负整数,其中n<=m。最少匹配n次且最多匹配m次。例如,“o{1,3}”将匹配“fooooood”中的前三个o。“o{0,1}”等价于“o?”。请注意在逗号和两个数之间不能有空格。

?

当该字符紧跟在任何一个其他限制符(*,+,?,{n},{n,},{n,m})后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串“oooo”,“o+?”将匹配单个“o”,而“o+”将匹配所有“o”。

.

匹配除“\n”之外的任何单个字符。要匹配包括“\n”在内的任何字符,请使用像“(.|\n)”的模式。

(pattern)

匹配pattern并获取这一匹配。

(?:pattern)

匹配pattern但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用或字符“(|)”来组合一个模式的各个部分是很有用。例如“industr(?:y|ies)”就是一个比“industry|industries”更简略的表达式。

(?=pattern)

正向肯定预查,在任何匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如,“Windows(?=95|98|NT|2000)”能匹配“Windows2000”中的“Windows”,但不能匹配“Windows3.1”中的“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。

(?!pattern)

正向否定预查,在任何不匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如“Windows(?!95|98|NT|2000)”能匹配“Windows3.1”中的“Windows”,但不能匹配“Windows2000”中的“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始

(?<=pattern)

反向肯定预查,与正向肯定预查类拟,只是方向相反。例如,“(?<=95|98|NT|2000)Windows”能匹配“2000Windows”中的“Windows”,但不能匹配“3.1Windows”中的“Windows”。

(?

反向否定预查,与正向否定预查类拟,只是方向相反。例如“(?

x|y

匹配x或y。例如,“z|food”能匹配“z”或“food”。“(z|f)ood”则匹配“zood”或“food”。

[xyz]

字符集合。匹配所包含的任意一个字符。例如,“[abc]”可以匹配“plain”中的“a”。

[^xyz]

负值字符集合。匹配未包含的任意字符。例如,“[^abc]”可以匹配“plain”中的“p”。

[a-z]

字符范围。匹配指定范围内的任意字符。例如,“[a-z]”可以匹配“a”到“z”范围内的任意小写字母字符。

[^a-z]

负值字符范围。匹配任何不在指定范围内的任意字符。例如,“[^a-z]”可以匹配任何不在“a”到“z”范围内的任意字符。

\b

匹配一个单词边界,也就是指单词和空格间的位置。例如,“er\b”可以匹配“never”中的“er”,但不能匹配“verb”中的“er”。

\B

匹配非单词边界。“er\B”能匹配“verb”中的“er”,但不能匹配“never”中的“er”。

\cx

匹配由x指明的控制字符。例如,\cM匹配一个Control-M或回车符。x的值必须为A-Z或a-z之一。否则,将c视为一个原义的“c”字符。

\d

匹配一个数字字符。等价于[0-9]。

\D

匹配一个非数字字符。等价于[^0-9]。

\f

匹配一个换页符。等价于\x0c和\cL。

\n

匹配一个换行符。等价于\x0a和\cJ。

\r

匹配一个回车符。等价于\x0d和\cM。

\s

匹配任何空白字符,包括空格、制表符、换页符等等。等价于[ \f\n\r\t\v]。

\S

匹配任何非空白字符。等价于[^ \f\n\r\t\v]。

\t

匹配一个制表符。等价于\x09和\cI。

\v

匹配一个垂直制表符。等价于\x0b和\cK。

\w

匹配包括下划线的任何单词字符。等价于“[A-Za-z0-9_]”。

\W

匹配任何非单词字符。等价于“[^A-Za-z0-9_]”。

\xn

匹配n,其中n为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如,“\x41”匹配“A”。“\x041”则等价于“\x04&1”。正则表达式中可以使用ASCII编码。.

\num

匹配num,其中num是一个正整数。对所获取的匹配的引用。例如,“(.)\1”匹配两个连续的相同字符。

\n

标识一个八进制转义值或一个向后引用。如果\n之前至少n个获取的子表达式,则n为向后引用。否则,如果n为八进制数字(0-7),则n为一个八进制转义值。

\nm

标识一个八进制转义值或一个向后引用。如果\nm之前至少有nm个获得子表达式,则nm为向后引用。如果\nm之前至少有n个获取,则n为一个后跟文字m的向后引用。如果前面的条件都不满足,若n和m均为八进制数字(0-7),则\nm将匹配八进制转义值nm。

\nml

如果n为八进制数字(0-3),且m和l均为八进制数字(0-7),则匹配八进制转义值nml。

\un

匹配n,其中n是一个用四个十六进制数字表示的Unicode字符。例如,\u00A9匹配版权符号(©)。

re例子

用户名

/^[a-z0-9_-]{3,16}$/

密码

/^[a-z0-9_-]{6,18}$/

十六进制值

/^#?([a-f0-9]{6}|[a-f0-9]{3})$/

电子邮箱

/^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/

/^[a-z\d]+(\.[a-z\d]+)*@([\da-z](-[\da-z])?)+(\.{1,2}[a-z]+)+$/

URL

/^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/

IP 地址

/((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)/

/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/

HTML 标签

/^<([a-z]+)([^<]+)*(?:>(.*)<\/\1>|\s+\/>)$/

删除代码\\注释

(?

Unicode编码中的汉字范围

/^[\u2E80-\u9FFF]+$/

更多爬虫知识以及实例源码,可关注微信公众号:angry_it_man

你可能感兴趣的:(JavaScript,javascript,前端,html)