python - Python代码:赋值前引用的局部变量
问题描述
我在 python 2.7 中有以下程序来启动网页并进行活动。我已经解析了网页的 HTML DOM,并且能够在通过 PyCharm IDE 或通过使用 PyInstaller 创建的 Exe 或通过包装 Exe 的 bat 文件启动时完成这项工作。
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.common.by import By
import time
import sys
def main():
try:
mgmt_console_server_name = sys.argv[1]
user_session_to_terminate = sys.argv[2]
# Phase 1: Launch a browser and open the management console page
# Using IE to access web
driver = webdriver.Ie('IEDriverServer32.exe')
return_code = 0
# Open the management console page.
driver.get("http://" + mgmt_console_server_name + ":8183/mgmt/security/login.html")
# Phase 2: Enter the LDAP credentials and hit enter
# Select the username and the password text boxes
username = driver.find_element_by_class_name('gwt-TextBox')
password = driver.find_element_by_class_name('gwt-PasswordTextBox')
# Send username information
username.send_keys('sa-tcnxbot-gds')
# Send password information
password.send_keys('zzzzzzzzz')
# Login to Teamcenter management console with the above set credentials.
signinbutton = driver.find_element_by_class_name('GFHWBTICII')
signinbutton.click()
# Phase 3: Click on the 'TcServer' component to reach the UI where we can find and kill the user sessions.
# We are now in the main page. We need to wait till we find an XML element by the ID
# 'Console'. This signifies that the page has loaded. And we wait at the maximum of 20 seconds.
WebDriverWait(driver, 20).until(ec.presence_of_element_located((By.ID, "Console")))
# We find the XML element whose InnerHTML is 'Tc Server'.
tcserverelement = driver.find_element_by_xpath("//div[text()='Tc Server']")
# We then find its immediate parent, which is the clickable element and finally click it.
tcserverclickableelement = tcserverelement.find_element_by_xpath('..')
tcserverclickableelement.click()
# Phase 4: We enter the user id whose session is to be terminated in the search field and hit the search.
WebDriverWait(driver, 20).until(ec.presence_of_element_located((By.XPATH, "//div[text()='Assigned User:']")))
# We are at the HTML element that has the text 'Assigned User:'
assigneduserelement = driver.find_element_by_xpath("//div[text()='Assigned User:']")
# print(assigneduserelement)
# An immediate parent of this HTML element is the TD element.
assigneduserelementparent = assigneduserelement.find_element_by_xpath('..')
# print(assigneduserelementparent)
# An immediate sibling of this TD HTML element is another TD element which contains INPUT HTML element.
assigneduserelementparent.find_element_by_xpath("//TD/following-sibling::TD")
# print(assigneduserelementparent_sibling)
# assignedusertextbox = assigneduserelementparent_sibling.find_elements_by_xpath(".//*")
# print(assignedusertextbox[0])
# Send username information
driver.find_elements_by_class_name('gwt-TextBox')[1].send_keys(user_session_to_terminate)
search_button = driver.find_element_by_xpath("//button[text()='Search']")
# We then find its immediate parent, which is the Search button and finally click it.
search_button.click()
time.sleep(4)
# There would be three cases here.
# Case 1: The input user has no sessions on his name.
# Case 2: The input user has one session on his name.
# Case 3: The input user has more than one sessions on his name.
# Case 1: This should be one of the table header elements containing the list of servers assigned to the user.
assigned_server_rows = driver.find_elements_by_xpath("//div[text()='Assigned']")
if len(assigned_server_rows) == 0:
return_code = 4
else:
# Case 2 and Case 3:
for each_assigned_server in assigned_server_rows:
print each_assigned_server.tag_name
assigned_server_parent_td = each_assigned_server.find_element_by_xpath('..') # td
print assigned_server_parent_td.tag_name
assigned_server_parent_td.click()
# assigned_server_parent_tr = assigned_server_parent_td.find_element_by_xpath('..') #tr
# print assigned_server_parent_tr.tag_name
# assigned_server_parent_tr.click()
shutdown_button_element = driver.find_element_by_xpath("//button[text()='Shutdown Server']")
shutdown_button_element.click()
time.sleep(2)
main_page = driver.window_handles[0]
alert_window = driver.switch_to.alert
alert_window.accept()
driver.switch_to.window(main_page)
except:
return_code = 1
finally:
driver.quit()
if return_code == 0:
print('=> Successfully terminated sessions for the user ' + user_session_to_terminate)
elif return_code == 4:
print('=> There are no sessions assigned to the user ' + user_session_to_terminate)
else:
print('=> An error occurred while tying to terminate sessions for the user ' + user_session_to_terminate)
return return_code
if __name__ == "__main__":
main()
但作为 Azure Chatbot 的一部分,当我们尝试将其插入 NodeJS 代码时,我们看到了这个问题。我的代码真的有问题吗?我应该如何正确纠正它。
我阅读了关于 python 的作用域,但在这种情况下,一切都在 main 函数内,并且知道 python try-catch 不会添加新的块作用域。所以我的期望是一切都应该奏效。请让我知道我错过了什么。
PyAutomationScript Error:Error: Command failed: C:\tcnxbot_data\automated_script\auto.exe localhost pdittaka
[9904] Failed to execute script auto
Traceback (most recent call last):
File "auto.py", line 131, in <module>
File "auto.py", line 118, in main
UnboundLocalError: local variable 'driver' referenced before assignment
谢谢,帕万。
解决方案
这可能是 finally 函数内的行的问题。你本质上说的是不管是否有错误(无论是进入 try 还是 except ) execute driver.quit()
。
但是,如果您的代码在定义驱动程序之前或期间在 try 中遇到错误,它会进入 except,然后是您尝试关闭驱动程序的 finally。但是,这是不可能的,因为尚未定义驱动程序。你可以做的是在 main 函数的开头添加这个:
driver = None
并将内部的代码更改为finally:
:
if driver is not None:
driver.quit()
推荐阅读
- c# - ICAL.NET 重复元素:每个月的第五个或最后一个星期日
- google-analytics - Google Analytics API V4 - 通过 URL 查询查找
- d3.js - 将选择与组合并
- php - ftp_put():打开文件上传到“/xxx.txt”服务器的数据通道
- jquery - jQuery UI Chosen MultiSelect 插件选择保留在 Chrome 中,但不在 IE11 或 Edge 中
- regex - RewriteRule 不适用于 .htaccess 中的斜杠
- c# - 列表框不添加句子
- java - 如何在 Java 应用程序中在运行时更新 css 文件
- angular - rxjs/Subscription 没有导出的成员“ISubscription”
- ios - 在发布模式下部署后应用组无法正常工作