• 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。

  • 相关阅读:
    [LintCode] 最长上升子序列
    [LintCode] 最长公共前缀
    [LintCode] A + B 问题
    [hihoCoder] 拓扑排序·一
    [LintCode] 拓扑排序
    [LintCode] 第k大元素
    [LintCode] 最小路径和
    [LeetCode] Factorial Trailing Zeros
    [LintCode] 尾部的零
    [LeetCode] Length of Last Word
  • 原文地址:https://www.cnblogs.com/lmsj/p/6504742.html
Copyright © 2020-2023  润新知