腊月的季节

scrapy爬虫技术二

scrapy.Item理解

1、Selectors选择器
为什么要先说这个呢?因为没有这个,就算你定义了item也没卵用。
从网页提取数据有很多方法。scrapy使用了一种基于XPth和CSS表达式机制:Scrapy Selectors
这里给一些XPath表达式的例子及对应的含义:

  • /html/head/title:选择HTML文档中标签内的元素
  • /html/head/title/text():选择上面提到的元素的文字
  • //td:选择所有的元素
  • //div[@class=”mine”]:选择所有具有class=”mine”属性的div元素
  • //div/a/@href:提取所有div标签内的a标签里的属性为href的值。
    Selector有四个基本的方法:
  • xpath():传入xpath表达式,返回该表达式所对应的所有节点的selector list列表。
  • css():传入CSS表达式,返回该表达式所对应的所有节点的selector list列表
  • extract():序列化该节点为Unicode字符串并返回list。
  • re():根据传入的正则表达式对数据进行提取,返回Unicode字符串list列表。
    这里估计你们有点不理解这四者的不同,他们不同在哪里呢?举个例子吧!xpath(),css()就是个中间过程,真正的终结者是extract(),re().前两者返回的都还是selector,selector是什么呢?你们可以在shell中尝试一下就知道了。
    一般都有内置的IPython终端。直接说吧!
    首先在项目的根目录,执行下面命令启动shell:
    1
    scrapy shell "http://www.dmoz.org/Computers/Programming/Languages/Python/Books/"

载入完成后你会得到一个response的本地变量。输入response.body将输出response的包体,输出response.headers可以看到response的包头。
这些都是浮云,重要的是你要用response.selector,你可以直接使用快捷方法:response.xpath()和response.css()。
试一下吧!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
In [1]: response.xpath('//title')
Out[1]: [<Selector xpath='//title' data=u'<title>Open Directory - Computers: Progr'>]

In [2]: response.xpath('//title').extract()
Out[2]: [u'<title>Open Directory - Computers: Programming: Languages: Python: Books</title>']

In [3]: response.xpath('//title/text()')
Out[3]: [<Selector xpath='//title/text()' data=u'Open Directory - Computers: Programming:'>]

In [4]: response.xpath('//title/text()').extract()
Out[4]: [u'Open Directory - Computers: Programming: Languages: Python: Books']

In [5]: response.xpath('//title/text()').re('(\w+):')
Out[5]: [u'Computers', u'Programming', u'Languages', u'Python']

大家都可以看到,结尾没有extract()和re()的都返回的是[]的一个列表。而结尾用了的都被终结了。所以就这个意思吧!自己领会一下,呵呵。
2、提取数据
我们利用选择器肯定是要提取有用的数据,那么我们一开始怎么知道是有用的数据呢?这就要说一下源码了,你要通过工具找出你要爬的网站有什么信息值得你去爬取或者值得未来去分析。
比如说官网的这个,在查看了网页的源码后,您会发现网站的信息是被包含在第二个

    元素中。
    首先我们要获取这个标签里面的标签还是内容要分清,还是要逐级去筛选。
    1
    >>> response.xpath('//ul/li')

再在li标签获取文字

1
>>> response.xpath('//ul/li/text()').extract()

在li标签下的a标签获取@href的属性值。

1
>>> response.xpath('//ul/li/a/@href').extract()

当然在实际中我们是这样做的。根据.xpath()返回的selector组成的list,用for in循环来一个提取。

1
2
3
4
5
for sel in response.xpath('//ul/li'):
title = sel.xpath('a/text()').extract()
link = sel.xpath('a/@href').extract()
desc = sel.xpath('text()').extract()
print title, link, desc

那么你可以把我们第一次做的那个爬虫,加入这个代码,输出得到的数据。
3、使用item
现在我们正式使用item,item对像是自定义的python字典,你可以使用标准的字典语法来获取到其每个字段的值。(字段就是我们之前用Field赋值的属性):

1
2
3
4
>>> item = DmozItem()
>>> item['title'] = 'Example title'
>>> item['title']
'Example title'

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import scrapy

from tutorial.items import DmozItem

class DmozSpider(scrapy.Spider):
name = "dmoz"
allowed_domains = ["dmoz.org"]
start_urls = [
"http://www.dmoz.org/Computers/Programming/Languages/Python/Books/",
"http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/"
]

def parse(self, response):
for sel in response.xpath('//ul/li'):
item = DmozItem()
item['title'] = sel.xpath('a/text()').extract()
item['link'] = sel.xpath('a/@href').extract()
item['desc'] = sel.xpath('text()').extract()
yield item

怎么把这些数据保存到文件中呢?
使用命令

1
scrapy crawl dmoz -o items.json

该命令将采用JSON格式对爬取的数据进行序列化,生成items.json文件到你的项目根目录。
如果需要对爬取到的item做更多更为复杂的操作,您可以编写 Item Pipeline 。 类似于我们在创建项目时对Item做的,用于您编写自己的 tutorial/pipelines.py 也被创建。 不过如果您仅仅想要保存item,您不需要实现任何的pipeline。

热评文章