C#でgigafile便にアップロードされたファイルをダウンロードする【備忘録】

C#でgigafile便からファイルをダウンロードすることができたのでここに残しておきます。

この記事は、2022年11月6日時点でのものです。
この先gigafile便で仕様変更がなされて、紹介する方法が使えなくなる可能性があります。

環境

  • ランタイム: .NET 6.0
  • OS: Windows 11 21H2

ダウンロードの仕組み

結果だけ知りてーよ!という方も手順1だけはお読みください。

ダウンロードしたいファイルのURLを
https://31.gigafile.nu/0000-hogehoge
として説明します。

1. ファイルID・サーバー番号の取得

ファイルID(仮称)は、上記URLの0000-hogehogeの部分です。


サーバー番号(仮称)は、上記URLのgigafile.nuの前についている番号です。
このURLの場合は31です。

これらを記録しておきます。

2. ダウンロードURLの取得

単一ファイルの場合と、「まとめる」を行ったファイルの場合とでURLが異なります。

単一ファイルの場合

download.phpにリクエストを送ることでファイルをダウンロードできます。
ファイルIDを引数として渡します。


ダウンロードURLは、
https://<サーバー番号>.gigafile.nu/download.php?file=<ファイルID>
です。

今回ダウンロードしたいファイルの場合、
https://31.gigafile.nu/download.php?file=0000-hogehoge
となります。

「まとめる」を行ったファイルの場合

dl_zip.phpにリクエストを送ることでファイルをダウンロードできます。
ファイルIDを引数として渡します。


ダウンロードURLは、
https://<サーバー番号>.gigafile.nu/dl_zip.php?file=<ファイルID>
です。

今回ダウンロードしたいファイルの場合、
https://31.gigafile.nu/dl_zip.php?file=0000-hogehoge
となります。

3. ダウンロード

上で得たダウンロードURLにリクエスト送るだけだろー
と思われるかもしれませんが、僕はここでハマりました。
ファイルを取得するプログラムを書いて実行しても正しくダウンロードされない……。

そこで試しにブラウザでアクセスしてみたところ、このようなアラートが

エラーのアラート

あれ?

※このメッセージが何度も表示される場合、Cookieが無効になっている可能性があります。

gigafile.nuからの大ヒント

なるほどCookieを送ればいいのか!!!()

この予想は正しく、一度正規のダウンロードページにアクセスし、取得したCookieとともにダウンロードURLにリクエストを送るとファイルをダウンロードすることができました。

いらん話・自分語り

このダウンロード方法を見つけるのがそこそこ大変だった^^;
というのも、単純なリクエストだけでgigafile便からダウンロードする方法をググっても出てこなかったんですよね。Edgeの開発者ツールで(Chrome使えって言わないで)gigafile便のソースを地道に読んで探しました。

cf. gigafile.nu/js/download.js, gigafile.nu/js/matomete.js

実装

ではC#で実装します。同期処理で書いていきます。

任意のWebページにアクセスしてCookieを取得する関数↓

static System.Net.CookieCollection GetCookieCollectionFromUrl(string url) {
    var cc = new System.Net.CookieContainer();
    var req = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(url);
    req.CookieContainer = new System.Net.CookieContainer();
    await req.GetResponse();
    return req.CookieContainer.GetCookies(new Uri(url));
}

任意のアドレスからCookieを取得し、System.Net.CookieCollectionとして返します。

ファイルをダウンロードする処理↓

string fileUrl = "ダウンロードページのURL";
string downloadUrl = "ダウンロードURL";
string filename = "保存したいファイル名";

var req = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(downloadUrl);
req.CookieContainer = new System.Net.CookieContainer();
req.CookieContainer.Add(GetCookieCollectionFromUrl(fileUrl));
var response = req.GetResponse();
var list = new List<byte>();
var stream = response.GetResponseStream();

using (var fs = new FileStream(filename, FileMode.Create, FileAccess.Write)) {
    byte[] data = new byte[1024];
    while (true) {
        var size = stream.Read(data, 0, data.Length);
        if (size == 0) {
            break;
        }
        fs.Write(data, 0, size);
    }
}

Streamオブジェクトを取得してFileStreamに書き込んでるだけ

適宜いじってご利用ください。

おまけ:ファイル名を取得する

ダウンロードしたいファイルのファイル名を取得します。

string filename = "";
// reqは上の「ファイルをダウンロードする処理」のHttpWebRequest
string cd = req.Headers.Get("Content-Disposition");
var re = new System.Text.RegularExpressions.Regex(@".*[filename*=UTF]-[8]''(?<filename>.*)");
var m = re.Match(cd);
fileName = System.Web.HttpUtility.UrlDecode(m.Groups["filename"].Value);

Content-Dispositionレスポンスヘッダーから正規表現でファイル名を探しています。

おわりに

C#でgigafile便にアップロードされたファイルをダウンロードする方法を備忘録も兼ねて紹介しました。
何かの参考になれば幸いです。

もしこの記事が伸びたらPython版とかも書くかも
記事量産できるし

タイトルとURLをコピーしました