Scrapy研究探索(六)——自动爬取网页之II(CrawlSpider)

原创,转载注明:
http://blog.csdn.net/u012150179/article/details/34913315
基于上面的博客修改而得

一 目的

教程(二)中使用基于Spider实现了自己的w3cschool_spider,并在items.py中定义了数据结构,
在pipelines.py中实现获得数据的过滤以及保存。
但是以上述方法只能爬取start_url列表中的网页,而网络爬虫如google等搜索引擎爬虫实现的就是对整个互联网的爬取,所以在本教程中研究使用scrapy自动实现多网页爬取功能。
教程(五)中已经编写继承自spider的类实现爬虫,实现了自动多网页爬取,这里引出CrawlSpider类,使用更简单方式实现自动爬取。

二 热身

1.CrawlSpider

(1)概念与作用:

它是Spider的派生类,首先在说下Spider,它是所有爬虫的基类,对于它的设计原则是只爬取start_url列表中的网页,而从爬取的网页中获取link并继续爬取的工作CrawlSpider类更适合。

(2)使用:

它与Spider类的最大不同是多了一个rules参数,其作用是定义提取动作。在rules中包含一个或多个Rule对象,Rule类与CrawlSpider类都位于scrapy.contrib.spiders模块中。

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

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

callback参数:当link_extractor获取到链接时会调用该参数所指定的回调函数. 该回调函数接受一个response作为其第一个参数, 并返回一个包含 Item 以及(或) Request 对象(或者这两者的子类)的列表(list)。
callback参数使用注意:当编写爬虫规则时,请避免使用parse作为回调函数。于CrawlSpider使用parse方法来实现其逻辑,如果您覆盖了parse方法,crawlspider将会运行失败。

cb_kwargs:包含传递给回调函数的参数(keyword argument)的字典。
follow:指定了根据该规则从response提取的链接是否需要跟进到下一个规则。当callback为None,默认值为True。
process_links:主要用来过滤由link_extractor获取到的链接。
process_request:主要用来过滤在rule中提取到的request。

2.LinkExtractor

(1)概念:

顾名思义,链接提取器。

(2) 作用:

response对象中获取链接,并且该链接会被接下来爬取。

(3) 使用:

通过SmglLinkExtractor提取希望获取的链接。

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

主要参数:
allow:满足这个正则表达式(或正则表达式列表)的URL会被提取,如果为空,则全部匹配。
deny:满足这个正则表达式(或正则表达式列表)的URL一定不提取。如果为空,不过滤任何URL。
allow_domains:会被提取的链接的domains(或domains列表)。
deny_domains:一定不会被提取链接的domains(或domains列表)。
deny_extensions: 需要忽略的url扩展名列表,如”bmp”,”gif”,”jpg”,”mp3”,”wav”,”mp4”,”wmv”。默认使用在模块scrapy.linkextractors中定义的IGNORED_EXTENSIONS。
restrict_xpaths:指定提取URL的xpath(或xpath列表)。若不为空,则只使用该参数去提取URL。和allow共同作用过滤链接。
restrict_css:指定提取URL的css列表。若不为空,则只使用该参数去提取URL
tags:指定提取URL的页面tag列表。默认为(‘a’,’area’)
attrs:从tags参数中指定的tag上提取attrs。默认为(‘href’)
canonicalize:是否标准化每个URL,使用scrapy.utils.url.canonicalize_url。默认为True。
unique:是否过滤提取过的URL
process_value:处理tags和attrs提取到的URL

三 RUN

1.shell中验证

开始编写代码之前,使用scrapyshell查看使用SmglLinkExtractor在网页中获取到的链接:

scrapy shell "http://blog.csdn.net/u012150179/article/details/11749017"

继续import相关模块:

from scrapy.linkextractors import LinkExtractor

现在使用SgmlLinkExtractor查看在当前网页中获得的链接:

item = LinkExtractor(allow=('/u012150179/article/details')).extract_links(response)

其中item为包含Link()对象的列表,现在显示其中的text元素(就是获取到的文章链接对应的文章标题):

for i in item:
print i.text

部分结果如下:
*写在开始
Python相关介绍(很好)
scrapy研究探索(二)——爬w3school.com.cn
Scrapy研究探索(六)——自动爬取网页之II(CrawlSpider)
Git使用之——冲突解决一(git merge conflict)
Scrapy研究探索(五)——自动多网页爬取(抓取某人博客所有文章)
Scrapy研究探索(七)——如何防止被ban之策略大集合
Scrapy研究探索(一)——基础入门
scrapy-redis实现爬虫分布式爬取分析与实现
Scrapy研究探索(四)——中文输出与中文保存
Scrapy研究探索(三)——Scrapy核心架构与代码运行分析
scrapy-redis源码分析
遇到Qt调用dll问题(整理版)
qwt安装使用精华版
已将GitHub scrapy-redis库升级,使其兼容最新版本Scrapy
GitHub中README.md添加图片方式
moos-ivp 下载编译运行
升级scrapy-redis代码,使与更新版本scrapy兼容
关于“淘宝爆款”的数据抓取与数据分析*

对照网页可以得到此时获取的是当前网页中所有满足allow条件的链接,不仅包含“下一篇”的链接,还有网页侧边栏“阅读排行“、”评论排行“中的文章链接。为了只获得”下一篇“文章链接,这就要进行所有链接的筛选,引入参数restrict_xpaths,继续:

item = SgmlLinkExtractor(allow=('/u012150179/article/details'),restrict_xpaths=('//li[@class="next_article"]')).extract_links(response)

这是在如上查看结果,便提取出了“下一篇”文章链接。

2.编写代码

(1)items.py和pipelines.py以及settings.py与之前教程类似,不详细描述。

(2)爬虫编写。

上码:

#-*- coding:utf-8-*-
from scrapy.contrib.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
from scrapy.selector import Selector
from CSDNBlogCrawlSpider.items import CsdnblogcrawlspiderItem
class CSDNBlogCrawlSpider(CrawlSpider):
"""继承自CrawlSpider,实现自动爬取的爬虫。"""
    name = "CSDNBlogCrawlSpider"
    #设置下载延时
    download_delay = 2
    allowed_domains = ['blog.csdn.net']
    #第一篇文章地址
    start_urls = ['http://blog.csdn.net/u012150179/article/details/11749017']
    #rules编写法一,官方文档方式
    rules = [
        #提取“下一篇”的链接并**跟进**,若不使用restrict_xpaths参数限制,会将页面中所有
        #符合allow链接全部抓取
        Rule(LinkExtractor(allow=('/u012150179/article/details'),
                restrict_xpaths=('//li[@class="next_article"]')),
                follow=True),
        #提取“下一篇”链接并执行**处理**
        Rule(LinkExtractor(allow=('/u012150179/article/details')),
                callback='parse_item',
                follow=False),
    ]
    #rules编写法二,更推荐的方式(自己测验,使用法一时经常出现爬到中间就finish情况,并且无错误码)
    rules =[
        Rule(LinkExtractor(allow=('/u012150179/article/details'),
                restrict_xpaths=('//li[@class="next_article"]')),
                callback='parse_item',
                follow=True)
    ]
def parse_item(self, response):
    #print "parse_item>>>>>>"
    item = CsdnblogcrawlspiderItem()
    sel = Selector(response)
    blog_url = str(response.url)
    blog_name = sel.xpath('//div[@id="article_details"]/div/h1/span/a/text()').extract()
    item['blog_name'] = [n.encode('utf-8') for n in blog_name]
    item['blog_url'] = blog_url.encode('utf-8')
    yield item

运行:

scrapy crawl CSDNBlogCrawlSpider

得到的效果如教程(五)一致。

其中指出和教程(五)所编写爬虫方法的差异:

首先,基类CrawlSpider提供了更完善的自动多网页爬取机制,只需要我们配置的就是rules,通过Rule对象实现链接的提取与跟进,恩,对,没了。。。就这样。详细的注释也都在程序中。
进行到这里,就将本篇文章主题讲述完毕,核心是CrawlSpider,主要方法是rules。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值