正在 python 中对已打开的 url 发送 POST 请求

Sending POST request on an already open url in python

基本上我想发送 POST 请求以下表格。

<form method="post" action="">
449 * 803 - 433 * 406 = <input size=6 type="text" name="answer" />
<input type="submit" name="submitbtn" value="Submit" />
</form>

我基本上想做的是通读页面,找出表格中的方程式,计算答案,输入答案作为参数与 POST 请求一起发送,但不打开新的URL 对于页面,因为每次打开页面都会出现一个新的等式,因此之前获得的结果已过时。最后,我想获得发送 POST 请求后出现的页面。我被困在必须发送 POST 请求而不打开新的 URL 实例的部分。另外,我很感激在 POST 请求后如何再次阅读页面的帮助。 (调用 read() 就足够了吗?)

我目前的 python 代码看起来像这样。

import urllib, urllib2

link = "http://www.websitetoaccess.com"
f = urllib2.urlopen(link)

line = f.readline().strip()
equation = ''
result = ''
file1 = open ('firstPage.html' , 'w')
file2 = open ('FinalPage.html', 'w')

for line in f:
    if 'name="answer"' in line:
        result = getResult(line)
    file1.write(line)

file1.close()

raw_params = {'answer': str(result), 'submit': 'Submit'}
params = urllib.urlencode(raw_params)
request = urllib2.Request(link, params)
page = urllib2.urlopen(request)

file2.write(page.read())
file2.close()

我有点疑惑,POST 请求总是一个新的单独请求,所以我不明白你所说的“不打开新的 URL 实例”是什么意思.. . 你有没有试过看看当你手动做你想在这个脚本中做的事情时会发生什么?就像在 Chrome 中打开开发人员控制台一样,转到网络选项卡,将保留日志切换为开,删除历史记录,然后执行您要手动执行的操作?然后在 python 中复制它?我还建议您试用请求模块,它比使用 urllib 更简单。只需 pip install requests(和 pip install lxml)。

import requests
from lxml import etree

url = 'http://www.websitetoaccess.com'
res1 = requests.get(url)
# do something with res1.content
# you could try parsing the html page with lxml
root = etree.fromstring(res1.content, etree.HTMLParser())
# do something with root, find question and calc answer?
post_params = {'answer': str(42), 'submit': 'Submit'}
res2 = requests.post(url, data=post_params)
# check res2 for success or content?

编辑:

您可能遇到了一些 header 问题或 cookie 问题。您可能会收到一些 session ID,它使服务器能够确定您在上一个 GET 请求中收到的问题。 POST 请求是与前一个 GET 请求不同的请求,不能合并为一个请求。您应该检查从上一个 GET 请求 and/or 收到的 header 尝试设置 session/cookies 处理(如果使用请求很容易做到,请参阅 https://requests.readthedocs.io/en/master/user/advanced/)。

是的,最后一个 link 真的很有帮助,事实证明我只需要根据这样的请求创建一个新会话:

s = requests.session()
res1 = s.get(url)

并在

之后将其添加为 post 请求
res2 = s.post(url, data=post_params)

我相信这实现了存储 get 请求中的 cookie 并将它们与 post 请求一起发送的结果,从而保持与之前的 get 请求相同的问题。非常感谢您对这个问题 Loknar 的帮助和协助。