您的位置:首页 > 其它

Scrapy框架学习(四)----CrawlSpider、LinkExtractors、Rule及爬虫示例

2017-11-29 20:26 423 查看

Scrapy框架学习(四)—-CrawlSpider、LinkExtractors、Rule及爬虫示例

CrawlSpider
LinkExtractors
Rule
scrapy
框架中的类,其中
CrawlSpider
Spider
的派生类,具有更多的方法和功能,
LinkExtractor
类是用作提取链接的,
Rule
表示的是爬取的规则

CrawlSpider

CrawlSpider
Spider
的派生类,
Spider
类的设计原则是只爬取
start_urls
中的
url
,而
CrawlSpider
类定义了一些规则(
rules
)来提供跟进链接(
link
)的方便机制,从爬取的网页中获取
link
并继续爬取的工作更适合。

CrawlSpider除了Spider继承过来的属性外,还提供了一个新的属性:

rules


包含一个或多个
Rule
对象的集合。每个
Rule
对爬取网站的动作定义了特定规则。
Rule
对象会在下面介绍。

如果多个
Rule
匹配了相同的链接,则根据他们在本属性中被定义的顺序,第一个会被使用。

CrawlSpider也提供了一个可复写的方法:

parse_start_url(response)


当start_url的请求返回时,该方法被调用。该方法分析最初的返回值并必须返回一个
Item
对象或一个
Request
对象或者一个可迭代的包含二者的对象

当编写爬虫规则时,请避免使用
parse
作为回调函数。 由于
CrawlSpider
使用
parse
方法来实现其逻辑,如果 您覆盖了
parse
方法,
CrawlSpider
将会运行失败。

LinkExtractor

class scrapy.linkextractors.LinkExtractor


LinkExtractor
是从网页(
scrapy.http.Response
)中抽取会被
follow
的链接的对象。

LinkExtractor
CrawlSpider
类(在
Scrapy
可用)中使用, 通过一套规则,但你也可以用它在你的
Spider
中,即使你不是从
CrawlSpider
继承的子类, 因为它的目的很简单: 提取链接

每个LinkExtractor有唯一的公共方法是 extract_links(),它接收一个 Response 对象,并返回一个 scrapy.link.Link 对象。

Link Extractors要实例化一次,并且 extract_links 方法会根据不同的 response 调用多次提取链接。

class scrapy.linkextractors.LinkExtractor(
allow = (),
deny = (),
allow_domains = (),
deny_domains = (),
deny_extensions = None,
restrict_xpaths = (),
tags = ('a','area'),
attrs = ('href'),
canonicalize = True,
unique = True,
process_value = None
)


主要参数:

allow
:满足括号中”正则表达式”的值会被提取,如果为空,则全部匹配。

deny
:与这个正则表达式(或正则表达式列表)不匹配的url一定不提取

allow_domains
:会被提取的连接的domains

deny_domains
:一定不会被提取链接的domains。

restrict_xpaths
:使用xpath表达式,和allow共同作用过滤链接。

Rule

Rule
对象是一个爬取规则的类。

其类的定义如下:

class scrapy.contrib.spiders.Rule(link_extractor,callback=None,cb_kwargs=None,follow=None,process_links=None,process_request=None)


link_extractor
:是一个Link Extractor对象。其定义了如何从爬取到的页面提取链接。

callback
:是一个
callable
string
(该
Spider
中同名的函数将会被调用)。从
link_extractor
中每获取到链接时将会调用该函数。该回调函数接收一个
response
作为其第一个参数,并返回一个包含
Item
以及
Request
对象(或者这两者的子类)的列表。

cb_kwargs
:包含传递给回调函数的参数(keyword argument)的字典。

follow
:是一个
boolean
值,指定了根据该规则从
response
提取的链接是否需要跟进。如果
callback
None
follow
默认设置
True
,否则默认
False


process_links
:是一个
callable
string
(该
Spider
中同名的函数将会被调用)。从
link_extrator
中获取到链接列表时将会调用该函数。该方法主要是用来过滤

process_request
:是一个
callable
string
(该
spider
中同名的函数都将会被调用)。该规则提取到的每个
request
时都会调用该函数。该函数必须返回一个
request
或者
None
。用来过滤
request


CrawlSpider的爬虫示例

CrawlSpider以
58租房 上海
为例,爬取的数据有
标题,房子,地址,价格等
。具体看下面代码:

创建项目

在项目的父目录创建项目,执行如下命令:

scrapy startproject zufang58


定义需要爬取的字段

items.py
创建一个Item,默认会创建一个
ZufangItem
类,在
ZufangItem
类中定义字段

import scrapy

class Zufang58Item(scrapy.Item):
# 标题
title = scrapy.Field()
# 房间
room = scrapy.Field()
# 区域
zone = scrapy.Field()
# 地址
address = scrapy.Field()
# 价格
money = scrapy.Field()
# 发布信息的类型,品牌公寓,经纪人,个人
type = scrapy.Field()


编写Spider类

在spiders目录创建一个
zufang58_spider.py
文件,在文件中定义一个名为
ZuFang58Spider
继承
CrawlSpider
,代码如下。

from scrapy.spider import CrawlSpider, Rule
from scrapy.linkextractor import LinkExtractor
from zufang58.items import Zufang58Item

class ZuFang58Spider(CrawlSpider):
# spider的唯一名称
name = 'zufang58'
# 开始爬取的url
start_urls = ["http://sh.58.com/chuzu/"]
# 从页面需要提取的url 链接(link)
links = LinkExtractor(allow="sh.58.com/chuzu/pn\d+")
# 设置解析link的规则,callback是指解析link返回的响应数据的的方法
rules = [Rule(link_extractor=links, callback="parseContent", follow=True)]

def parseContent(self, response):
"""
解析响应的数据,获取需要的数据字段
:param response: 响应的数据
:return:
"""
# 根节点 //ul[@class="listUl"]/li[@logr]
# title: .//div[@class="des"]/h2/a/text()
# room: .//div[@class="des"]/p[@class="room"]/text()
# zone: .//div[@class="des"]/p[@class="add"]/a[1]/text()
# address: .//div[@class="des"]/p[@class="add"]/a[last()]/text()
# money: .//div[@class="money"]/b/text()
# type: # .//div[@class="des"]/p[last()]/@class     # 如果是add,room  .//div[@class="des"]/div[@class="jjr"]/@class

for element in response.xpath('//ul[@class="listUl"]/li[@logr]'):
title = element.xpath('.//div[@class="des"]/h2/a/text()')[0].extract().strip()
room = element.xpath('.//div[@class="des"]/p[@class="room"]')[0].extract()
zone = element.xpath('.//div[@class="des"]/p[@class="add"]/a[1]/text()')[0].extract()
address = element.xpath('.//div[@class="des"]/p[@class="add"]/a[last()]/text()')[0].extract()
money = element.xpath('.//div[@class="money"]/b/text()')[0].extract()
type = element.xpath('.//div[@class="des"]/p[last()]/@class')[0].extract()
if type == "add" or type == "room":
type = element.xpath('.//div[@class="des"]/div[@class="jjr"]/@class')[0].extract()

item = Zufang58Item()

item['title'] = title
item['room'] = room
item['zone'] = zone
item['address'] = address
item['money'] = money
item['type'] = type

yield item


编写pipeline(管道)

在pipeline.py文件中,创建
Zufang58Pipeline
类,实现
process_item()
方法。如:

class Zufang58Pipeline(object):
def __init__(self):
self.file = open('zufang58.json', mode='w', encoding='utf-8')

def process_item(self, item, spider):
jsondata = json.dumps(dict(item), ensure_ascii=False) + "\n"
self.file.write(jsondata)
return item

def close_spider(self, spider):
self.file.close()


配置pipeline管道和请求头字段

DEFAULT_REQUEST_HEADERS = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.89 Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en',
}

...

ITEM_PIPELINES = {
'zufang58.pipelines.Zufang58Pipeline': 300,
}


执行爬虫命令

scrapy crawl zufang58


我们可以在控制台中可以看到有很多的log输出。如果我们想把log保存到文件。可以在setting.py配置。

配置logging

Scrapy
提供5层
logging
级别:

CRITICAL
:严重错误(critical)

ERROR
:一般错误(regular errors)

WARNING
:警告信息(warning messages)

INFO
:一般信息(informational messages)

DEBUG
: 调试信息(debugging messages)

通过在
setting.py
中进行以下设置可以被用来配置
logging
:

LOG_ENABLED
默认:
True
,启用logging

LOG_ENCODING
默认:
utf-8
,logging使用的编码

LOG_FILE
默认:
None
,在当前目录里创建logging输出文件的文件名

LOG_LEVEL
默认:
DEBUG
,log的最低级别

LOG_STDOUT
默认:
False
,如果为 True,进程所有的标准输出(及错误)将会被重定向到log中。例如,执行 print “hello” ,其将会在Scrapy log中显示。

在settings.py配置logging

LOG_FILE = 'zufang58.log'
LOG_LEVEL = 'DEBUG'


就可以将log输出到
zufang58.log
文件中。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: