proxy 環境下でselenium がうまく動作しなくて困っていた話

困っていたこと

  • Windows11 になってselenium をアップデートしてからselenium manager が動かなくて困っていた話
  • ChromeDriver も起動しない

原因

  • 環境変数の設定をちゃんとしてあげる必要がある
  • http_proxy, https_proxy が設定されてないとselenium manager がちゃんと動作しない
  • no_proxy が設定されてないとChromeDriver が起動しない

やり方1

窓ボタン→検索→env と入力してEnter→env と入力してEnter

システム環境変数を以下の通り設定

全部設定しないとダメ

http_proxy
{proxy_addr:port}

https_proxy
{proxy_addr:port}

no_proxy
127.0.0.1,localhost

やり方2

  • os.environ でプログラム実行時に環境変数を割り当てる

全部設定しないとダメ

import os

os.environ["HTTP_PROXY"] = "{proxy_addr: port}"
os.environ["HTTPS_PROXY"] = "{proxy_addr: port}"
os.environ["NO_PROXY"] = "localhost,127.0.0.1"

Selenium経由でChromeの開発者ツールのrequest URLを取得する

やりたいこと

Selenium経由でChromeの開発者ツールでみえるようなrequest URLを取得する

原因

質問でチラ見した

やり方

  • driver.get_log でログをゲットしてrequest でフィルタする

参考にしたサイト(というかほぼそのまま)

blog.motikan2010.com

別の要素でフィルタすることもできそう

github.com

  • 実際のやり方
# coding:utf-8
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.chrome.options import Options
import json

url = 'https://www.google.co.jp/'

options = webdriver.ChromeOptions()
options.set_capability("goog:loggingPrefs", {"performance": "ALL"})
driver = webdriver.Chrome(options=options,)
driver.get(url)

for entry_json in driver.get_log('performance'):
    entry = json.loads(entry_json['message'])
    if entry['message']['method'] != 'Network.requestWillBeSent' :
        continue
    print(entry['message']['params']['request']['url'])

driver.close()

ファイル名を大文字から小文字に変換する

やりたいこと

大文字の拡張子でできた.pdf とかを自社のシステムにアップロードすると良くないことがおこるので、拡張子を小文字にしたい

原因

相手が勝手に.PDF とかで吐いてくるから(ドウシテ…

やり方

  • lower メソッド を使う(逆に大文字にしたいときはupper メソッドを使う)
# 使い方

print("Hello".lower())
>> hello

print("apple".upper())
>> APPLE
  • 実際のやり方
# ダウンロードしてきたときのファイル名 を小文字にする
filename = '20231216_BILL.PDF'
filename = filename1.lower()

# ダウンロードしたPDFファイル名をアップロード用に変更する
# ダウンロードディレクトリは download_dir
pdf_file_name_before = os.path.join(download_dir, filename)

# アップロード用に社名を頭につける
pdf_file_name = 'A社請求書_' + filename
pdf_file_name_after = os.path.join(download_dir, pdf_file_name)

#ダウンロードしたファイル名から、アップロード用にファイル名を変更する
os.rename(pdf_file_name_before, pdf_file_name_after) 

Windows環境でpython のzipfile ライブラリを使ったときに文字化けするのをなんとかしたい

やりたいこと

Windows環境でpython のzipfile ライブラリを使ったときに文字化けするのをなんとかしたい

そうは言っても相手側が勝手に送るzip なんでこっちで対策する必要がある場合

全部utf-8 で済ませられる人には関係ない話

原因

zipfile ライブラリがcp432 を使ってくるので、cp932 を使うようにzipfile ライブラリを書き換える

やり方

  • zipfile ライブラリを探せ

path ってうってpython.exe ある場所わかるから、↓のフォルダ開いたらLib フォルダ見つけられると思う

path
C:\Users\[ユーザ名]\AppData\Local\Programs\Python\Python38\ 
  • Lib フォルダ内の zipfile.py をコピペしてzipfileJPN.py にする

  • zipfileJPN.py をエディタで開いて cp437 を cp932 で置換

  • 保存

import zipfileJPN

exist_dir = '[展開したいフォルダ]'

#ZIP展開する(展開後元ZIPは削除する)
with zipfileJPN.ZipFile('sample.zip') as existing_zip:
    existing_zip.extractall(exist_dir)
os.remove('sample.zip')

pfx の証明書を使ってpython のrequests でクライアント証明書を使ったアクセスを行う

やりたいこと

pfx のクライアント証明書経由でアクセスする必要があるサイトをpython のrequests でアクセスしたい

前提知識

pfx の証明書はPKCS#12 に相当し、証明書や秘密鍵、中間証明書が同梱された証明書となっている。

requests の使い方をドキュメントで調べると…

You can also specify the local cert file either as a path or key value pair:

requests-docs-ja.readthedocs.io

>>> requests.get('https://kennethreitz.com', cert=('/path/server.crt', '/path/key'))
<Response [200]>

となっているので、crt とkey ファイルに分離すればいけそう。

上記のことから、pfx の証明書からpem 形式(非暗号化)に変換する必要がある。

証明書のエクスポート

PKCS#12(pfx)形式から、秘密鍵、公開鍵形式への変換方法

knowledge.digicert.com

  1. OpenSSLでPKCS#12形式から秘密鍵ファイルをエクスポートする

    ※要クライアント証明書のパスワード

    openssl pkcs12 -in <PKCS#12ファイル名> -nocerts -nodes -out <秘密鍵ファイル名>
    
  2. OpenSSLでPKCS#12形式から証明書ファイルをエクスポートする

    ※要クライアント証明書のパスワード

    openssl pkcs12 -in <PKCS#12ファイル名> -clcerts -nokeys -out <証明書ファイル名>
    
  3. OpenSSLでPKCS#12形式から中間CA証明書ファイルをエクスポートする

    (今回使っているpfx にはなかった)

    openssl pkcs12 -in <PKCS#12ファイル名> -cacerts -nokeys -out <中間CA証明書ファイル名>
    

実際にrequests に入れる

{証明書ファイル名} と {秘密鍵ファイル名} には↑で作成したそれぞれのファイルパスを指定する

import requests

URL =" {アクセスするURL} "
API_TOKEN=" {APIトークン} "

headers = {"X-Cybozu-API-Token":API_TOKEN,'X-Requested-With':'XMLHttpRequest'}
response =requests.get( URL , headers=headers,cert=('{証明書ファイル名}','{秘密鍵ファイル名}'))

無事にアクセスできました。

ブラーバ M6 iRobot アプリで追加できない問題(解決済)

既存ルンバが入っているiRobot アプリにブラーバM6 が追加できなかった。 Wifi に接続されないというエラーになる。(つながっている)

使っているスマホiPhone 12 Pro Max でどうにもならなかったので、 もう一台あるiPhoneSE2 に新しくiRobot アプリを追加し、 ブラーバを追加したら正常に認識、ロボットの管理自体はクラウド側の管理なので、 問題なくiPhone 12 Pro Max からも認識された。 すぐiPhoneSE2 のアプリは消した。

Python + Selenium でfileupload

Python + Selenium でfileupload しないといけないことがあったので、調べたのですが、日本語だと古い記事しか見つからなかったので、メモ。

開発環境 MacOS Catalina, Python3

XPath でファイルアップロードのinput 属性を指定して、send_keys でファイルパスを渡せばよい。

# アップロードするファイルパス
uploadfile = './file/uploadfile.pdf'
# ファイルアップロード
driver.find_element_by_xpath('//input[@type="file"]').send_keys(uploadfile)

# ファイルアップロード をクリック
driver.find_element_by_xpath('//*[@id="btn_upload"]/').click()

これが

これが
こうなって
こうなって

あとは、ファイルアップロードボタンをクリック(最後の行)すればupload できます。