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


    转载自:http://blog.csdn.net/u012150179/article/details/34913315

    .目的。

    在教程(二)(http://blog.csdn.net/u012150179/article/details/32911511)中使用基于Spider实现了自己的w3cschool_spider,并在items.py中定义了数据结构

    pipelines.py中实现获得数据的过滤以及保存。

    但是以上述方法只能爬取start_url列表中的网页,而网络爬虫如google等搜索引擎爬虫实现的就是对整个互联网的爬取,所以在本教程中研究使用scrapy自动实现多网页爬取功能。

    在教程(五)(http://blog.csdn.net/u012150179/article/details/34486677)中已经编写继承自spider的类实现爬虫,实现了自动多网页爬取,这里引出CrawlSpider类,使用更简单方式实现自动爬取。

    .热身。

    1.CrawlSpider

    1)概念与作用:

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

    2)使用:

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

    [python] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. class scrapy.contrib.spiders.Rule (  
    2. link_extractor, callback=None,cb_kwargs=None,follow=None,process_links=None,process_request=None )  

                         其中:

    link_extractorLinkExtractor,用于定义需要提取的链接。

    callback参数:当link_extractor获取到链接时参数所指定的值作为回调函数。



                          callback参数使用注意:

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

     

    follow:指定了根据该规则从response提取的链接是否需要跟进。当callbackNone,默认值为true

    process_links:主要用来过滤由link_extractor获取到的链接。

    process_request:主要用来过滤在rule中提取到的request



    2.LinkExtractor

    (1)概念:

    顾名思义,链接提取器。

    (2) 作用:

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

    (3) 使用:

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

    [python] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. classscrapy.contrib.linkextractors.sgml.SgmlLinkExtractor(  
    2. 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共同作用过滤链接。



    .RUN!

    1. shell中验证

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

      [python] view plain copy
       
       在CODE上查看代码片派生到我的代码片
      1. scrapy shell http://blog.csdn.net/u012150179/article/details/11749017  

      继续import相关模块:
      [python] view plain copy
       
       在CODE上查看代码片派生到我的代码片
      1. fromscrapy.contrib.linkextractors.sgml import SgmlLinkExtractor  

      现在使用SgmlLinkExtractor查看在当前网页中获得的链接:
      [python] view plain copy
       
       在CODE上查看代码片派生到我的代码片
      1. item=SgmlLinkExtractor(allow=('/u012150179/article/details')).extract_links(response)  

      其中item为包含Link()对象的列表,现在显示其中的text元素(就是获取到的文章链接对应的文章标题):
      [python] view plain copy
       
       在CODE上查看代码片派生到我的代码片
      1. for i in item:  
      2.     print i.text  

      部分结果截图:

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

      [python] view plain copy
       
       在CODE上查看代码片派生到我的代码片
      1. item= SgmlLinkExtractor(allow=('/u012150179/article/details'),restrict_xpaths=('//li[@class="next_article"]')).extract_links(response)  

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

      注意:在shell中并不对提取到的link进行跟进。

      在这里不得不提的就是scrapy shell是对调试、验证很有用的交互工具。应该掌握。

      shell中进行了验证后进入写代码阶段。

    编写代码

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


    2)爬虫编写。

    上码:

    [python] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. # -*- coding:utf-8 -*-  
    2.   
    3. from scrapy.contrib.spiders import CrawlSpider, Rule  
    4. from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor  
    5. from scrapy.selector import Selector  
    6. from CSDNBlogCrawlSpider.items import CsdnblogcrawlspiderItem  
    7.   
    8.   
    9. class CSDNBlogCrawlSpider(CrawlSpider):  
    10.   
    11.     """继承自CrawlSpider,实现自动爬取的爬虫。"""  
    12.   
    13.     name = "CSDNBlogCrawlSpider"  
    14.     #设置下载延时  
    15.     download_delay = 2  
    16.     allowed_domains = ['blog.csdn.net']  
    17.     #第一篇文章地址  
    18.     start_urls = ['http://blog.csdn.net/u012150179/article/details/11749017']  
    19.   
    20.     #rules编写法一,官方文档方式  
    21.     #rules = [  
    22.     #    #提取“下一篇”的链接并**跟进**,若不使用restrict_xpaths参数限制,会将页面中所有  
    23.     #    #符合allow链接全部抓取  
    24.     #    Rule(SgmlLinkExtractor(allow=('/u012150179/article/details'),  
    25.     #                          restrict_xpaths=('//li[@class="next_article"]')),  
    26.     #         follow=True)  
    27.     #  
    28.     #    #提取“下一篇”链接并执行**处理**  
    29.     #    #Rule(SgmlLinkExtractor(allow=('/u012150179/article/details')),  
    30.     #    #     callback='parse_item',  
    31.     #    #     follow=False),  
    32.     #]  
    33.   
    34.     #rules编写法二,更推荐的方式(自己测验,使用法一时经常出现爬到中间就finish情况,并且无错误码)  
    35.     rules = [  
    36.         Rule(SgmlLinkExtractor(allow=('/u012150179/article/details'),  
    37.                               restrict_xpaths=('//li[@class="next_article"]')),  
    38.              callback='parse_item',  
    39.              follow=True)  
    40.     ]  
    41.   
    42.     def parse_item(self, response):  
    43.   
    44.         #print "parse_item>>>>>>"  
    45.         item = CsdnblogcrawlspiderItem()  
    46.         sel = Selector(response)  
    47.         blog_url = str(response.url)  
    48.         blog_name = sel.xpath('//div[@id="article_details"]/div/h1/span/a/text()').extract()  
    49.   
    50.         item['blog_name'] = [n.encode('utf-8') for n in blog_name]  
    51.         item['blog_url'] = blog_url.encode('utf-8')  
    52.   
    53.         yield item  

    运行:

    [python] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. scrapy crawl CSDNBlogCrawlSpider  


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

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

    首先,基类CrawlSpider提供了更完善的自动多网页爬取机制,只需要我们配置的就是rules,通过Rule对象实现链接的提取与跟进,恩,对,没了。。。就这样。详细的注释也都在程序中。

    进行到这里,就将本篇文章主题讲述完毕,核心是CrawlSpider,主要方法是rules。

  • 相关阅读:
    Validation failed for one or more entities. See 'EntityValidationErrors' property for more details
    Visual Studio断点调试, 无法监视变量, 提示无法计算表达式
    ASP.NET MVC中MaxLength特性设置无效
    项目从.NET 4.5迁移到.NET 4.0遇到的问题
    发布网站时应该把debug设置false
    什么时候用var关键字
    扩展方法略好于帮助方法
    在基类构造器中调用虚方法需谨慎
    ASP.NET MVC中商品模块小样
    ASP.NET MVC中实现属性和属性值的组合,即笛卡尔乘积02, 在界面实现
  • 原文地址:https://www.cnblogs.com/lmsj/p/6504742.html
Copyright © 2020-2023  润新知