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
以上代码主要叙述了:
- 计算爬去商品唯一 值, 我这里用了 md5 当然,你也可以用其他方式。
- 去服务器检查信息是否存在。这里用了 HEAD 方法去请求服务器,用 GET 的话感觉比较消耗网络资源 (注,服务器需要允许 HEAD 方法不然永远返回 405)
- 判断服务器返回的响应码,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, # 提交信息到服务端
}
# 后面的数字代表程序执行的优先级