【问题标题】:Hidden file input Python Selenium隐藏文件输入 Python Selenium
【发布时间】:2018-02-22 23:36:46
【问题描述】:

我在尝试使用 Python Seleniun 将文件上传到隐藏文件输入时遇到问题。为了更清楚,请看下图。

Issue example

我自己为第一个字段上传了一个文件。 下面是上传前后对应的 HTML 代码示例。

<judge-upload caption="Output to be scored" is-uploading="submissionsCtrl.isUploading[$index]" ng-model="submissionsCtrl.newSubmissions[$index].submissionBlobKey" class="ng-pristine ng-untouched ng-valid ng-scope ng-not-empty" aria-invalid="false" style=""><div class="hcj-upload">
  <md-input-container class="md-input-has-value">
    <div class="hcj-upload-label ng-binding">Output to be scored</div>
    <div class="hcj-upload-content" ng-switch="!ctrl.fileKey">
      <!-- ngSwitchWhen: true -->
      <!-- ngSwitchWhen: false --><div ng-switch-when="false" layout="row" class="ng-scope layout-row" style="">
        <div>
          <input value="example0.out" aria-label="Filename" readonly="" class="md-input" id="input_8"><div class="md-errors-spacer"></div>
        </div>
        <div>
          <button class="md-icon-button md-button md-ink-ripple" type="button" ng-transclude="" ng-click="ctrl.onClear()" aria-label="Clear">
            <md-icon class="ng-scope material-icons" role="img" aria-hidden="true">delete</md-icon>
          </button>
        </div>
      </div><!-- end ngSwitchWhen: -->
    </div>
  </md-input-container>
</div>
</judge-upload>

*************************************

<judge-upload caption="Output to be scored" is-uploading="submissionsCtrl.isUploading[$index]" ng-model="submissionsCtrl.newSubmissions[$index].submissionBlobKey" class="ng-pristine ng-untouched ng-valid ng-scope ng-empty" aria-invalid="false"><div class="hcj-upload">
  <md-input-container class="">
    <div class="hcj-upload-label ng-binding">Output to be scored</div>
    <div class="hcj-upload-content" ng-switch="!ctrl.fileKey">
      <!-- ngSwitchWhen: true --><div ng-switch-when="true" layout="row" class="ng-scope layout-row">
        <button class="md-raised md-primary md-button md-ink-ripple" type="button" ng-transclude="" ng-click="ctrl.onUploadClick($event)" ng-disabled="!ctrl.ready || ctrl.fileName" aria-label="Upload">Upload file</button>
        <input class="hcj-upload-input ng-pristine ng-untouched ng-valid md-input ng-empty" ng-model="ctrl.fileValue" aria-label="Input file" id="input_3" aria-invalid="false" type="file"><div class="md-errors-spacer"></div>
        <div class="hcj-upload-filedrag layout-align-center-center layout-row" layout="row" ng-show="!ctrl.fileName" layout-align="center center" drag-drop="" on-drag="ctrl.onDragOver($event, $enter)" on-drop="ctrl.onDrop($event)" aria-hidden="false">
          or drop file here
        </div>
        <div class="hcj-upload-loading ng-hide layout-align-center-center layout-row" layout="row" ng-show="ctrl.fileName" layout-align="center center" aria-hidden="true">
          Uploading file. Please wait.
        </div>
      </div><!-- end ngSwitchWhen: -->
      <!-- ngSwitchWhen: false -->
    </div>
  </md-input-container>
</div>
</judge-upload>

使用 selenium,我尝试了各种解决方案来上传文件,但都不起作用:

driver.find_element_by_id("input_3").send_keys(PATH)
driver.execute_script('document.getElementById("input_4").setAttribute("value",PATH)')

在第二个之后,html 似乎更新了文件路径,但它没有在网络浏览器中显示。

你能帮我解决这个问题吗?

谢谢!

----- 编辑 ------ 当我使用第二种方法发送文件时,我遇到的问题是提交按钮仍然被禁用。按钮的代码看起来像

&lt;button class="md-primary md-button md-ink-ripple" type="button" ng-transclude="" ng-click="submissionsCtrl.createSubmission()" ng-disabled="!submissionsCtrl.canUploadSubmissions()" disabled="disabled"&gt;Submit&lt;/button&gt;

我尝试通过 Python 代码启用它,但目前还没有工作,如果您有任何想法,仍在努力。

driver.execute_script('document.getElementsByClassName("md-primary md-button md-ink-ripple")[0].disabled=false')
driver.find_elements_by_xpath("//*[@ng-click='submissionsCtrl.createSubmission()']")[0].click()
print driver.find_elements_by_xpath("//*[@ng-click='submissionsCtrl.createSubmission()']")[0].is_enabled()

即使在脚本调用之后,is_enabled 的输出仍然显示为 False,并且单击按钮什么也不做。

----- 编辑 2 ------ 我终于成功启用按钮并单击它。不幸的是,看起来这些文件并没有真正由表单发送。

我仍在调查文件未发送的原因。

我用来启用按钮的代码:

driver.execute_script('''document.evaluate("//*[@ng-click='submissionsCtrl.createSubmission()']", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.disabled=false''')
driver.find_elements_by_xpath("//*[@ng-click='submissionsCtrl.createSubmission()']")[0].click()

【问题讨论】:

  • 您尝试使用execute_script 是在寻找input_4 而不是input_3?有什么方法可以提供指向实际网站的链接以供查看?
  • 感谢您的回答。只是因为它们是几个输入,我想同时测试它们。该网页位于hashcodejudge.withgoogle.com,但遗憾的是,如果不注册比赛,您将无法看到它。
  • execute_script 将路径放入之后,即使浏览器未在字段中显示文本,您是否尝试上传文件?
  • 如果你想测试 UI 上传功能,这是一个很好的用例。如果您只想上传文件或测试是否可以将文件上传到端点,我建议您使用请求或 urllib 库使用 HTTP 请求上传文件。更快。
  • @PixelEinstein 感谢您的回答。我试过了,但由于文件未加载,该按钮被禁用。我尝试手动启用该按钮,但尚未成功。我将在原帖中添加相应的代码。

标签: python html selenium


【解决方案1】:

因为你的页面是AngularJs页面,所以文件输入绑定到模型ng-model="ctrl.fileValue"

即使你使用execute_script在后台设置值,但这种方式不会触发模型fileValue的变化。

我猜UPLOAD FILE按钮的点击事件ng-click="ctrl.onUploadClick($event)"会从模型fileValue获取文件路径,而不是从document.getElementById("input_3").value获取文件路径。

所以即使没有错误报告,你也不应该成功上传文件。

要解决您的问题,唯一的方法是直接更改模型fileValue 的值:

def input_upload_file_path(file_control, file_path):
    script = '''
       angular.element(arguments[0]).scope().$apply('fileValue=arguments[1]')
    '''
    driver.execute_script(script, file_control, file_path)

file_control = driver.find_element_by_css_selector('#input_3')
file_path = <absolute path of file>

input_upload_file_path(file_control, file_path)

执行input_upload_file_path()后,在此处添加一个暂停,然后您可以通过在浏览器开发工具的控制台选项卡中执行以下Javascript来检查功能是否正常:

angular.element('#input_3').scope().$eval('fileValue')

应该打印与input_upload_file_path()的参数值相同的文件路径

【讨论】:

  • 非常感谢您的回答。我试过这个,但我认为它没有做任何事情,文件没有上传到输入中并且在控制台中运行 JS 脚本给了我一个错误:未捕获的错误:[jqLit​​e:nosel]errors.angularjs.org/1.6.4-local+sha.617b36117/jqLite/nosel 在第三方。 js:42 在 Object.X [作为元素] (third_party.js:64) 在 :1:9
猜你喜欢
  • 1970-01-01
  • 2016-12-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-19
  • 2013-10-05
  • 2013-02-12
  • 2015-08-14
  • 2011-12-06
相关资源
最近更新 更多