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,本文章到此结束,下一篇讲讲如何构造代理中间件

  • 相关阅读:
    codevs 1569 最佳绿草

    luogu P3378 【模板】堆
    cogs 762. [USACO Open09] 奶牛队列
    各种 Python 实现的简单介绍与比较
    与 的区别
    Python3 print()函数sep,end,file参数用法练习
    python基础
    servlet篇 之 跳转问题
    servlet篇 之 servlet的访问
  • 原文地址:https://www.cnblogs.com/zx576/p/7295440.html
Copyright © 2011-2022 走看看