【原创】Scrapyd 的 .net 客户端
最近项目需要部署Scrapy爬虫,采用最简单的Scrapyd服务进行部署,基于.net core 进行了客户端的封装。
1)Scrapyd API文档:http://scrapyd.readthedocs.io/en/latest/api.html
2)使用HttpClient进行交互
比较麻烦的是部署爬虫所需要的使用 HttpClient 上传文件的代码,使用了 “MultipartFormDataContent” 对象进行上传,添加字符串内容,及StreamContent,直接可以将MVC中的File对象传入,不用自行处理临时文件。
var content = new MultipartFormDataContent("Upload-----" + Guid.NewGuid().ToString().Replace("-", ""));
content.Add(new StringContent(project), "\"project\"");
content.Add(new StringContent(version), "\"version\"");
content.Add(new StreamContent(eggStream), "\"egg\"", "\"" + project + ".egg" + "\"");
var resp = client.PostAsync("addversion.json", content).Result;
var strResult = resp.Content.ReadAsStringAsync().Result;
return JsonConvert.DeserializeObject<AddVersionResponse>(strResult);
完整代码
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text;
using Newtonsoft.Json;
using Scrapyd.Client.Response; namespace Scrapyd.Client
{
/// <summary>
/// A Client used to communicate with the Scrapyd Daemon
/// </summary>
public class ScrapydClient
{
private readonly string _host;
private readonly int _port; public ScrapydClient(string host, int port)
{
_host = host;
_port = port;
} /// <summary>
/// 查询状态
/// </summary>
/// <returns></returns>
public DaemonStatusResponse QueryStatus()
{
HttpClient client = new HttpClient()
{
BaseAddress = new Uri($"http://{_host}:{_port}")
}; try
{
var strResult = client.GetStringAsync("daemonstatus.json").Result; var jresult = JsonConvert.DeserializeObject<DaemonStatusResponse>(strResult);
return jresult;
}
catch (Exception e)
{
return new DaemonStatusResponse { status = "failed", message = e.Message };
}
} public AddVersionResponse AddVersion(string project, string version, Stream eggStream)
{
if (string.IsNullOrEmpty(project)) throw new ArgumentNullException(nameof(project));
if (eggStream == null) throw new ArgumentNullException(nameof(eggStream)); var client = new HttpClient()
{
BaseAddress = new Uri($"http://{_host}:{_port}")
}; try
{
var content = new MultipartFormDataContent("Upload-----" + Guid.NewGuid().ToString().Replace("-", "")); content.Add(new StringContent(project), "\"project\"");
content.Add(new StringContent(version), "\"version\"");
content.Add(new StreamContent(eggStream), "\"egg\"", "\"" + project + ".egg" + "\""); var resp = client.PostAsync("addversion.json", content).Result; var strResult = resp.Content.ReadAsStringAsync().Result; return JsonConvert.DeserializeObject<AddVersionResponse>(strResult);
}
catch (Exception e)
{
return new AddVersionResponse { status = "failed", message = e.Message };
}
} public ScheduleResponse ScheduleJob(string project, string spider,
string setting = "",
string jobid = "",
string version = "",
Dictionary<string, string> arguments = null)
{
if (string.IsNullOrEmpty(project)) throw new ArgumentNullException(nameof(project));
if (string.IsNullOrEmpty(spider)) throw new ArgumentNullException(nameof(spider)); var client = new HttpClient()
{
BaseAddress = new Uri($"http://{_host}:{_port}")
}; try
{
var data = new Dictionary<string, string>()
{
{"project", project},
{"spider", spider}
}; if (!string.IsNullOrEmpty(jobid))
{
data.Add("jobid", jobid);
}
if (!string.IsNullOrEmpty(setting))
{
data.Add("setting", setting);
} if (!string.IsNullOrEmpty(version))
{
data.Add("_version", version);
} if (arguments != null && arguments.Count > )
{
foreach (var argument in arguments)
{
data.Add(argument.Key, argument.Value);
}
} var strResult =
client.PostAsync("schedule.json", new FormUrlEncodedContent(data))
.Result.Content.ReadAsStringAsync()
.Result; return JsonConvert.DeserializeObject<ScheduleResponse>(strResult); }
catch (Exception e)
{
return new ScheduleResponse { status = "failed", message = e.Message };
}
} public CancelResponse CancelJob(string project, string jobid)
{
if (string.IsNullOrEmpty(project)) throw new ArgumentNullException(nameof(project));
if (string.IsNullOrEmpty(jobid)) throw new ArgumentNullException(nameof(jobid)); var client = new HttpClient()
{
BaseAddress = new Uri($"http://{_host}:{_port}")
}; try
{
var content = new FormUrlEncodedContent(new Dictionary<string, string>()
{
{"project", project},
{"job", jobid}
});
var strResult = client.PostAsync($"/cancel.json", content).Result.Content.ReadAsStringAsync().Result; return JsonConvert.DeserializeObject<CancelResponse>(strResult); }
catch (Exception e)
{
return new CancelResponse { status = "failed", message = e.Message };
}
} public ListProjectsResponse ListProjects()
{
try
{
var client = new HttpClient
{
BaseAddress = new Uri($"http://{_host}:{_port}")
};
var result = client.GetStringAsync("listprojects.json").Result;
return JsonConvert.DeserializeObject<ListProjectsResponse>(result);
}
catch (Exception e)
{
return new ListProjectsResponse { status = "failed", message = e.Message };
}
} public ListVersionsResponse ListVersions(string project)
{
if (string.IsNullOrEmpty(project)) throw new ArgumentNullException(nameof(project)); try
{
var client = new HttpClient
{
BaseAddress = new Uri($"http://{_host}:{_port}")
}; var result = client.GetStringAsync($"listversions.json?project={project}").Result;
return JsonConvert.DeserializeObject<ListVersionsResponse>(result);
}
catch (Exception e)
{
return new ListVersionsResponse { status = "failed", message = e.Message };
}
} public ListSpidersResponse ListSpiders(string project, string version = "")
{
if (string.IsNullOrEmpty(project)) throw new ArgumentNullException(nameof(project)); try
{
var client = new HttpClient
{
BaseAddress = new Uri($"http://{_host}:{_port}")
}; var result = client.GetStringAsync($"listspiders.json?project={project}&_version={version}").Result;
return JsonConvert.DeserializeObject<ListSpidersResponse>(result);
}
catch (Exception e)
{
return new ListSpidersResponse { status = "failed", message = e.Message };
}
} public ListJobsResponse ListJobs(string project)
{
if (string.IsNullOrEmpty(project)) throw new ArgumentNullException(nameof(project)); try
{
var client = new HttpClient
{
BaseAddress = new Uri($"http://{_host}:{_port}")
}; var result = client.GetStringAsync($"listjobs.json?project={project}").Result;
return JsonConvert.DeserializeObject<ListJobsResponse>(result);
}
catch (Exception e)
{
return new ListJobsResponse { status = "failed", message = e.Message };
}
} public ScrapydResponse DeleteVersion(string project, string version)
{
if (string.IsNullOrEmpty(project)) throw new ArgumentNullException(nameof(project));
if (string.IsNullOrEmpty(version)) throw new ArgumentNullException(nameof(version)); var client = new HttpClient()
{
BaseAddress = new Uri($"http://{_host}:{_port}")
}; try
{
var data = new Dictionary<string, string>()
{
{"project", project},
{"version", version}
}; var strResult =
client.PostAsync("delversion.json", new FormUrlEncodedContent(data))
.Result.Content.ReadAsStringAsync()
.Result; return JsonConvert.DeserializeObject<ScrapydResponse>(strResult); }
catch (Exception e)
{
return new ScrapydResponse { status = "failed", message = e.Message };
}
} public ScrapydResponse DeleteProject(string project)
{
if (string.IsNullOrEmpty(project)) throw new ArgumentNullException(nameof(project)); var client = new HttpClient()
{
BaseAddress = new Uri($"http://{_host}:{_port}")
}; try
{
var data = new Dictionary<string, string>()
{
{"project", project}
}; var strResult =
client.PostAsync("delproject.json", new FormUrlEncodedContent(data))
.Result.Content.ReadAsStringAsync()
.Result; return JsonConvert.DeserializeObject<ScrapydResponse>(strResult); }
catch (Exception e)
{
return new ScrapydResponse { status = "failed", message = e.Message };
}
} } }
博客地址 : http://www.cnblogs.com/mobwiz/
【原创】Scrapyd 的 .net 客户端的更多相关文章
- 原创:Javascript Websocket客户端封装
调试中,马马虎虎能用var LeesWebSocket = function (options) { this.defaults = { host: "127.0.0.1", po ...
- 微信团队原创分享:iOS版微信的内存监控系统技术实践
本文来自微信开发团队yangyang的技术分享. 一.前言 FOOM(Foreground Out Of Memory),是指App在前台因消耗内存过多引起系统强杀.对用户而言,表现跟crash一样. ...
- 让互联网更快:新一代QUIC协议在腾讯的技术实践分享
本文来自腾讯资深研发工程师罗成在InfoQ的技术分享. 1.前言 如果:你的 App,在不需要任何修改的情况下就能提升 15% 以上的访问速度,特别是弱网络的时候能够提升 20% 以上的访问速度. 如 ...
- 【转】手把手教你读取Android版微信和手Q的聊天记录(仅作技术研究学习)
1.引言 特别说明:本文内容仅用于即时通讯技术研究和学习之用,请勿用于非法用途.如本文内容有不妥之处,请联系JackJiang进行处理! 我司有关部门为了获取黑产群的动态,有同事潜伏在大量的黑产群 ...
- 全面解密QQ红包技术方案:架构、技术实现、移动端优化、创新玩法等
本文来自腾讯QQ技术团队工程师许灵锋.周海发的技术分享. 一.引言 自 2015 年春节以来,QQ 春节红包经历了企业红包(2015 年).刷一刷红包(2016 年)和 AR 红包(2017 年)几个 ...
- 微信团队分享:Kotlin渐被认可,Android版微信的技术尝鲜之旅
本文由微信开发团队工程是由“oneliang”原创发表于WeMobileDev公众号,内容稍有改动. 1.引言 Kotlin 是一个用于现代多平台应用的静态编程语言,由 JetBrains 开发( ...
- 腾讯技术分享:GIF动图技术详解及手机QQ动态表情压缩技术实践
本文来自腾讯前端开发工程师“ wendygogogo”的技术分享,作者自评:“在Web前端摸爬滚打的码农一枚,对技术充满热情的菜鸟,致力为手Q的建设添砖加瓦.” 1.GIF格式的历史 GIF ( Gr ...
- 微信技术分享:微信的海量IM聊天消息序列号生成实践(算法原理篇)
1.点评 对于IM系统来说,如何做到IM聊天消息离线差异拉取(差异拉取是为了节省流量).消息多端同步.消息顺序保证等,是典型的IM技术难点. 就像即时通讯网整理的以下IM开发干货系列一样: <I ...
- 手把手教你读取Android版微信和手Q的聊天记录(仅作技术研究学习)
1.引言 特别说明:本文内容仅用于即时通讯技术研究和学习之用,请勿用于非法用途.如本文内容有不妥之处,请联系JackJiang进行处理! 我司有关部门为了获取黑产群的动态,有同事潜伏在大量的黑产群 ...
随机推荐
- SpringMVC 之 表单标签
本篇我们来学习Spring MVC表单标签的使用,借助于Spring MVC提供的表单标签可以让我们在视图上展示WebModel中的数据更加轻松. 一.首先我们先做一个简单了例子来对Spring MV ...
- 省选模拟赛 LYK loves graph(graph)
题目描述 LYK喜欢花花绿绿的图片,有一天它得到了一张彩色图片,这张图片可以看做是一张n*m的网格图,每个格子都有一种颜色去染着,我们用-1至n*m-1来表示一个格子的颜色.特别地,-1代表这个颜色是 ...
- python的StringIO模块
StringIO经常被用来作字符串的缓存,因为StringIO的一些接口和文件操作是一致的,也就是说同样的代码,可以同时当成文件操作或者StringIO操作. 一.StringIO中的常用方法 1.r ...
- 1.5 Scipy:高级科学计算
sklearn实战-乳腺癌细胞数据挖掘(博主亲自录制视频教程) https://study.163.com/course/introduction.htm?courseId=1005269003&am ...
- 前端PHP入门-003-echo离不开它,注释看人品
不要自以为是,瞪着双眼看是没有用的!因为你不是天才! 永远不要自欺欺人,写不出来代码就是不会. 不要问为什么?我头疼! 我接触的人当中,以为自己已经很很很牛X了,总是问为什么这么写? [心中吐槽]:我 ...
- 往android主项目中添加辅助项目
一个较大的工程往往需要多个项目组成,便于更好的并行开发和管理,但最后还是要合到一起来发布.那如何往主项目里添加其他辅助项目呢? 通常的做法是将辅助项目打包成jar包,像库一样导入到主项目,但是如果我们 ...
- SpringCloud学习(4)——Ribbon负载均衡
Ribbon概述 SpringCloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡工具. 简单的说, Ribbon是Netflix发布的开源项目, 主要功能是提供客户端软 ...
- 维护后面的position + 离线 + 线段树 bzoj 3585
3585: mex Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 918 Solved: 481[Submit][Status][Discuss] ...
- CSS进阶知识
html { -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; text-size-adjust: 100%; } 该属性的作用是 ...
- 【CodeForces】915 F. Imbalance Value of a Tree 并查集
[题目]F. Imbalance Value of a Tree [题意]给定n个点的带点权树,求所有路径极差的和.n,ai<=10^6 [算法]并查集 [题解]先计算最大值的和,按点权从小到大 ...