您的位置:首页 > Web前端 > CSS

【Scrapy】 selector 学习记录一(xpath、css)

2016-12-31 00:00 495 查看
在你抓取页面的时候,最普遍的任务就是从HTML源码中提取数据data了。python中提供了很多的第三方库提供对页面数据的提取和解析。

BeautifulSoup

lxml

Scrapy提供了Selector实现随Html文档内容的提取

XPath

CSS

Scrapy selector 继承 Selector类,

>>>from scrapy.selectro import Selector

>>>from scrapy.http import HtmlRespodse

>>> response = HtmlResponse(url='http://example.com', body=body)
>>>Selector(response=response).xpath('//span/text()').extract()

>>> response.selector.xpath('//span/text()').extract()
[u'good']

例子:http://doc.scrapy.org/en/latest/_static/selectors-sample1.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>
</div>
</body>
</html>

首先利用scrapy 的shell获取网址

scrapy shell http://doc.scrapy.org/en/latest/_static/selectors-sample1.html

利用Xpath或者CSS来提取html文档中的内容

>>> response.xpath('//title/text()')
[<Selector (text) xpath=//title/text()>]
>>> response.css('title::text')
[<Selector (text) xpath=//title/text()>]

可以看到,xpath和css返回的是一个Selector的list实例,而不是一个字符串。

如果你要提取文本数据,需要在selector后加 .extract() 来提取数据。

如果你只想提取第一个匹配的元素,

.extract_first()

获取url和图片src链接

>>> response.xpath('//base/@href').extract()
[u'http://example.com/']

>>> response.css('base::attr(href)').extract()
[u'http://example.com/']

>>> response.xpath('//a[contains(@href, "image")]/@href').extract()
[u'image1.html',
u'image2.html',

>>> response.css('a[href*=image]::attr(href)').extract()
[u'image1.html',
u'image2.html']

>>> response.xpath('//a[contains(@href, "image")]/img/@src').extract()
[u'image1_thumb.jpg',
u'image2_thumb.jpg']

>>> response.css('a[href*=image] img::attr(src)').extract()
[u'image1_thumb.jpg',
u'image2_thumb.jpg']

( .xpath() 和 .css() ) 返回的是selector的一个list,所以可以嵌套使用他们,例如:

>>> links = response.xpath('//a[contains(@href, "image")]')
>>> links.extract()
[u'<a href="image1.html">Name: My image 1 <br><img src="image1_thumb.jpg"></a>',
u'<a href="image2.html">Name: My image 2 <br><img src="image2_thumb.jpg"></a>'

>>> for index, link in enumerate(links):
...     args = (index, link.xpath('@href').extract(), link.xpath('img/@src').extract())
...     print 'Link number %d points to url %s and image %s' % args

Link number 0 points to url [u'image1.html'] and image [u'image1_thumb.jpg']
Link number 1 points to url [u'image2.html'] and image [u'image2_thumb.jpg']

selector和正则表达式结合使用

在selector中也有正则表达式方法(.re()),但是 **.re() ** 不像 .xpath().css() 返回一个selector的list, .re() 返回的是一个Unicode的字符串。所以 .re() 不可嵌套使用。

>>> response.xpath('//a[contains(@href, "image")]/text()').re(r'Name:\s*(.*)')
[u'My image 1',
u'My image 2']

>>> response.xpath('//a[contains(@href, "image")]/text()').re_first(r'Name:\s*(.*)')
u'My image 1'

XPath 使用注意事项(相对路径)

注意: 如果你正在嵌套 selectors 和 使用 以 " / " 开始的 xpath 时,xpath 会相对整个document 而不是相对你的selector。

例如:

假设你想提取 在 <div> 标签中所有的 <p> 元素,首先,你先得到 <div> 元素

>>> divs = response.xpath('//div')

如果你使用下面这种方法,相对的是文档中所有的 <p> 元素,而不是 <div> 中的 <p> 元素,

>>> for p in divs.xpath('//p'):  # this is wrong - gets all <p> from the whole document
...     print p.extract()

正确的使用方法是这样:

>>> for p in divs.xpath('.//p'):  # extracts all <p> inside
...     print p.extract()

or

>>> for p in divs.xpath('p'):
...     print p.extract()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  scrapy selector