SeleniumとPythonを使用したGigaFile便への自動ファイルアップロード

# SeleniumとPythonを使用したGigaFile便への自動ファイルアップロード

## はじめに
この記事では、PythonのSeleniumライブラリを使用して、GigaFile便にファイルを自動でアップロードする方法を紹介します。また、GUIが不要なヘッドレスブラウザモードでの実行方法も説明します。

## 環境設定
- Python 3.x
- Selenium
- Chrome WebDriver
- tqdm

これらのライブラリおよびツールが必要です。未インストールの場合は、以下のコマンドでインストールできます。

```bash
pip install selenium tqdm
```

Chrome WebDriverは、[こちら](https://sites.google.com/a/chromium.org/chromedriver/downloads)から適切なバージョンをダウンロードしてください。

## コード全体
以下のコードは、指定されたファイルをGigaFile便にアップロードする関数 `upload_files` を定義しています。





```python
def upload_files(file_paths, lifetime=100):
    # Chromeオプションの設定
    options = Options()
    options.page_load_strategy = 'eager'
    options.add_argument("--headless")  # ヘッドレスモードを有効化

    # WebDriverの設定
    driver = webdriver.Chrome(options=options)

    # GigaFile便のウェブサイトにアクセス
    driver.get("https://gigafile.nu/")

    # 保存期限の値に基づいて適切な要素を選択し、クリック
    valid_lifetimes = [3, 5, 7, 14, 30, 60, 100]
    if lifetime in valid_lifetimes:
        lifetime_selector = f"li[data-lifetime-val='{lifetime}']"
        element = WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.CSS_SELECTOR, lifetime_selector)))

        # JavaScriptを使用してクリックする
        driver.execute_script("arguments[0].click();", element)
    else:
        print(f"無効な保存期限: {lifetime}。有効な値: {valid_lifetimes}")

    # ファイル選択とアップロードの処理
    file_input = driver.find_element(By.CSS_SELECTOR, "#upload_panel_button > input")
    file_input.send_keys("\n".join(file_paths))

    # Initialize tqdm progress bar
    progress_bar = tqdm(total=100, desc="Overall Progress", unit="%")

    while True:
        progress_texts = []
        for i in range(len(file_paths)):
            progress_texts.append(driver.find_element(By.CSS_SELECTOR, f"#file_{i} > div.file_info_prog_box > span").text)
        
        if all(text == "完了！" for text in progress_texts):
            progress_bar.n = 100
            progress_bar.update(0)
            break

        overall_progress = 0
        for text in progress_texts:
            if text != "完了！":
                overall_progress += int(text.rstrip("%"))
        
        overall_progress /= len(file_paths)
        progress_bar.n = overall_progress
        progress_bar.update(0)

        time.sleep(1)

    progress_bar.close()

    # 「まとめてダウンロード」リンクのURLを取得してクリック
    matomete_link_btn = driver.find_element(By.ID, "matomete_btn")
    driver.execute_script("arguments[0].click();", matomete_link_btn)

    # アラートが表示されたら、OKをクリックして閉じる
    try:
        WebDriverWait(driver, 10).until(EC.alert_is_present(),
                                       'Timed out waiting for PA creation ' +
                                       'confirmation popup to appear.')

        alert = driver.switch_to.alert
        alert.accept()
        print("アラートを閉じました。")
    except TimeoutException:
        print("アラートが表示されませんでした。")

    # origin属性を持つ要素を取得して、その値を印刷
    matomete_url_element = driver.find_element(By.ID, "matomete_url")
    origin_value = matomete_url_element.get_attribute("origin")
    
    # 終了時にブラウザを閉じる
    driver.quit()

    #URLを返す
    return origin_value 

```


## 使用例

まず、`upload_files`関数を使用するためには、アップロードしたいファイルのパスのリストと、設定したいファイルの保存期限（日数）を用意する必要があります。例として、以下の2つのファイルをアップロードし、保存期限を30日に設定する場合を考えます。

```python
# アップロードするファイルのパスをリストに格納
file_paths = [
    "/path/to/file1.pdf",
    "/path/to/file2.jpg"
]

# 関数を呼び出し、ファイルのアップロードと保存期限の設定を行う
url = upload_files(file_paths, lifetime=30)
```

このコードでは、`file1.pdf`と`file2.jpg`という2つのファイルをアップロードし、保存期限を30日に設定しています。パスは実際にアップロードしたいファイルの場所に置き換える必要があります。


## コードの詳細解説
この関数`upload_files`は、指定されたファイルパスのリストをGigaFile便にアップロードするためのSeleniumスクリプトです。以下は、この関数の各部分に対する詳細な説明です。

### 関数定義と初期設定

```python
def upload_files(file_paths, lifetime=100):
```
- この関数は、`file_paths`（アップロードするファイルのパスのリスト）と`lifetime`（ファイルの保存期限を日数で指定）を引数として受け取ります。`lifetime`はデフォルトで100日に設定されています。

```python
options = Options()
options.page_load_strategy = 'eager'
options.add_argument("--headless")
```
- Chromeブラウザのオプションを設定します。ページ読み込み戦略を'eager'に設定して、必要最低限のリソースが読み込まれた時点で操作を開始します。
- `--headless`オプションにより、ブラウザのGUIを表示せずにバックグラウンドで実行します。

```python
driver = webdriver.Chrome(options=options)
```
- 設定したオプションを用いて、Chrome WebDriverのインスタンスを初期化します。

### ウェブサイトへのアクセスと要素の操作

```python
driver.get("https://gigafile.nu/")
```
- GigaFile便のウェブサイトにアクセスします。

```python
if lifetime in valid_lifetimes:
    lifetime_selector = f"li[data-lifetime-val='{lifetime}']"
    element = WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.CSS_SELECTOR, lifetime_selector)))
    driver.execute_script("arguments[0].click();", element)
```
- 指定された保存期限に応じて、対応する要素をCSSセレクタで見つけ、JavaScriptを用いてクリック操作を行います。

### ファイルのアップロード処理

```python
file_input = driver.find_element(By.CSS_SELECTOR, "#upload_panel_button > input")
file_input.send_keys("\n".join(file_paths))
```
- ファイルアップロードのための入力フィールドを見つけ、引数で与えられたファイルパスをそのフィールドに入力します。

### アップロード進行状況の監視

```python
progress_bar = tqdm(total=100, desc="Overall Progress", unit="%")
...
progress_bar.close()
```
- `tqdm`ライブラリを用いてプログレスバーを表示し、アップロードの進捗状況をユーザーに視覚的に提供します。

### その他の操作とブラウザの終了

```python
    matomete_link_btn = driver.find_element(By.ID, "matomete_btn")
    driver.execute_script("arguments[0].click();", matomete_link_btn)
...
return origin_value 
```
- ファイルアップロード後に、「まとめてダウンロード」ボタンをクリックし、発生したアラートを処理します。
- 最終的に、ウェブドライバを閉じてURLを返します。




## まとめ
この記事では、SeleniumとPythonを使用してGigaFile便にファイルを自動でアップロードする方法を紹介しました。ヘッドレスモードにより、GUIが不要な環境でも使用可能です。