【问题标题】:Sending POST request on an already open url in python在 python 中已打开的 url 上发送 POST 请求
【发布时间】:2016-05-25 01:00:36
【问题描述】:

基本上我想发送以下表单的 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()

【问题讨论】:

    标签: python forms http-post


    【解决方案1】:

    是的,最后一个链接真的很有帮助,结果我只需要从这样的请求中创建一个新会话:

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

    并将其添加为 post 请求之后

    res2 = s.post(url, data=post_params)
    

    我相信这样就达到了将 cookie 从 get 请求中存储起来并与 post 请求一起发送的结果,从而保持与之前的 get 请求相同的问题。非常感谢您在这个问题 Loknar 上的帮助和帮助。

    【讨论】:

    • 嘿,谢谢,这正是我想要的,它就像魅力一样工作。我相信这是问题的准确答案。
    【解决方案2】:

    我有点困惑,POST 请求将始终是一个新的单独请求,所以我不明白您所说的“不打开新的 URL 实例”是什么意思……您是否尝试过看看会发生什么当您在此脚本中手动执行您想要执行的操作时?就像在 Chrome 中打开开发者控制台一样,转到网络选项卡,将保留日志切换为开启,删除历史记录,然后手动执行您想要执行的操作?然后在python中复制它?另外我建议你试试 requests 模块,它比使用 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?
    

    编辑:

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

    【讨论】:

    • 在网络浏览器中手动执行的问题是表单需要机器驱动的响应才能正确验证,因为它有超时并且在尝试手动执行时无法验证,因为人类无法足够快地给出正确答案。
    • 我尝试按照您的建议使用请求,但遇到了同样的问题。我相信您在上面提供的代码中使用 res2,它确实会启动一个新的单独请求(这反过来会改变问题,因此使我之前存储的 res1 中问题的答案错误)
    • 这可能是标题问题还是 cookie 问题? POST 请求是与前一个 GET 请求分开的请求,不能合并为一个请求。您应该检查标题和/或尝试使用会话(如果使用请求,则易于添加,docs.python-requests.org/en/master/user/advanced)。
    猜你喜欢
    • 1970-01-01
    • 2013-04-20
    • 1970-01-01
    • 2011-06-10
    • 2017-11-17
    • 1970-01-01
    • 2017-02-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多