如果你想跳過這個簡單的代碼示例,可以看到在GitHub完整的源代碼:https://github.com/XtrmJosh/YouTubeDownloader
我是非常正確的與我的假設,雖然它是我花10個小時左右,我終於實現了我的目標。這是一個粗略的故障:
- 逃生繩,以確保我們不會破壞任何東西
- 運行一些花哨的正則表達式,什麼不能捕捉到的字符串的確切領域,我們正在尋找
- 查找簽名和我們發現每個網址中都沒有(我們會發現很多,我們需要在它們可以使用之前將它們縮小一點點)
- 添加我們爲每個網址找到的簽名,否則我們會得到垃圾文件
- 掃描一些itags,所以我們知道哪個文件類型與每個鏈接相關聯 - 我只有想要FLV文件。
- 將視頻名稱追加到URL中,然後下載。
因此,這裏是我使用的是得到一個HTML文檔中的所有視頻的網址(僅限YouTube - 至今)代碼
public static List<string> ExtractUrls(string html)
{
string title = GetTitle(html);
List<string> urls = new List<string>();
string DataBlockStart = "\"url_encoded_fmt_stream_map\":\\s+\"(.+?)&"; // Marks start of Javascript Data Block
html = Uri.UnescapeDataString(Regex.Match(html, DataBlockStart, RegexOptions.Singleline).Groups[1].ToString());
string firstPatren = html.Substring(0, html.IndexOf('=') + 1);
var matchs = Regex.Split(html, firstPatren);
for (int i = 0; i < matchs.Length; i++)
matchs[i] = firstPatren + matchs[i];
foreach (var match in matchs)
{
if (!match.Contains("url=")) continue;
string url = GetTxtBtwn(match, "url=", "\\u0026", 0, false);
if (url == "") url = GetTxtBtwn(match, "url=", ",url", 0, false);
if (url == "") url = GetTxtBtwn(match, "url=", "\",", 0, false);
string sig = GetTxtBtwn(match, "sig=", "\\u0026", 0, false);
if (sig == "") sig = GetTxtBtwn(match, "sig=", ",sig", 0, false);
if (sig == "") sig = GetTxtBtwn(match, "sig=", "\",", 0, false);
while ((url.EndsWith(",")) || (url.EndsWith(".")) || (url.EndsWith("\"")))
url = url.Remove(url.Length - 1, 1);
while ((sig.EndsWith(",")) || (sig.EndsWith(".")) || (sig.EndsWith("\"")))
sig = sig.Remove(sig.Length - 1, 1);
if (string.IsNullOrEmpty(url)) continue;
if (!string.IsNullOrEmpty(sig))
url += "&signature=" + sig;
urls.Add(url);
}
for (int i = 0; i < urls.Count; i++)
{
urls[i] += "&title=";
urls[i] += title;
}
return urls;
}
public static string GetTitle(string RssDoc)
{
string str14 = GetTxtBtwn(RssDoc, "'VIDEO_TITLE': '", "'", 0, false);
if (str14 == "") str14 = GetTxtBtwn(RssDoc, "\"title\" content=\"", "\"", 0, false);
if (str14 == "") str14 = GetTxtBtwn(RssDoc, "&title=", "&", 0, false);
str14 = str14.Replace(@"\", "").Replace("'", "'").Replace("\"", """).Replace("<", "<").Replace(">", ">").Replace("+", " ");
return str14;
}
public static string GetTxtBtwn(string input, string start, string end, int startIndex, bool UseLastIndexOf)
{
int index1 = UseLastIndexOf ? input.LastIndexOf(start, startIndex) :
input.IndexOf(start, startIndex);
if (index1 == -1) return "";
index1 += start.Length;
int index2 = input.IndexOf(end, index1);
if (index2 == -1) return input.Substring(index1);
return input.Substring(index1, index2 - index1);
}
此代碼將(與當前的YouTube格式)提供一個FLV文件的鏈接,你可以下載並做你喜歡的(在YouTube的TOS內)。然後我用這從那些本規範規定找到最優質的鏈接:
public static string GetFLV(List<string> urls)
{
// Acquire a list of links which match the criteria for being FLV files
List<string> flvurls = new List<string>();
foreach (string url in urls)
{
string itag = Regex.Match(url, @"itag=([1-9]?[0-9]?[0-9])", RegexOptions.Singleline).Groups[1].ToString();
int itagint;
int.TryParse(itag, out itagint);
if (itagint == 5 || itagint == 6 || itagint == 34 || itagint == 35)
{
flvurls.Add(url);
}
}
// If we didn't find any FLVs, we return a fatal error and cause a bug later on
if (flvurls.Count == 0)
{
MessageBox.Show("Fatal error | iTag could not be found for FLV filetype. Please contact software vendor for assistance.");
return "";
}
// If we did find some FLVs, we need to find the highest quality FLV
else
{
#region findBestFLV
foreach (string url in flvurls)
{
string itag = Regex.Match(url, @"itag=([1-9]?[0-9]?[0-9])", RegexOptions.Singleline).Groups[1].ToString();
int itagint;
int.TryParse(itag, out itagint);
if (itagint == 35)
{
return url;
}
}
foreach (string url in flvurls)
{
string itag = Regex.Match(url, @"itag=([1-9]?[0-9]?[0-9])", RegexOptions.Singleline).Groups[1].ToString();
int itagint;
int.TryParse(itag, out itagint);
if (itagint == 34)
{
return url;
}
}
foreach (string url in flvurls)
{
string itag = Regex.Match(url, @"itag=([1-9]?[0-9]?[0-9])", RegexOptions.Singleline).Groups[1].ToString();
int itagint;
int.TryParse(itag, out itagint);
if (itagint == 6)
{
return url;
}
}
foreach (string url in flvurls)
{
string itag = Regex.Match(url, @"itag=([1-9]?[0-9]?[0-9])", RegexOptions.Singleline).Groups[1].ToString();
int itagint;
int.TryParse(itag, out itagint);
if (itagint == 5)
{
return url;
}
}
#endregion
}
MessageBox.Show("Fatal error | Something has gone horrible wrong whilst finding the best FLV to use. Run, brave warrior, for the end is near.");
return "";
}
注意它是在一分鐘很零碎,代碼的其餘部分大多是片斷我一直借錢略加編輯,但這一點我從頭腦裏寫了一些匆忙的嘗試,爲SOF找到一些東西。
希望這有助於別人:)
你需要一個HTML解析器。 http://htmlagilitypack.codeplex.com – SLaks
這真的不能用RegEx實現嗎?或者更好的是,在.NET中使用字符串操作? – XtrmJosh
你可以顯式*一些信息*? – Stephan