javascript - 如何将文件发布到多部分/表单数据?

标签 javascript python html post multipartform-data

我想将文件上传并提交到 http://www.broadinstitute.org/cmap/newQuery?servletAction=querySetup&queryType=quick 上的表单(需要登录)。表格如下所示

<form name="form1" enctype="multipart/form-data" method="post" action="newQuery">
    <input type="hidden" name="servletAction" value="quickQuery">
        <div class="formTable">
            <div class="row">
                <span class="label" style="width: 100px;">up tag file:</span>
                <span class="field"><input type="file" name="ups" size="30" accept="grp"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font size="-1"><a href="#" onClick="window.open('help_topics_frames.jsp?topic=tag list', 'helpTopicsWindow', 'scrollbars,resizable,height=600,width=700')">tag file help</a></font></span>
            </div>
            <div class="row">
                <span class="label" style="width: 100px;">down tag file:</span>
                <span class="field"><input type="file" name="dns" size="30" accept="grp"></span>
            </div>
            <div class="row">
                <span class="label" style="width: 100px;">&nbsp;</span>
                <span class="navigation"><input type="button" onClick="submitForm()" name="submitButton" value="execute query"></span>
            </div>
        </div>
</form>

首先,来自答案https://stackoverflow.com/a/22547541/651779我获取带有登录凭据的 cookie

import http.cookiejar
import urllib
from bs4 import BeautifulSoup
import requests

submit_signature_url = 'http://www.broadinstitute.org/cmap/newQuery?servletAction=querySetup&queryType=quick'
login_url = 'http://www.broadinstitute.org/cmap/j_security_check'

login_values = urllib.parse.urlencode({'j_username': 'example',
                                       'j_password': 'example', 
                                       'submit': 'sign in'})

payload_submit_signature = bytes(login_values, 'ascii')

cj = http.cookiejar.CookieJar()
opener = urllib.request.build_opener(
    urllib.request.HTTPRedirectHandler(),
    urllib.request.HTTPHandler(debuglevel=0),
    urllib.request.HTTPSHandler(debuglevel=0),
    urllib.request.HTTPCookieProcessor(cj))

resp_1 = opener.open(submit_signature_url) #First call to capture the JSESSIONID
resp = opener.open(login_url, payload_submit_signature)

这可以正常工作。现在我想将文件发布到表单中。我尝试使用这个答案 https://stackoverflow.com/a/12385661/651779

# changed after Brett Lempereur's answer
values = {'ups':open(r'path\to\up.grp','rb'),
          'dns':open(r'path\to\down.grp','rb')}

submit_signature_url = 'http://www.broadinstitute.org/cmap/newQuery?servletAction=querySetup&queryType=quick'
req = requests.post(submit_signature_url, files=values, cookies=cj)
soup = BeautifulSoup(req.text)
print(soup.prettify())

这会打印

Requested URL:  http://www.broadinstitute.org/cmap/newQuery
java.lang.NullPointerException

如果您已登录并转到 http://www.broadinstitute.org/cmap/newQuery在你的浏览器中你会得到同样的结果。如果我在 requests.post 中使用 data 而不是 files: req = requests.post(submit_signature_url, data=values, cookies=cj),它打印包含表单的页面的html,因此它没有发布表单。

如何发布到 multipart/form-data?

<小时/>

对于示例 up-file,将以下内容复制到文件中并将其命名为 up.grp

205258_at
221369_at
205751_at
212954_at
219914_at
206703_at
207352_s_at
203548_s_at
203549_s_at
210382_at
212110_at
213805_at
213935_at
218739_at
219737_s_at
219738_s_at
204131_s_at
204132_s_at
210655_s_at
217399_s_at
206791_s_at
206792_x_at
211818_s_at
221523_s_at
221524_s_at

对于示例 down 文件,将以下内容复制到文件中并将其命名为 down.grp

204725_s_at
211063_s_at
219921_s_at
200618_at
219701_at
220342_x_at
220926_s_at
201323_at
204692_at
221956_at
222017_x_at
90610_at
217755_at
207843_x_at
209366_x_at
215726_s_at
201827_at
201185_at
212411_at
201692_at
214484_s_at
202910_s_at
202381_at
200663_at
201459_at
219770_at
220853_at
201349_at
207015_s_at
207016_s_at
212338_at
220330_s_at

最佳答案

大胆猜测一下,当前版本的请求模块期望其参数具有以下格式之一:

files = {"name": file-handle, ...}
files = {"name": (file-name, file-handle, content-type,), ...}

您是否尝试过将文件字典的创建替换为以下内容:

values = {'ups': open(r'path\to\up.grp', 'rb'), 'dns': open(r'path\to\down.grp', 'rb')}

您的代码在技术上是正确的,但在语义上并不正确,因为一些文件数据将被发送到站点,但它实际上是字符串文字 r'path\to\up.grp 的内容'.

在阅读表单时,您还应该将字典 {"servletAction": "quickQuery"} 作为数据参数传递给 requests.post 调用。此外,您发布到的 URL 应为 http://www.broadinstitute.org/cmap/newQuery,其中不包含您在原始代码中使用的当前查询字符串。

关于javascript - 如何将文件发布到多部分/表单数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22613814/

相关文章:

javascript - 在 wordpress 中使用 codepen 示例不起作用

javascript - 如何获取脚本标签的 innerHTML

python - 使用 Python 将日期和时间字符串组合到单个日期时间对象的最简单方法

html - 如何在一行中添加“To”标签和输入(HTML)

html - 将图像分成不同的部分

javascript - 如何设置电话号码、邮政编码等的格式而不显示掩码?

java - 最好的 RESTful JavaScript API 是什么?

python - jupyter lab 中的缩进自动换行是否可行?

python - 临时对象的内存消耗和生命周期

html - 调整导航栏+页脚大小时出现故障