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

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

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

CrawlSpider

CrawlSpiderSpider的派生类,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的链接的对象。

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

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

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

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

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

CrawlSpider的爬虫示例

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

  1. 创建项目

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

scrapy startproject zufang58
  1. 定义需要爬取的字段

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()
  1. 编写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
  1. 编写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()
  1. 配置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,
}
  1. 执行爬虫命令
scrapy crawl zufang58

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

  1. 配置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文件中。

  • 3
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值