2 min read

scrapy 实战(三)页面抓取完成如何同步到服务端

scrapy 实战(三)页面抓取完成如何同步到服务端

上次讲到了,如何提取页面中的图片资源。

接下来,介绍页面抓取完成如何同步到服务端 或者写入数据库。

首先, 在 settings.py 添加一行设置

# 设置 抓取的页面 post 到服务器的 地址  
SERVER_URL = 'http://localhost:8000/api/entities/'  

接着,在写 scrapy 的 提交信息的 pipelines.py 之前我们先要写一个重复检查的
pipeline避免重复提交信息到数据库,导致脏数据的产生。

    # -*- 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-pipeli...](http://doc.scrapy.org/en/latest/topics/item-pipeline.html)  
      
    from hashlib import md5  
    import requests  
      
    from scrapy.exceptions import DropItem  
    from andromeda import settings  
      
      
    class DuplicatesPipeline(object):  
      
        def process_item(self, item, spider):
            # 这里主要是拿商品原始链接计算 md5   
            identified_code     = md5(item['origin_link']).hexdigest()  
    
            #生成 检查商品的 URL  
            check_url           = "{url}/{identified_code}".format(  
                url = settings.SERVER_URL,  
                identified_code = identified_code,  
            )  
            res = requests.head(check_url)  
            
            # 提交信息后判断信息是否存在
            if res.status_code  == 200:
                #如果存在 DROP  
                raise DropItem("Duplicate entity found: %s", item)  
            else:  
                return item  

以上代码主要叙述了:

  1. 计算爬去商品唯一 值, 我这里用了 md5 当然,你也可以用其他方式。
  2. 去服务器检查信息是否存在。这里用了 HEAD 方法去请求服务器,用 GET 的话感觉比较消耗网络资源 (注,服务器需要允许 HEAD 方法不然永远返回 405)
  3. 判断服务器返回的响应码,200 的话就直接 DROP

继续,检查完信息是否重复后,我们就可以提交信息到服务端。

class PostEntityPipeline(object):  
  
    def process_item(self, item, spider):  
        res = requests.post(settings.SERVER_URL, json=dict(item))  
        if res.status_code == 200:  
            return item  
        else:  
            logging.error(res.text)  

以上代码很简单, 将 item 转换为字典。然后,通过 requests 提交到服务端。

最后,我们需要在 settings.py 中加入下面的配置

    
    # Configure item pipelines  
    # See [https://scrapy.readthedocs.org/en/latest/topics/ite...](https://scrapy.readthedocs.org/en/latest/topics/item-pipeline.html)  
    ITEM_PIPELINES = {  
        'andromeda.pipelines.DuplicatesPipeline': 100,    # 检查重复  
        'scrapy.pipelines.images.ImagesPipeline': 300,    # 下载图片
        'andromeda.pipelines.PostEntityPipeline': 500,    # 提交信息到服务端  
    }
    # 后面的数字代表程序执行的优先级

项目源代码