@rokuseipiitaa (H F)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

Pythonのglobal変数に要素のデータが入っていない?

解決したいこと

Python selenium chromeの組み合わせでWEB画面の操作を試みています。
global変数「driver_global」に最新のdriverを格納しているつもりですがエラーが発生します。
引数としてdriverを渡すと上手く動くのですがglobal変数として扱いたいです。
恐らく記述ルールの認識誤りだと思うのですがご指摘いただきたいです。

発生している問題・エラー

name 'driver_global' is not defined

例)

import subprocess
import time
import chromedriver_binary
import re
import os
import platform
import requests
from selenium.webdriver.common.by import By
from concurrent.futures import ThreadPoolExecutor
from concurrent.futures import ProcessPoolExecutor
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service as ChromeService
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from webdriver_manager.chrome import ChromeDriverManager

global driver_global
global urlSBI_login
urlSBI_login = "https://www.sbifxt.co.jp/login.html"

def killChromeProcess():
	print("stop_all_chrome_prcess")
	cmd = 'taskkill /im chrome.exe /f'
	returncode = subprocess.call(cmd)
	print(returncode)

# def unlockSBI(driver):
def unlockSBI():
#このやりかただとうまくいく
#def unlockSBI(driver):
	try:
		# ロックボタン押下
		driver=driver_global
		button = driver.find_element(By.XPATH,'//*[@id="tradeTwoWay"]/section/form/div[1]/input[3]')
		#このやりかただとうまくいく
		#button = driver.find_element(By.XPATH,'//*[@id="tradeTwoWay"]/section/form/div[1]/input[3]')
		button.click()
	# エラーが発生した時はエラーメッセージを吐き出す。
	except Exception as e:
		print(e)
		print("unlockSBI()のエクセプトに入った。エラーが発生しました。")
	# 最後にドライバーを終了する
	finally:
		print("unlockSBI()のふぁいなりーにはいっておしまい")

def openSBI():
	try:
		# ドライバーを自動でインストールしてくれる
		# Selenium3の場合
		#driver = webdriver.Chrome(ChromeDriverManager().install()) 
		# Selenium4の場合
		# driver = webdriver.Chrome(executable_path='C:\fukui-mini共有\selenium\chromedriver_win32\chromedriver.exe')#←すでに非推奨になった書き方
		# driver = webdriver.Chrome(service=Service(ChromeDriverManager().install())) 
		driver = webdriver.Chrome(service=ChromeService(ChromeDriverManager().install())) 

		# ------- 追加部分 -------
		# 最大の読み込み時間を設定 今回は最大30秒待機できるようにする
		wait = WebDriverWait(driver=driver, timeout=30)
		# -------------------------*/

		# 開くURL
		# ChromeDriverの呼び出し
		# driver = webdriver.Chrome()
		# utlを開く
		driver.get(urlSBI_login)
		# 要素が全て検出できるまで待機する
		wait.until(EC.presence_of_all_elements_located)
		# //<input type="text" name="ID" id="loginid" class="fz12">
		name = driver.find_element(By.ID,"loginid")
		name.send_keys("1234567890")
		# //<input type="password" name="PASS" id="password" class="fz12">
		name = driver.find_element(By.ID,"password")
		name.send_keys("pw1234567890")
		# <a href="javascript:postLoginUrl(MPAGE_URL);" onclick="$(this).click(function(e){ return false });">ログイン</a>
		#リンクテキスト名が"画像"の要素を取得
		button = driver.find_element(By.LINK_TEXT, "ログイン")
		# element.submit
		button.click()
		# 要素が全て検出できるまで待機する
		wait.until(EC.presence_of_all_elements_located)
		# <button class="channel_open c-btn-trade  p-btn-fx is-acOpend"><span class="c-lbl-sup">FX取引スタート</span></button>
		# //*[@id="home_depositGraph"]/section[1]/div/div/ul/li[1]/p/button[1]/span
		button = driver.find_element(By.CLASS_NAME,"c-lbl-sup")
		button.click()
		# # 要素が全て検出できるまで待機する
		wait.until(EC.presence_of_all_elements_located)
		#このやりかただとエラーになる
		driver_global=driver
		unlockSBI()#ロックを解除
		#このやりかただと期待通りに動作する
		#unlockSBI(driver)#ロックを解除
	# エラーが発生した時はエラーメッセージを吐き出す。
	except Exception as e:
		print(e)
		print("openSBI()のエクセプトに入った。エラーが発生しました。")
	# 最後にドライバーを終了する
	finally:
		# Chromeを閉じる
		# driver.close()
		# driver.quit()
		print("openSBI()のふぁいなりーにはいっておしまい")

#コマンドからインストールされているChromeのヴァージョンを取得
def get_chrome_version(cmd):
    pattern = r'\d+\.\d+\.\d+'
    stdout = os.popen(cmd).read()
    version = re.search(pattern, stdout)
    chrome_version = version.group(0)
    print('Chrome Version : ' + chrome_version)
    return chrome_version

#Chromeのヴァージョンから、適合する最新のChromeDriverのヴァージョンを取得
def get_chrome_driver_version(chrome_version):
    url = 'https://chromedriver.storage.googleapis.com/LATEST_RELEASE_' + chrome_version
    response = requests.request('GET', url)
    print('ChromeDriver Version : ' + response.text)
    return response.text

# SBIのchromeが起動できているかチェック 0存在せず、1正常、
def chromeOpenCheckSBI():
	try:
		while True:
			print("checkStatusSBI()でエラー")
			# if IeOpenCheck()=1 then//chromeが起動していれば
	# エラーが発生した時はエラーメッセージを吐き出す。
	except Exception as e:
		print(e)
		print("checkStatusSBI()でエラー")
	# 最後にドライバーを終了する
	finally:
		# Chromeを閉じる
		# driver.close()
		# driver.quit()
		print("chromeOpenCheckSBI()のふぁいなりーにはいっておしまい")

#残っているといやなのですべてのchromeプロセスを落としておく
killChromeProcess()
#OSを判別
#cmd:それぞれのOSでChrome(Beta)のヴァージョンを確認するコマンド
#location:Chrome(Beta)の場所
pf = platform.system()
if pf == 'Windows':
    print('OS : Windows')
    cmd = r'reg query "HKEY_CURRENT_USER\Software\Google\Chrome Beta\BLBeacon" /v version'
    location = 'C:/Program Files/Google/Chrome Beta/Application/chrome.exe'

elif pf == 'Darwin':
    print('OS : Mac')
    cmd = r'/Applications/Google\ Chrome\ Beta.app/Contents/MacOS/Google\ Chrome\ Beta --version'
    location = '/Applications/Google Chrome Beta.app/Contents/MacOS/Google Chrome Beta'

if __name__ == '__main__':
	#Chromeのヴァージョン取得
	chrome_version = get_chrome_version(cmd)
	#Chromeのヴァージョンから、適合する最新のChromeDriverのヴァージョンを取得
	driver_version = get_chrome_driver_version(chrome_version)
	#Chromeの場所を指定
	options = Options()
	options.binary_location = location
	#ChromeDriverのヴァージョンを指定
	chrome_service = ChromeService(ChromeDriverManager(version=driver_version).install())
	driver = webdriver.Chrome(service=chrome_service,options=options)
	driver.close()#インストール用に起動したchromeはこのあと使わないので閉じる
	driver.quit()#インストール用に起動したchromeはこのあと使わないので閉じる
	with ThreadPoolExecutor(max_workers=8) as executor:
		executor.submit(openSBI())#初期処理
0 likes

1Answer

global は関数の中で使う宣言です。以下のように関数の中でグローバル変数に代入したいとき、ローカル変数ではないことを明示するために使います。

a = 'NONE'

def set_local():
    # 関数のローカル変数 a に代入する。グローバル変数 a には影響しない
    a = 'LOCAL'

def set_global():
    # a がグローバル変数だと宣言する
    global a
    # グローバル変数 a に代入する
    a = 'GLOBAL'

set_local()
print(a) # => NONE
set_global()
print(a) # => GLOBAL

エラーを解消するには def openSBI(): の次の行に global driver_global を書いてください。

なお、トップレベルに global driver_global と書いても意味はありません。宣言だけでは変数は作られませんし、宣言しなくてもトップレベルで代入すればグローバル変数になります。

1Like

Comments

  1. @rokuseipiitaa

    Questioner

    ありがとうございます。ご指摘いただいた通りにやってみたのですが、やはりdriverの中身はglobal変数には入ってくれずにエラーとなります。unlockSBI(driver)というふうにdriverを渡してあげると上手くうごいてくれるのですが、これをglobalで扱うことはpythonでは不可能でしょうか。
    以下に簡略化してみたのですがdriverをglobal化させるにはどのように記述すればよいか教えていただけるでしょうか。
    driver
    urlSBI_login = "https://www.sbifxt.co.jp/login.html"

    def unlockSBI():
    button = driver.find_element(By.XPATH,'//*[@id="tradeTwoWay"]/section/form/div[1]/input[3]')
    button.click()

    def openSBI():
    driver = webdriver.Chrome(service=ChromeService(ChromeDriverManager().install()))
    driver.get(urlSBI_login)
    name = driver.find_element(By.ID,"loginid")
    name.send_keys("1234567890")
    name = driver.find_element(By.ID,"password")
    name.send_keys("pw1234567890")
    button = driver.find_element(By.LINK_TEXT, "ログイン")
    button.click()
    button = driver.find_element(By.CLASS_NAME,"c-lbl-sup")
    button.click()
    unlockSBI()#ロックを解除
    openSBI()
  2. @rokuseipiitaa

    Questioner

    ↑pythonはインデントが消されてしまうと読みづらいですね、、、すみません
  3. 整形したコードを回答として投稿してもらえると助かります。
  4. 簡略化したコードには global 宣言が入っていないようですが、実際には入れてありますか?
  5. @rokuseipiitaa

    Questioner


    上記のように黒い背景のコード特有の表現ができず見にくくてすみません。

    ---python

    driver#←グローバル変数

    【呼ばれる関数】
    def unlockSBI()
      global driver#←中身が入っていない気がしています
    button = driver.find_element(By.XPATH,'XXXXXXX')
    button.click()

    【呼び出し側】
    def openSBI()
      driver = webdriver.Chrome(service=ChromeService(ChromeDriverManager().install()))
      driver.get("XXXXXX")
      ~省略~
      global driver#←このdriverに赤いエラーの下線が付きます
      unlockSBI()
    ---
  6. global driver は def openSBI() の次の行に書いてください。 driver = webdriver.Chrome(略) の前に(つまり関数の中で driver に何か代入する前に)書かないと意味がありません。

    逆に代入せずグローバル変数を読み取るだけなら不要なので、 unlockSBI() の中では global driver なしでも動きます。
  7. それと

    driver#←グローバル変数

    もエラーになります。 driver = None のように何か値を代入してください。
  8. コメント欄でコードの整形が効かない仕様のは困りますよね。コメントではなく回答として投稿すれば整形が効くので、必要ならそちらから貼ってください。
  9. @rokuseipiitaa

    Questioner

    動きました! global変数が期待通りに使用できました! pythonはdriverの前に書くんですね。確かに言われてみれば当たり前なのですが、他の言語ではトップに書くだけで済んでいた事なのでuasiさんにとってはチンプンカンプンなやり取りをさせることになってしまい申し訳ありませんでした。

    コードの整形についても理解できておらず申し訳ありませんでした。この記入欄の下に「投稿する」という欄はあるのですが「回答」という欄は私が質問者だからなのか見当たらなかったのでこの「質問者コメント」の事をおっしゃっていると思いこんでおりました。

    バージョン違いで動かなかったり、global変数の使い方のように基本的なところで躓いてしまって前途多難でございます。

    ここ数日全然先に進まなくて呆然としていたので感謝感謝ですm(_ _)m
  10. 解決したなら何よりです。

    > 「回答」という欄は私が質問者だからなのか見当たらなかったのでこの「質問者コメント」の事をおっしゃっていると思いこんでおりました。

    確かに質問者から見ると何のことやらですね、これは失礼しました。

Your answer might help someone💌