• scrapy genspider -t crawl --小例子


    1.目标

    利用链接提取器爬取目标网站简单信息

    2.代码

    read.py

    # -*- coding: utf-8 -*-
    from scrapy.linkextractors import LinkExtractor
    from scrapy.spiders import CrawlSpider, Rule
    
    from ..items import ReadbookItem
    
    '''
    scrapy genspider -t crawl read www.XXXXX.com
    但是这样子我ignore第一页的content,
    原因是起始页不正确:false(1107_1.html)true(1107_1.html)
    '''
    class ReadSpider(CrawlSpider):
        name = 'read'
        allowed_domains = ['www.dushu.com']
        start_urls = ['https://www.dushu.com/book/1107_1.html']
    
        rules = (
            Rule(LinkExtractor(allow=r'/book/1107_d+.html'),
                 callback='parse_item',
                 follow=True), 
        )
    
        def parse_item(self, response):
            # 这个结构可以用item+yield代替
            # i = {}
            # #i['domain_id'] = response.xpath('//input[@id="sid"]/@value').extract()
            # #i['name'] = response.xpath('//div[@id="name"]').extract()
            # #i['description'] = response.xpath('//div[@id="description"]').extract()
            # return i
    
            res = response
    
            img_list = res.xpath('//div[@class="book-info"]//img')
            for img in img_list:
                # 这里图片用了js懒加载,故而解析data-original
                # meanwhile 使用了防盗链,403,没有权限拒加载图片,
                # 这个网站直接修改user-agent,或者修改默认请求头,即可解决,
                # 他没有校验referer,判断你是否从上一页跳转过来的
                pictrue = img.xpath('./@data-original').extract_first()
                title = img.xpath('./@alt').extract_first()
                #
                # print(pictrue)
                # print(title)
    
                item = ReadbookItem()
    
                item['title'] = title
                item['pictrue'] = pictrue
    
                yield item
    

     

    pipeline.py
    # -*- coding: utf-8 -*-
    
    # Define your item pipelines here
    #
    # Don't forget to add your pipeline to the ITEM_PIPELINES setting
    # See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html
    
    
    class ReadbookPipeline(object):
    
    
        def open_spider(self,spider):
            self.fp = open('info.json','w+',encoding='utf-8')
    
    
        def process_item(self, item, spider):
            self.fp.write(str(item) )
    
            return item
    
        def close_spider(self , spider):
            self.fp.close()
    

    items.py

    # -*- coding: utf-8 -*-
    
    # Define here the models for your scraped items
    #
    # See documentation in:
    # http://doc.scrapy.org/en/latest/topics/items.html
    
    import scrapy
    
    
    class ReadbookItem(scrapy.Item):
        # define the fields for your item here like:
        # name = scrapy.Field()
        title = scrapy.Field()
        pictrue = scrapy.Field()
    

      

    3.扩展

    follow 是一个布尔(boolean)值,指定了根据该规则从response提取的链接是否需要跟进。 如果callback 为None,follow 默认设置为 True ,添加回调函数callback后为 False,不跟踪

    一句话解释:follow可以理解为回调自己的回调函数

    举个例子,如百度百科,从任意一个词条入手,抓取词条中的超链接来跳转,rule会对超链接发起requests请求,如follow为True,scrapy会在返回的response中验证是否还有符合规则的条目,继续跳转发起请求抓取,周而复始,如下图

       

                                                             

    1. 遍历所有的Rule对象, 并使用其link_extractor属性提取链接
    2. 对于提取到的链接, 我们把它加入到一个集合中
    3. 使用链接发送一个请求, 并且callback的最终结果是self._parse_response
    4. 同时在你可以在规则提取里添加多个提取规则作用于下一级URL提取
    5. rules = (
              Rule(LinkExtractor(allow=r'/book/1107_d+.html'),
                   callback='parse_item',
                   follow=True), 
              Rule(LinkExtractor(allow=r'XXXXXX'),
                   callback='parse_item',
                   follow=True),  
              Rule(LinkExtractor(allow=r'XXXXX'),
                   callback='parse_item',
                   follow=True), 
          )
      

        然后在回调函数里还可以配合scrapy.Request()使用来提取详细信息

           上述操作表明, 当我们follow一个链接时, 我们其实是用rules把这个链接返回的response再提取一遍.

     

    所以要注意read.py里的follow的布尔值。

    参考:https://blog.csdn.net/qq_18525247/article/details/82743614https://zhuanlan.zhihu.com/p/25650763

  • 相关阅读:
    [BZOJ2296] [POJ Challenge] 随机种子
    [BZOJ1026] [SCOI2009] windy数 (数位dp)
    [BZOJ1306] [CQOI2009] match循环赛 (搜索)
    [BZOJ2654] tree (kruskal & 二分答案)
    [BZOJ3506] [Cqoi2014] 排序机械臂 (splay)
    [BZOJ1552] [Cerc2007] robotic sort (splay)
    [BZOJ3110] [Zjoi2013] K大数查询 (树套树)
    BZOJ3611: [Heoi2014]大工程
    BZOJ2286: [Sdoi2011]消耗战
    BZOJ3876: [Ahoi2014]支线剧情
  • 原文地址:https://www.cnblogs.com/cheflone/p/13648395.html
Copyright © 2020-2023  润新知