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件のPDFファイルがない場合は、失敗と判断できるようにしました。

つまり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を実行している間はパソコンが使えない!

「えー! そーなのー!!」

飯食ってる間とか、出かけている時とか、帰るときに実行してくれ、
と、言うことで対応してもらいました。
なかなか小規模な方など、PCが1台しかないなんてケースは要注意ですね。

思い込みは、システム屋の地雷である。
久々に感じました。





Have a Happy Hucking!!

Lightning Brains

コメント

このブログの人気の投稿

Linuxシステムコール、共有メモリの使い方

Linuxシステムコール、メッセージキューの使い方

Linuxシステムコール、セマフォの使い方