ボットを構築して日常業務を自動化する方法

ほとんどのジョブには、自動化できる反復タスクがあり、貴重な時間を解放します。これにより、自動化は習得するための重要なスキルになります。

熟練した自動化エンジニアとドメインの専門家の小グループが、チーム全体の最も退屈なタスクの多くを自動化できる場合があります。

この記事では、強力で習得が容易なプログラミング言語であるPythonを使用したワークフロー自動化の基本について説明します。Pythonを使用して、特定のフォルダーをクリーンアップし、各ファイルを対応するフォルダーに配置する、簡単で便利な小さな自動化スクリプトを作成します。

私たちの目標は、最初から完璧なコードを書いたり、理想的なアーキテクチャを作成したりすることではありません。

また、「違法」なものは作成しません。代わりに、特定のフォルダーとそのすべてのファイルを自動的にクリーンアップするスクリプトを作成する方法を見ていきます。

目次

  1. 自動化の分野とどこから始めるべきか
    • シンプルな自動化
    • パブリックAPIオートメーション
    • APIリバースエンジニアリング
  2. 自動化の倫理的考慮事項
  3. ディレクトリクリーンアップスクリプトの作成
  4. ボットの作成と日常業務の自動化に関する完全ガイド

自動化の分野とどこから始めるべきか

どんな種類の自動化があるかを定義することから始めましょう。

自動化の技術はほとんどのセクターに適用されます。手始めに、それはあなたが電子メールブラストをすることができるようにたくさんの文書から電子メールアドレスを抽出するようなタスクを助けます。または、大企業内のワークフローとプロセスの最適化など、より複雑なアプローチ。

もちろん、小さな個人用スクリプトから実際の人に取って代わる大規模な自動化インフラストラクチャに移行するには、学習と改善のプロセスが必要です。それでは、どこから旅を始められるか見てみましょう。

シンプルな自動化

シンプルな自動化により、すばやく簡単なエントリポイントが可能になります。これは、プロジェクトのクリーンアップやディレクトリ内のファイルの再構築などの小さな独立したプロセス、またはすでに保存されているファイルの自動サイズ変更などのワークフローの一部をカバーできます。

パブリックAPIオートメーション

現在、APIへのHTTPリクエストを使用してほとんどの機能にアクセスできるため、パブリックAPI自動化は最も一般的な自動化の形式です。たとえば、自宅で自分で作ったスマートガーデンの水やりを自動化したい場合です。

そのためには、今日の天気をチェックして、水をやる必要があるかどうか、または雨が降っているかどうかを確認します。

APIリバースエンジニアリング

APIリバースエンジニアリングベースの自動化は、実際のボットと、以下の「倫理的考慮事項」セクションのチャートの「ボット詐欺師」セクションでより一般的です。

APIをリバースエンジニアリングすることで、アプリケーションのユーザーフローを理解します。一例として、オンラインブラウザゲームへのログインがあります。

ログインと認証のプロセスを理解することで、独自のスクリプトでその動作を複製できます。次に、アプリケーションが提供していなくても、アプリケーションを操作するための独自のインターフェイスを作成できます。

目的のアプローチが何であれ、それが合法であるかどうかを常に考慮してください。

トラブルに巻き込まれたくないですよね??

倫理的配慮

GitHubの誰かが私に連絡して、こう言ったことがあります。

「いいねとエンゲージメントはデジタル通貨であり、あなたはそれらを切り下げています。」

これは私に固執し、まさにその目的のために私が構築したツールに疑問を投げかけました。

これらの相互作用とエンゲージメントが自動化され、ますます「偽造」される可能性があるという事実は、歪んだ壊れたソーシャルメディアシステムにつながります。

ボットやその他のエンゲージメントシステムを使用しない場合、価値のある優れたコンテンツを作成する人々は、他のユーザーや広告会社には見えません。

私の友人は、ダンテの「Nine Circles of Hell」と次のような関係を思いつきました。そこでは、社会的影響力を持つ人になるまでの一歩ごとに、このシステム全体が実際にどれほど壊れているかについて気づきにくくなります。

これは、InstaPyでインフルエンサーと積極的に協力しているときに私が目撃したことを非常に正確に表したものだと思うので、ここで共有したいと思います。

レベル1:Limbo-ボットをまったく行わない場合

Level 2: Flirtation - When you manually like and follow as many people as you can to get them to follow you back / like your posts

Level 3: Conspiracy - when you join a Telegram group to like and comment on 10 photos so the next 10 people will like and comment on your photo

Level 4: Infidelity - When you use a low-cost Virtual Assistant to like and follow on your behalf

Level 5: Lust - When you use a bot to give likes, and don’t receive any likes back in return (but you don’t pay for it - for example, a Chrome extension)

Level 6: Promiscuity - When you use a bot to Give 50+ likes to Get 50+ likes, but you don’t pay for it - for example, a Chrome extension

Level 7: Avarice or Extreme Greed - When you use a bot to Like / Follow / Comment on between 200–700 photos, ignoring the chance of getting banned

Level 8: Prostitution - When you pay an unknown 3rd party service to engage in automated reciprocal likes / follows for you, but they use your account to like / follow back

Level 9: Fraud / Heresy - When you buy followers and likes and try to sell yourself to brands as an influencer

The level of botting on social media is so prevalent that if you don’t bot, you will be stuck in Level 1, Limbo, with no follower growth and low engagement relative to your peers.

経済理論では、これは囚人のジレンマとゼロサムゲームとして知られています。私がボットせず、あなたがボットした場合、あなたが勝ちます。あなたがボットせず、私がボットした場合、私は勝ちます。ボットがいない場合は、全員が勝ちます。しかし、誰もがボットしないというインセンティブがないため、誰もがボットするので、誰も勝ちません。

これに注意し、このツール全体がソーシャルメディアに与える影響を決して忘れないでください。

私たちは、倫理的な影響に対処することを避け、引き続きここで自動化プロジェクトに取り組んでいきたいと考えています。これが、乱雑なフォルダを整理するのに役立つ簡単なディレクトリクリーンアップスクリプトを作成する理由です。

ディレクトリクリーンアップスクリプトの作成

ここで、非常に単純なスクリプトを見てみましょう。これらのファイルをファイル拡張子に基づいて適切なフォルダに移動することにより、特定のディレクトリを自動的にクリーンアップします。

だから私たちがしたいのはこれだけです:

引数パーサーの設定

Since we are working with operating system functionality like moving files, we need to import the os library. In addition to that, we want to give the user some control over what folder is cleaned up. We will use the argparse library for this.

import os import argparse

After importing the two libraries, let's first set up the argument parser. Make sure to give a description and a help text to each added argument to give valuable help to the user when they type --help.

Our argument will be named --path. The double dashes in front of the name tell the library that this is an optional argument. By default we want to use the current directory, so set the default value to be ".".

parser = argparse.ArgumentParser( description="Clean up directory and put files into according folders." ) parser.add_argument( "--path", type=str, default=".", help="Directory path of the to be cleaned directory", ) # parse the arguments given by the user and extract the path args = parser.parse_args() path = args.path print(f"Cleaning up directory {path}")

This already finishes the argument parsing section – it's quite simple and readable, right?

Let's execute our script and check for errors.

python directory_clean.py --path ./test => Cleaning up directory ./test

Once executed, we can see the directory name being printed to the console, perfect.

Let's now use the os library to get the files of the given path.

Getting a list of files from the folder

By using the os.listdir(path) method and providing it a valid path, we get a list of all the files and folders inside of that directory.

After listing all elements in the folder, we want to differentiate between files and folders since we don't want to clean up the folders, only the files.

In this case, we use a Python list comprehension to iterate through all the elements and put them into the new lists if they meet the given requirement of being a file or folder.

# get all files from given directory dir_content = os.listdir(path) # create a relative path from the path to the file and the document name path_dir_content = [os.path.join(path, doc) for doc in dir_content] # filter our directory content into a documents and folders list docs = [doc for doc in path_dir_content if os.path.isfile(doc)] folders = [folder for folder in path_dir_content if os.path.isdir(folder)] # counter to keep track of amount of moved files # and list of already created folders to avoid multiple creations moved = 0 created_folders = [] print(f"Cleaning up {len(docs)} of {len(dir_content)} elements.")

As always, let's make sure that our users get feedback. So add a print statement that gives the user an indication about how many files will be moved.

python directory_clean.py --path ./test => Cleaning up directory ./test => Cleaning up 60 of 60 elements.

After re-executing the python script, we can now see that the /test folder I created contains 60 files that will be moved.

Creating a folder for every file extension

The next and more important step now is to create the folder for each of the file extensions. We want to do this by going through all of our filtered files and if they have an extension for which there is no folder already, create one.

The os library helps us with more nice functionality like the splitting of the filetype and path of a given document, extracting the path itself and name of the document.  

# go through all files and move them into according folders for doc in docs: # separte name from file extension full_doc_path, filetype = os.path.splitext(doc) doc_path = os.path.dirname(full_doc_path) doc_name = os.path.basename(full_doc_path) print(filetype) print(full_doc_path) print(doc_path) print(doc_name) break

The break statement at the end of the code above makes sure that our terminal does not get spammed if our directory contains dozens of files.

Once we've set this up, let's execute our script to see an output similar to this:

python directory_clean.py --path ./test => ... => .pdf => ./test/test17 => ./test => test17

We can now see that the implementation above splits off the filetype and then extracts the parts from the full path.

Since we have the filetype now, we can check if a folder with the name of this type already exists.

Before we do that, we want to make sure to skip a few files. If we use the current directory "." as the path, we need to avoid moving the python script itself. A simple if condition takes care of that.

In addition to that, we don't want to move Hidden Files, so let's also include all files that start with a dot. The .DS_Store file on macOS is an example of a hidden file.

 # skip this file when it is in the directory if doc_name == "directory_clean" or doc_name.startswith('.'): continue # get the subfolder name and create folder if not exist subfolder_path = os.path.join(path, filetype[1:].lower()) if subfolder_path not in folders: # create the folder

Once we've taken care of the python script and hidden files, we can now move on to creating the folders on the system.

In addition to our check, if the folder already was there when we read the content of the directory, in the beginning, we need a way to track the folders we've already created. That was the reason we declared the created_folders = [] list. It will serve as the memory to track the names of folders.

To create a new folder, the os library provides a method called os.mkdir(folder_path) that takes a path and creates a folder with the given name there.

This method may throw an exception, telling us that the folder already exists. So let's also make sure to catch that error.

if subfolder_path not in folders and subfolder_path not in created_folders: try: os.mkdir(subfolder_path) created_folders.append(subfolder_path) print(f"Folder {subfolder_path} created.") except FileExistsError as err: print(f"Folder already exists at {subfolder_path}... {err}")

After setting up the folder creation, let's re-execute our script.

python directory_clean.py --path ./test => ... => Folder ./test/pdf created.

On the first run of execution, we can see a list of logs telling us that the folders with the given types of file extensions have been created.

Moving each file into the right subfolder

The last step now is to actually move the files into their new parent folders.

An important thing to understand when working with os operations is that sometimes operations can not be undone. This is, for example, the case with deletion. So it makes sense to first only log out the behavior our script would achieve if we execute it.

This is why the os.rename(...) method has been commented here.

# get the new folder path and move the file new_doc_path = os.path.join(subfolder_path, doc_name) + filetype # os.rename(doc, new_doc_path) moved += 1 print(f"Moved file {doc} to {new_doc_path}")

After executing our script and seeing the correct logging, we can now remove the comment hash before our os.rename() method and give it a final go.

# get the new folder path and move the file new_doc_path = os.path.join(subfolder_path, doc_name) + filetype os.rename(doc, new_doc_path) moved += 1 print(f"Moved file {doc} to {new_doc_path}") print(f"Renamed {moved} of {len(docs)} files.")
python directory_clean.py --path ./test => ... => Moved file ./test/test17.pdf to ./test/pdf/test17.pdf => ... => Renamed 60 of 60 files.

This final execution will now move all the files into their appropriate folders and our directory will be nicely cleaned up without the need for manual actions.

In the next step, we could now use the script we created above and, for example, schedule it to execute every Monday to clean up our Downloads folder for more structure.

That is exactly what we are creating as a follow-up inside of our Bot Creation and Workflow Automation Udemy course.

A Complete Guide to Bot Creation and Automating Your Everyday Work

Felix and I built an online video course to teach you how to create your own bots based on what we've learned building InstaPy and his Travian-Bot. In fact, he was even forced to take down since it was too effective.

Join right in and start learning.

If you have any questions or feedback, feel free to reach out to us on Twitter or directly in the discussion section of the course ?