アングラサイトに、全く物怖じしない、弓削田です。
何故なら、そのサイトで構築されているシステムの上を行く技術を持つ自身があるから・・・
それは言いすぎかもしれないけれど、
何かしらのダウンロードサイトに行った時に、アフェリエイト広告が山盛りのダウンロードサイトには、
うんざりしてしまいます。
もちろん、無料で閲覧させてもらっている上、便利にダウンロードさせてもらえるって、
神のようなサイトなんだけど、めんどくさいのは、非常に嫌なのであるし、
広告なんかに邪魔されたくないのである。
あと、自宅だけど、できるだけ無駄なパケットも消費したくないし・・・
一番は、時間の効率化を求めたい。
という事で、今回は、たくさんファイルがダウンロードできるサイトで、
自動的にダウンロードできるツールを作って、作業自動化をして、コーヒー飲みながら
待っているだけになったという技術的な話をしてみたいと思います。
ダウンロードサイトについて
窓の杜や、フリーソフトダウンロード、
何かしらのエミュレーターソフトのダウンロード(もちろん合法のものですよwww)
ダウンロードしたいコンテンツがたくさんあって、
それらを一つずつリンククリックしてダウンロードしてくようなサイトに出会った時、
まずリンククリックして、ダウンロードページに行くと思いますが、多くの場合広告山盛りサイトに行き、
「○秒後にリンクが表示されます」という文言が表示されて、カウントダウン
その後、リンクが表示されて、ダウンロードリンクが画面に表示されて、それをクリックすれば、
対象のファイルがダウンロードできるというような、ウザい手順のサイトがとても多いでしょう。
これは、アフェリエイト(広告表示)することが目的なので、致し方ないかもしれませんが、
ウザいことに変わりはありません。
1つのダウンロードで、30秒ぐらいかかるとしたら、
ダウンロードするリンクが100個あった場合に、3000秒 = 50分 アバウト1時間・・・orz
もったいない時間の無駄ですね。
構築手順と仕様設計
はい!そこで、プログラミングが出来る人は、簡単なプログラムを作って、
こうした手間と時間をショートカットする事を考えます。
とりあえず、こうしたやり方(クローリングとかスクレイピングって言います)がわからない人は、
参考にしてみてください。
分析
まず、対象のサイトのHTMLソースコードを分析します。
これは、HTML言語を理解している必要もありますが、
DOM構造を意識した、サイトの構成を掴むことが重要です。
ちなみに、今回対応したサイトの構成は次のような感じでした。
- ダウンロードコンテンツのグループ一覧ページ
- グループのコンテンツ一覧表示(一定個数毎にページネーションさせる仕様)
- コンテンツ単体のダウンロードリンク
- コンテンツダウンロードのカウントダウンページ(一定時間が経つと、ダウンロードリンクが表示される)
- リンクをクリックすると、ダイレクトダウンロード
とりあえず、上記のそれぞれのリンクのselector情報も抜き取って置くと、この後の作業がはかどります。
幸い今回対応するページは、ダイレクトダウンロードすることができるページだったので、
最終のダウンロードURLさえあれば、どんな状態でもダウンロードができるようになるという事で
比較的ラクな部類でした。
余談ですが、セッション情報や、リファラー情報、クッキー利用ダウンロードなどなど、
ダウンロードセキュリティが周到なサイトでは、URLだけでダウンロードできない場合もあるし、
ロボット判断する処理を入れていて、手書き文字を読み取って入力するなどの場合は、もはや
すべての作業をオートにするのが難しいでしょうね。
そして、一番重要な仕様ですが、できるかぎりJavascriptのみで対応できるようにしたいと思います。
運が良ければ、ブラウザのデバッグコンソールに、javascriptをコピペするだけで、簡単ダウンロードできる仕様もできます。
ですが、今回は、PHPを使って、ある程度のサーバーサイド仕様を入れないといけないことがわかったので、
javascript + phpという仕組みで行いました。
あとは、プログラミングするだけですね。
しんどかった点と他のサイトでの流用のヒント
さて、実際のプログラミングですが、いくつか、課題にぶち当たったので、その内容も書き残しておきます。
まず、javascriptでHTMLソースコードを取得する場合に、クロスドメイン(ダウンロードするサイトのドメイン)に引っかかり、ソースコードが取得できなかったので、
簡単なPHP処理を作って、PHP側でソースコードを取得→それをjavascriptで受け取り、HTMLをパースして処理するようにしました。
まだあります。
ダウンロードリンクをするときに、次のようなURLだったので、これを解明する必要がありました。
http://ドメイン/SlhVek1EWkJKWFV6TURrekpYVXpNRFJDSlhVek1EVTNKWFV6TURnNUpYVXpNRFpGSlhVek1FSXpKWFV6TUVZekpYVXpNRU0ySlhVek1FWXpKWFV6TUVNMEpYVXpNRU0zSlhVek1FWkRKWFV6TUVKR0xucHBjQ1UzUXpBdU1DNHdMakFsTjBNeE5qRTNOemsxTkRVekpUZERabWx1WVd4ZlpHOTNibXh2WVdSZmJHbHVhdz09
通常の人であれば、この段階でお手上げに感じると思いますが、
エンジニアたるもの、ある程度の暗号を解読する術は持っておきたいものです。
そして、簡単なbase64ぐらいであれば、javascriptでデコードできてしまうので、記号部分をデコードしてみます。
atob("SlhVek1EWkJKWFV6TURrekpYVXpNRFJDSlhVek1EVTNKWFV6TURnNUpYVXpNRFpGSlhVek1FSXpKWFV6TUVZekpYVXpNRU0ySlhVek1FWXpKWFV6TUVNMEpYVXpNRU0zSlhVek1FWkRKWFV6TUVKR0xucHBjQ1UzUXpBdU1DNHdMakFsTjBNeE5qRTNOemsxTkRVekpUZERabWx1WVd4ZlpHOTNibXh2WVdSZmJHbHVhdz09")
> "JXUzMDZBJXUzMDkzJXUzMDRCJXUzMDU3JXUzMDg5JXUzMDZFJXUzMEIzJXUzMEYzJXUzMEM2JXUzMEYzJXUzMEM0JXUzMEM3JXUzMEZDJXUzMEJGLnppcCU3QzAuMC4wLjAlN0MxNjE3Nzk1NDUzJTdDZmluYWxfZG93bmxvYWRfbGluaw=="
結果も、暗号文字列なので、ここで心折れそうですが、念の為、これもbase64デコードしてみます。
atob("JXUzMDZBJXUzMDkzJXUzMDRCJXUzMDU3JXUzMDg5JXUzMDZFJXUzMEIzJXUzMEYzJXUzMEM2JXUzMEYzJXUzMEM0JXUzMEM3JXUzMEZDJXUzMEJGLnppcCU3QzAuMC4wLjAlN0MxNjE3Nzk1NDUzJTdDZmluYWxfZG93bmxvYWRfbGluaw==")
> "%u306A%u3093%u304B%u3057%u3089%u306E%u30B3%u30F3%u30C6%u30F3%u30C4%u30C7%u30FC%u30BF.zip%7C0.0.0.0%7C1617795453%7Cfinal_download_link"
あれ?なんか、認識できそうな文字列になった。
文字列のところは、urlencodeっぽいので、これをURLデコードしてみる。
unescape("%u306A%u3093%u304B%u3057%u3089%u306E%u30B3%u30F3%u30C6%u30F3%u30C4%u30C7%u30FC%u30BF.zip%7C0.0.0.0%7C1617795453%7Cfinal_download_link");
> "なんかしらのコンテンツデータ.zip|0.0.0.0|1617795453|final_download_link"
マーベラス!!!解読成功ですね。
ここまですんなり解読できる事も少ないかもしれませんが、実際のダウンロードのフォーマットがわかれば、ページ内のいろいろな情報を元にこのURLを作り出すこともできるはずです。
まとめ
こんな感じで、130行ぐらいのjavascriptと、15行ぐらいのphpをプログラミングして、
無事に500個ものダウンロードを、鼻くそをほじくりながら、30分ぐらい放置で達成することができました。
でも、残念ながら、こうしたプログラミングは、ほぼそのサイト専用のプログラムになるので、
他のサイトでは、使い物になりません。
別のサイトで使う場合は、また同じ様な工程で、プログラミングしなければいけません。
最近流行りのRPAとかDXって、こういう事というのをわかってもらえるだけでもいいかもですね。
プログラマーって、こういう30分で済む話を、僕の場合でも2時間かかって作っている訳ですが、そういう生き物という事を合わせて覚えておいてもらえると幸いです。
0 件のコメント:
コメントを投稿