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

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


首先, 在 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...

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 http://scrapy.readthedocs.org/en/latest/topics/ite...
ITEM_PIPELINES = {
'andromeda.pipelines.DuplicatesPipeline': 100, # 检查重复
'scrapy.pipelines.images.ImagesPipeline': 300, # 下载图片 'andromeda.pipelines.PostEntityPipeline': 500, # 提交信息到服务端
} # 后面的数字代表程序执行的优先级


项目源代码