如何使用帖子请求填写表格并获得回复

Moh*_*hit 2 python python-requests

我有一个像下面这样的表格:

url = "http:/foo.com"
<table>
    <form action="showtree.jsp" method="post" id="form" name="form">
        <input type="hidden" id="sortAction" name="sortAction" value="">
        <tr>
            <td style="text-align: right;font-weight:bold;">State:&thinsp;</td>
            <td><select name="state">
                <option value="ca">CA</option>
                <option value="or">OR</option>
                <option value="al">AL</option>

                </select></td>
        </tr>
        <tr>
            <td style="text-align: right;font-weight:bold;">Populartion:&thinsp;</td>
            <td><select id="pop" name="population" onchange="disableShowOnAll()">
                <option value="100">100</option>
                <option value="200">200</option>
                <option value="300">300</option>


                </select></td>
        </tr>
        <tr>
            <td></td>
            <td>
                <button id="showbutton" class="btn btn-default" onclick="submitForm('show')">Show Tree
                </button>
            </td>
        </tr>
    </form>
Run Code Online (Sandbox Code Playgroud)

所以,基本上表单有两个选项,State 和 Population,每个选项都有一些选项。这个想法是从表单中选择选项然后提交。

提交时,结果显示在同一页面中..

所以,基本上我如何在 python 中提交这个帖子请求......然后得到结果(当按下提交时......并且页面用结果刷新?)让我知道这是否有意义?谢谢

jon*_*anl 5

你正在试图做的是提交POST给请求http://example.com/showtree.jsp

使用requests库(推荐)

参考:http : //docs.python-requests.org/en/master/

requests库极大地简化了发出 HTTP 请求,但它是一个额外的依赖项

import requests

# Create a dictionary containing the form elements and their values
data = {"state": "ca", "population": 100}

# POST to the remote endpoint. The Requests library will encode the
# data automatically
r = requests.post("http://example.com/showtree.js", data=data)

# Get the raw body text back
body_data = r.text
Run Code Online (Sandbox Code Playgroud)

使用内置 urllib

相关答案:Python - make a POST request using Python 3 urllib

from urllib import request, parse

# Create a dictionary containing the form elements and their values
data = {"state": "ca", "population": 100}

# This encodes the data to application/x-www-form-urlencoded format
# then converts it to bytes, needed before using with request.Request
encoded_data = parse.urlencode(data).encode()

# POST to the remote endpoint
req =  request.Request("http://example.com/showtree.js", data=encoded_data)

# This will contain the response page
with request.urlopen(req) as resp:
    # Reads and decodes the body response data
    # Note: You will need to specify the correct response encoding
    #       if it is not utf-8
    body_data = resp.read().decode('utf-8')
Run Code Online (Sandbox Code Playgroud)

编辑:附录

根据 tmadam 的评论添加,如下

上面的示例是POST向大多数 URI 端点(例如 API 或基本网页)提交请求的简化方式。

但是,有一些常见的并发症:

1)有CSRF令牌

...或其他隐藏字段

隐藏字段仍将显示在 a 的源代码中<form>(例如<input type="hidden" name="foo" value="bar">

如果隐藏字段在每次表单加载时都保持相同的值,那么只需将其包含在您的标准数据字典中,即

data = {
    ...
    "foo": "bar",
    ...
}
Run Code Online (Sandbox Code Playgroud)

如果隐藏字段页面加载,例如CSRF令牌之间改变,你必须加载表单的页面第一(例如,使用GET要求),解析响应,以获取表单元素的值,然后将其包含在您的数据字典

2) 该页面需要您登录

...或其他一些需要 cookie 的情况。

您最好的方法是发出一系列请求,在您通常使用目标页面之前完成所需的步骤(例如,向POST登录表单提交请求)

您将需要使用“cookie jar”。在这一点上,我真的开始推荐requests图书馆了;您可以在此处阅读有关 cookie 处理的更多信息

3) 需要在目标表单上运行 Javascript

有时,表单需要在提交之前运行 Javascript。

如果你不幸拥有这样的表单,不幸的是我建议你不要再使用 python,并切换到某种无头浏览器,比如 PhantomJS

(可以使用像 Selenium 这样的库从 Python 控制 PhantomJS;但对于简单的项目,直接使用 PhantomJS 可能更容易)