准备工作

  起因是因为这个网站:http://i.youku.com/kmsfan 这个是一个叫做冒险岛的游戏的资讯论坛,以前我经常在里面传视频,现在我不玩这个游戏了,但是很多玩家还是经常到我的网站里面去看视频,所以我觉得有点不好意思,我觉得开发出一款自动上传下载的工具比什么都好,也不耽误我时间。需要准备一些插件,这些插件都可以从Nuget里面找到,比如Newtonsoft.Json啊HtmlAgilityPack ,不过目前为止也只用到了这些东西。还有我没有做youtube视频的下载,我只做了Daum tv的视频解析,因为Insoya视频区大部分都是上传到Daum Tv 的视频。

Insoya视频区结构解析

  我先不放代码,大家先要对网站的文件解析有个大概的了解才行吧?我的想法就是:解析当天的视频。因为Insoya是一个韩国网站,所以韩文什么的思密达什么的就不要再吐槽了。这是视频区的地址:http://www.insoya.com/bbs/zboard.php?id=ucc

  大家可以把手指指向链接,可以发现:视频的ID是一个自增长的。比如:

  http://www.insoya.com/bbs/zboard.php?id=ucc&no=58158

  http://www.insoya.com/bbs/zboard.php?id=ucc&no=58157

  http://www.insoya.com/bbs/zboard.php?id=ucc&no=58156.....略掉了。。。

  我们随便点一个进去,如果我们想获得视频的标题啊,URL啊,还有发布日期的话,就可以从里面获取,下面框框就是:

需要知道的几件事情

  第一,我们从Daum Tv上面获取视频的真实地址,具体可以参考优酷,因为有点难度,视频的地址通常只是给了ID,所以我们还必须获取真实地址:不过StackoverFlow上面我得到了答案 ,哈哈多亏这位老兄。下面是daumTv 的调用API,后面的Vid是视频的ID.

        public static string daumAPI = "http://videofarm.daum.net/controller/api/closed/v1_2/IntegratedMovieData.json?vid=";

  光有了api不行,因为我们是从inosya网站里面去得到视频的真实地址,所以我们还需要有一个解析工具就是HtmlAgilityPack .为此我们需要知道网站是怎么在HTML结点里面存储这些东西的(标题,URL等)。下面几张图可以帮你解惑。下面这张图中指向的是URL,我们想,如果这些ID都是连续的话,那我是不是在第一页获取一个最大的ID,那其他的ID是不是可以都得出来了呢?

下面图是内容页的,我们可以看到时间是存储到这个CLASS里面的,也许我们有疑问,为什么我要标注CLASS呢,嘿嘿,别急,等下你就知道了。

编码1:获取文件的真实地址

  因为我们是从INSOYA网站里面去获取,INSOYA采用的是iframe方式,所以我们并没有在daumTV里面弄。我的想法是弄到DAUM TV的真实页面地址。

public static string GetDownloadUrls(string videoUrl)
{
string vid = "";
if (videoUrl == null)
{
throw new ArgumentNullException("video Url can not be null");
} //是否是标准的daumtv链接,并输出链接地址和视频ID
bool isDaumUrl = TryNormalizeDaumTvUrl(videoUrl, out videoUrl,out vid); if (!isDaumUrl)
{
throw new ArgumentException("It is not a daum Url");
}
string vLink = "";
try
{
//通过DAUM API获得返回的JSON
var json = LoadJson(daumAPI + vid); //通过JSON获得文件的真实地址。
vLink = GetVideLink(json); }
catch (Exception ex)
{ } return vLink; }

GetDownloadUrls(获取下载URL)

/// <summary>
/// 把从insoya.com中获取的视频地址转换为标准的DAUM TV的视频地址
/// </summary>
/// <param name="url"></param>
/// <param name="normalizeUrl"></param>
/// <returns></returns>
public static bool TryNormalizeDaumTvUrl(string url, out string normalizeUrl, out string vId)
{
url = url.Trim();
string videoId = "";
if (url.IndexOf("videofarm") != -)
{
int firstParam = url.IndexOf('=');
int secondParam = url.IndexOf('&')-;
videoId = url.Substring(firstParam + , secondParam - firstParam); url = "http://tvpot.daum.net/v/" + videoId; }
vId = videoId;
normalizeUrl = url; return true;
}

TryNormalizeDaumTvUrl(转换INSOYA内嵌视频地址为标准的DAUM TV视频地址)

        private static JObject LoadJson(string url)
{ string pageSource = HttpHelper.DownloadString(url); if (!IsVideoValid(pageSource))
{
throw new Exception("video not valid");
} return JObject.Parse(pageSource);
} public class HttpHelper
{
public static string DownloadString(string url)
{
using (var client = new WebClient())
{
client.Encoding = System.Text.Encoding.UTF8;
return client.DownloadString(url);
} } }

LoadJson(把返回的JSON以字符串形式下载下来)

编码2:分析HTML结点并存储

  首先我们需要得到HTML结点的数据并存储。我的想法是从主页面进去也就是:http://www.insoya.com/bbs/zboard.php?id=ucc 然后再区最大的ID,那样就可以把第一页的所有东西都取到了 o(╯□╰)o。,用的是HtmlAgilityPack 有不懂的自己百度吧。

 private static int getMaxIdOfVideo()
{
HtmlWeb docWeb = new HtmlWeb();
HtmlDocument doc = docWeb.Load("http://www.insoya.com/bbs/zboard.php?id=ucc&page=1&divpage=12"); IList<int> b = new List<int>();
foreach (HtmlNode numbers in doc.DocumentNode.Descendants("td").Where(d=>d.Attributes.Contains("class")&&
d.Attributes["class"].Value.Contains("eng w_num")))
{
int a;
int.TryParse(numbers.InnerText, out a); if (a != )
{
b.Add(a);
}
} return b.Max();
}

getMaxIdOfVideo(获取视频页面的最新视频的ID)

  下面的就是最重要的了,就是抓取视频标题,视频URL等,当然我们首先需要建立一个Model然后返回的是这个Model的List.

    public class VideoModel
{
public int VideoId { get; set; }
public string VideoUrl { get; set; }
public string Title { get; set; }
public DateTime PubTime { get; set; } }

VideoModel(视频实体模型)

public static IList<VideoModel> GrabVideoInfo()
{
int max=getMaxIdOfVideo();
int staticMax = max;
IList<VideoModel> models = new List<VideoModel>();
do {
VideoModel model=new VideoModel();
HtmlWeb innerDocWeb = new HtmlWeb();
HtmlDocument innerDoc = innerDocWeb.Load(insoyaUcc + max);
//标题
foreach (HtmlNode title in innerDoc.DocumentNode.Descendants("a").Where(d =>
d.Attributes.Contains("name") && d.Attributes["name"].Value.Contains("pv9")))
{
model.Title = title.InnerText;
break;
} //日期
foreach (HtmlNode title in innerDoc.DocumentNode.Descendants("span").Where(d =>
d.Attributes.Contains("class") && d.Attributes["class"].Value=="eng"))
{
DateTime date;
DateTime.TryParse(title.InnerText,out date); if (date != null)
{
model.PubTime = date;
break;
} }
//视频地址
foreach (HtmlNode title in innerDoc.DocumentNode.Descendants("iframe").Where(d =>
d.Attributes.Contains("title") && d.Attributes["title"].Value.Contains("maplestory_ucc")))
{
string oldUrl = title.Attributes["src"].Value;
string newUrl = GetDownloadUrls(oldUrl);
model.VideoUrl = newUrl;
break; }
model.VideoId = max;
models.Add(model);
Console.WriteLine("ID:"+max + " has accomplish grabbed!");
--max;
} while (max >= staticMax - ); return models;
}

GrabVideoInfo(获取视频模型)

  好了,到此为止我们就可以抓取到视频模型了。

尚未完成的工作

  当然了,才完成了30%,还要自动上传视频到优酷,还有要把韩文翻译成最合适的中文,如果我做出来了,会和大家分享的,首先是上传到优酷。有兴趣的同好可以看看优酷开放平台。

C#控制台程序取得INSOYA视频区的视频的真实URL,视频标题,发布时间集合。的更多相关文章

  1. 在.NET Core控制台程序中使用依赖注入

    之前都是在ASP.NET Core中使用依赖注入(Dependency Injection),昨天遇到一个场景需要在.NET Core控制台程序中使用依赖注入,由于对.NET Core中的依赖注入机制 ...

  2. 使用 CommandLineApplication 类创建专业的控制台程序

    闲话 在很久很久以前,电脑是命令行/终端/控制台的天下,那屏幕上的光标在行云流水般的键盘敲击下欢快地飞跃着,那一行行的字符输出唰唰唰地滚动着--直到 Windows 95 的出现(那时候我还不知道苹果 ...

  3. C#基础-关于用json给控制台程序传值的坑

    上周遇到了一个非常诡异的坑,首先写了两个程序,第一个程序输出成dll,第二个程序是控制台程序. 在第一个程序里,我使用了process去启动第二个程序,同时传入了一个Json作为参数,即: Proce ...

  4. 你们信不信一句Console.WriteLine就能让你的控制台程序失去响应

    好久没更新博客了,今天是扒衣见君节,难得闲下来就来说说一个最近有趣的发现吧. 首先废话不多说,直接上代码吧 class Program { static void Main(string[] args ...

  5. 【转】WIN32 控制台程序

    http://blog.csdn.net/houmin0036/article/details/7702236 win32控制台项目指在32位Windows命令提示符(即所谓的dos)环境下运行的应用 ...

  6. Async Console Programs 异步控制台程序

    如果你正在写一个控制台程序,你可能最终想要一个异步的main方法,像这样: class Program { static async void Main(string[] args) { ... } ...

  7. C#控制台程序的参数解析类库 CommandLine简单使用说明

    前言 C#开发的控制台程序,默认接收string[] args参数.如果有多个参数需要输入时,可以按照顺序依次输入:但如果有些参数不是必选的,或者有些参数中间需要有空格比如时间“2016-05-18 ...

  8. .Net Core 控制台程序错误:Can not find runtime target for framework '.NETCoreApp,Version=v1.0' compatible with one of the target runtimes: 'win10-x64, win81-x64, win8-x64, win7-x64'.

    .Net Core 控制台程序错误:Can not find runtime target for framework '.NETCoreApp,Version=v1.0' compatible wi ...

  9. C# 控制台程序(命令行程序)设置字体颜色,窗口宽高,光标行数

    控制台程序(命令行程序)设置窗口宽度高度,如下代码: Console.WriteLine(Console.WindowHeight); Console.WriteLine(Console.Buffer ...

随机推荐

  1. jQuery的61种选择器

    The Write Less , Do More ! jQuery选择器 1. #id : 根据给定的ID匹配一个元素 <p id="myId">这是第一个p标签< ...

  2. JAVA回调机制(CallBack)详解

    序言 最近学习java,接触到了回调机制(CallBack).初识时感觉比较混乱,而且在网上搜索到的相关的讲解,要么一言带过,要么说的比较单纯的像是给CallBack做了一个定义.当然了,我在理解了回 ...

  3. JavaScript Array对象

    介绍Js的Array 数组对象. 目录 1. 介绍:介绍 Array 数组对象的说明.定义方式以及属性. 2. 实例方法:介绍 Array 对象的实例方法:concat.every.filter.fo ...

  4. Spring之旅

    Java使得以模块化构建复杂应用系统成为可能,它为Applet而来,但为组件化而留. Spring是一个开源的框架,最早由Rod Johnson创建.Spring是为了解决企业级应用开发的复杂性而创建 ...

  5. 【Web动画】SVG 线条动画入门

    通常我们说的 Web 动画,包含了三大类. CSS3 动画 javascript 动画(canvas) html 动画(SVG) 个人认为 3 种动画各有优劣,实际应用中根据掌握情况作出取舍,本文讨论 ...

  6. 第一个移动前端开源项目-dailog

    你还在为手机上没有忙碌光标而发愁吗?你还在抱怨弹出框组件要依赖zepto/jqery吗?你还在纠结是否要自己写一套还是去网上寻找成现成的UI组件吗?YouA为你轻松解决所有烦恼.YouA是我为移动前端 ...

  7. 深入解析Sqlite的完美替代者,android数据库新王者——Realm

    写在前面: 又到一年一度七夕虐狗节,看着大家忍受着各种朋友圈和QQ空间还有现实生活中的轮番轰炸,我实在不忍心再在这里给大家补刀,所以我觉得今天不虐狗,继续给大家分享有用的. 如果你比较关心androi ...

  8. 后缀数组的倍增算法(Prefix Doubling)

    后缀数组的倍增算法(Prefix Doubling) 文本内容除特殊注明外,均在知识共享署名-非商业性使用-相同方式共享 3.0协议下提供,附加条款亦可能应用. 最近在自学习BWT算法(Burrows ...

  9. linux拷贝命令,移动命令

    http://blog.sina.com.cn/s/blog_7479f7990101089d.html

  10. Flex 布局教程:实例篇

    该教程整理自 阮一峰Flexible教程 今天介绍常见布局的Flex写法.你会看到,不管是什么布局,Flex往往都可以几行命令搞定. 我的主要参考资料是Landon Schropp的文章和Solved ...