UiPathで、ファイルをまとめてダウンロード
UiPathでファイルをまとめてダウンロード
とある知り合いが、悩んでいました。
その悩みとは。。。
いま契約している有償サイトが閉鎖することになった。
そのサイトは、業界向けのドキュメントのアーカイブで、ドキュメントはPDF形式で
そこで、
とりあえず、片っ端からダウンロードしたいが、
バイトにやらせるのもねぇ。。。
との内容。
そこで、ワタシは、
「なあんだ、そんなのRPAにやらせればいいじゃん。」
「え? でも金ないぞ。」
このブログのネタにさせてもらう!
ってコトで、格安で引き受けました。
ってコトで、格安で引き受けました。
(それでもイメージとかアップできないので。。。)
ポイントは
・とにかく自動でダウンロードしたい・使うのは今回だけなので金はかけたくない
→ 本格的な開発はム~リ~
サイトの方はどうなっているかと言えば
・要求は暗号化されている
・条件指定で検索、1ページ20件まで表示
・結果は表形式(テーブル)表示される
・表中のリンクをクリックするとダウンロードページが表示される
最初は、自動で検索とかも考えていましたが、『
半自動ダウンロードの仕様
・『金はかけたくない』 とのことなので、検索は人が行う
使っているブラウザは、Chromeなのでソレに固定。
1年分とかをまとめて検索、時系列に古い順にソート、は人にやってもらいます。
すでに検索済みのページに対してダウンロードを行うとする。
検索結果のページは、下記のようになる。
・『金はかけたくない』 とのことなので、”力技”実装
検索結果は、テーブルにサマリーとリンクとして表示される。
そのリンクをクリックするとダウンロードページに遷移する。
ページは同じフォーマットなので、キホン”タブ”+”Enter” で操作できる。
テーブルの前に、いくつかのリンクがあるので、ソコを”タブ”で飛ばす。
テーブル内のリンクまでたどり着いたら”Enter”でダウンロードページ遷移。
テーブルのリンクまでの”タブ”の数は決まっている。
次の検索結果リンクは、”タブ”を1つづつ増やせばよい。
ダウンロードページでは、
"ダウンロード"のボタンをクリック。
”Alt”+”←”の入力で戻る
以上を20件繰り返し、
最後まで行ったら、”次のページ” をクリック
入力は、"TypeInfo"で入力
ただし、高速化のためStringでまとめで入力しています。
クリックは、"ClickImage"でボタンイメージを指定
『金はかけたくない』とのことなので。。。やっつけ的な対応
テーブル要素を指定して操作することもできますが、”タブ”
人間ならめんどくさい”タブ”+”Enter”だって、RPAは文句言いませんから。
その上、ページ応答はちゃんとWait処理せず、 3秒待って次の処理で対応。
最後のページは20件のドキュメントがなく、 端数になりますがソコは人が対応してください!
あまり多くのページをまとめてダウンロードすると問題が発生する (後述)場合があるので、ある程度細切れで対応した方がよいが、 StartとMaxの変数名に自分で数値を設定して対応してくれ 。
それでも実際に実行してみると。。。
・サイトが応答しなくなる・ダウンロードに失敗する
ことがある。。。
などナド、サーバー側に起因するような問題がたまに発生します。
かなりクセモノなサイトです。
かなりクセモノなサイトです。
応答がなくなった場合、 途中で止まったりしているのでわかります。
ただし、このときRPAが爆走するので、他のプログラムを止めておいて、プリンタとかも切断しておいたほうが安全です。
厄介なのが、ダウンロードは始まるものの、途中で失敗するケース。
仕方がないので後からオマケで付けた機能ですが、
ダウンロードの失敗があとから見てわかりやすいように、
ダウンロードの失敗があとから見てわかりやすいように、
つまり20件ごとにダミーファイルが発生するので、 その間に20件のドキュメントが無ければ失敗しているので、 どれが失敗しているのかは自分で確認して手動で対応してくれ、 と、言うことにしました。
ヤレヤレ
UiPathのプログラミング内容
System.Activities.Statements.Sequence // 全体をシーケンスで作成 { UiPath.Core.Activities.WindowScope // 検索結果のブラウザ(Chrome)にアタッチ { System.Activities.Statements.While // ページ数分のループ Condition: 処理済みページ数 <= ページ数 Body: { System.Activities.Statements.Sequence // ページ毎の処理 { System.Actuvities.Statements.Assign テーブルカウント = 1 // テーブル処理数 System.Activities.Statements.While // 1ページ20件まで処理 Condition: テーブルカウント <= 20 Body: { System.Activities.Statements.Sequence // 1件のダウンロード処理 { UiPath.Core.Activities.TypeInfo // 頭のいくつかのリンクをスキップ "[k(tab)][k(tab)][k(tab)][k(tab)][k(tab)][k(tab)][k(tab)]" System.Actuvities.Statements.Assign タブカウント = 0 System.Actuvities.Statements.Assign テーブル選択文字列 = "" System.Activities.Statements.While // テーブルの処理レコード数の"タブ"を加算 Condition: ダウンロード数 <= 20 Body: { System.Activities.Statements.Sequence // タブのダウンロード処理 { System.Actuvities.Statements.Assign タブカウント < テーブルカウント System.Actuvities.Statements.Assign テーブル選択文字列 = テーブル選択文字列 + "[k(tab)]" System.Actuvities.Statements.Assign タブカウント = タブカウント + 1 } } System.Actuvities.Statements.Assign テーブル選択文字列 = テーブル選択文字列 + "[k(enter)]" UiPath.Core.Activities.TypeInfo テーブル選択文字列 System.Actuvities.Statements.Delay 3秒待つ // 3秒待ってる間に切り替わるハズ UiPath.Core.Activities.ClickImage "ダウンロード"ボタン // ダウンロードボタンをクリック System.Actuvities.Statements.Delay 3秒待つ // 3秒待ってる間にダウンロードが始まるハズ UiPath.Core.Activities.SendHotKey "Alt"+"←" // 前ページに戻る System.Actuvities.Statements.Delay 3秒待つ // 3秒待ってる間に切り替わるハズ System.Actuvities.Statements.Assign テーブルカウント = テーブルカウント + 1 } } } // 1ページ、20件のダウンロードが終わった UiPath.Core.Activities.ClickImage "次のページ"ボタン // 次のページボタンをクリック System.Actuvities.Statements.Assign ダミーファイル名 = XXX + 処理済みページ数 UiPath.Core.Activities.CreateFile ダミーファイル名で作成 System.Actuvities.Statements.Delay 1秒待つ // 1秒くらい待たないとよくないみたいだ System.Actuvities.Statements.Assign 処理済みページ数 = 処理済みページ数 + 1 } } }
※ "{}"は、入れ子を示しやすくするためのものです。
もう一つ、我々は当たり前と思っていたことでしたが。。。
RPAを実行している間はパソコンが使えない!
「えー! そーなのー!!」
飯食ってる間とか、出かけている時とか、帰るときに実行してくれ、
と、言うことで対応してもらいました。
なかなか小規模な方など、
思い込みは、システム屋の地雷である。
久々に感じました。
Have a Happy Hucking!!
Lightning Brains
Lightning Brains
コメント
コメントを投稿