zoukankan      html  css  js  c++  java
  • scrapy 集成到 django(二)

    在上一篇文章中,介绍了如何搭建 scrapy-django 项目,结尾的时候说道,如果在 django-orm 中存在外键,该如何处理呢

    项目地址: recruitment

    比如在 django/models.py 中

    
    class Recruit(models.Model):
    
        belong = models.ForeignKey('Firm', verbose_name='所属公司')
        resource = models.CharField('信息来源', max_length=255)
        url = models.URLField('信息链接', default='')
        # ...
    
    class Firm(models.Model):
        # 公司相关信息
        firm_introduction = models.TextField('公司简介')
        # ...
    
    
    

    这里定义了一个 belong 外键,因为一家公司可能发布多个职位。处理外键的难度在于,在 pipelines 中一次只能处理一个 item ,按照之前的写法,我们处理的 item 要么是 职位信息,要么是公司信息,这样要将两部分对上号,是有些困难的。

    以下给出解决方案
    在 crawlend/spiders.py 中处理完数据后

    
    # ...
    def parse(self, response):
        item = {}
        offer = CrawlendItem()
        firm = FirmItem()
    
        offer['resource'] = '智联'
        firm['firm_introduction'] = 'XXXX'
        # ...
    
        item['offer'] = offer
        item['firm'] = firm
    
        yield item
    
    
    

    看到了么,处理外键的关键在于,一次性将两个 Item 打包到一个 dict 中。这样我们在 pipelines 中解析 dict ,同时取到两个 dict ,这样就可以设置外键了。

    pipelines.py

    
    from .items import CrawlendItem, FirmItem, ProxyItem
    from backend.models import Proxy, Firm, Recruit
    
    class CrawlendPipeline(object):
    
        def process_item(self, item, spider):
            '''
            :param item: dict
            :param spider:
            :return:
            '''
            # 检查数据库内是否存在该公司
            def _check_firm(firm_name):
                try:
                    ins = Firm.objects.get(firm_name=firm_name)
                    return ins
                except:
                    return None
            #
            if isinstance(item, dict):
    
                # 提取 两个 ITEM
                offer = item['offer']
                firm = item['firm']
                f_name = firm['firm_name']
                offers_ = 0
                # 判断该公司是否存在
                if _check_firm(f_name):
                    firm = _check_firm(f_name)
                    offers_ = len(firm.recruit_set.filter(name=offer['name']))
    
                # 保存数据
                firm.save()
    
                # 判断职位是否有重复
                if offers_ == 0:
                    offer['belong'] = Firm.objects.get(firm_name=f_name) 
                    offer.save()
    
                return item
    
    

    思路: 在查看使用基本的 scrapy_djangoitem 库中,发现在 piplines 部分调用了 item.save() 方法,也就是说,在 piplines 中已经将数据保存下来了,所以 return item 这部分已经无关紧要了。

    同时查看 scrapy piplines 的官方文档发现, item 可以为 items 定义的类对象也可以为 字典,所以直接想到凑一个 dict ,然后到 piplines 中再解析。

    OK,本文章到此结束,下一篇讲讲如何构造代理中间件

  • 相关阅读:
    第十二章学习笔记
    UVa OJ 107 The Cat in the Hat (戴帽子的猫)
    UVa OJ 123 Searching Quickly (快速查找)
    UVa OJ 119 Greedy Gift Givers (贪婪的送礼者)
    UVa OJ 113 Power of Cryptography (密文的乘方)
    UVa OJ 112 Tree Summing (树的求和)
    UVa OJ 641 Do the Untwist (解密工作)
    UVa OJ 105 The Skyline Problem (地平线问题)
    UVa OJ 100 The 3n + 1 problem (3n + 1问题)
    UVa OJ 121 Pipe Fitters (装管子)
  • 原文地址:https://www.cnblogs.com/zx576/p/7295440.html
Copyright © 2011-2022 走看看