Python 发出 HTTP POST 请求

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3659595/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 12:08:12  来源:igfitidea点击:

Making HTTP POST request

pythonhttpposturllib

提问by infrared

I'm trying to make a POST request to retrieve information about a book. Here is the code that returns HTTP code: 302, Moved

我正在尝试发出 POST 请求以检索有关一本书的信息。这是返回 HTTP 代码的代码:302, Moved

import httplib, urllib
params = urllib.urlencode({
    'isbn' : '9780131185838',
    'catalogId' : '10001',
    'schoolStoreId' : '15828',
    'search' : 'Search'
    })
headers = {"Content-type": "application/x-www-form-urlencoded",
           "Accept": "text/plain"}
conn = httplib.HTTPConnection("bkstr.com:80")
conn.request("POST", "/webapp/wcs/stores/servlet/BuybackSearch",
             params, headers)
response = conn.getresponse()
print response.status, response.reason
data = response.read()
conn.close()

When I try from a browser, from this page: http://www.bkstr.com/webapp/wcs/stores/servlet/BuybackMaterialsView?langId=-1&catalogId=10001&storeId=10051&schoolStoreId=15828, it works. What am I missing in my code?

当我从浏览器尝试,从这个页面:http://www.bkstr.com/webapp/wcs/stores/servlet/BuybackMaterialsView?langId=-1&catalogId=10001&storeId=10051&schoolStoreId=15828,它工作。我的代码中缺少什么?

EDIT: Here's what I get when I call print response.msg

编辑:这是我调用 print response.msg 时得到的结果

302 Moved Date: Tue, 07 Sep 2010 16:54:29 GMT
Vary: Host,Accept-Encoding,User-Agent
Location: http://www.bkstr.com/webapp/wcs/stores/servlet/BuybackSearch
X-UA-Compatible: IE=EmulateIE7
Content-Length: 0
Content-Type: text/plain; charset=utf-8

Seems that the location points to the same url I'm trying to access in the first place?

似乎该位置指向我首先尝试访问的同一个网址?

EDIT2:

编辑2:

I've tried using urllib2 as suggested here. Here is the code:

我已经尝试按照此处的建议使用 urllib2。这是代码:

import urllib, urllib2

url = 'http://www.bkstr.com/webapp/wcs/stores/servlet/BuybackSearch'
values = {'isbn' : '9780131185838',
          'catalogId' : '10001',
          'schoolStoreId' : '15828',
          'search' : 'Search' }


data = urllib.urlencode(values)
req = urllib2.Request(url, data)
response = urllib2.urlopen(req)
print response.geturl()
print response.info()
the_page = response.read()
print the_page

And here is the output:

这是输出:

http://www.bkstr.com/webapp/wcs/stores/servlet/BuybackSearch
Date: Tue, 07 Sep 2010 16:58:35 GMT
Pragma: No-cache
Cache-Control: no-cache
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Set-Cookie: JSESSIONID=0001REjqgX2axkzlR6SvIJlgJkt:1311s25dm; Path=/
Vary: Accept-Encoding,User-Agent
X-UA-Compatible: IE=EmulateIE7
Content-Length: 0
Connection: close
Content-Type: text/html; charset=utf-8
Content-Language: en-US
Set-Cookie: TSde3575=225ec58bcb0fdddfad7332c2816f1f152224db2f71e1b0474c866f3b; Path=/

采纳答案by ars

Their server seems to want you to acquire the proper cookie. This works:

他们的服务器似乎希望您获取正确的 cookie。这有效:

import urllib, urllib2, cookielib

cookie_jar = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie_jar))
urllib2.install_opener(opener)

# acquire cookie
url_1 = 'http://www.bkstr.com/webapp/wcs/stores/servlet/BuybackMaterialsView?langId=-1&catalogId=10001&storeId=10051&schoolStoreId=15828'
req = urllib2.Request(url_1)
rsp = urllib2.urlopen(req)

# do POST
url_2 = 'http://www.bkstr.com/webapp/wcs/stores/servlet/BuybackSearch'
values = dict(isbn='9780131185838', schoolStoreId='15828', catalogId='10001')
data = urllib.urlencode(values)
req = urllib2.Request(url_2, data)
rsp = urllib2.urlopen(req)
content = rsp.read()

# print result
import re
pat = re.compile('Title:.*')
print pat.search(content).group()

# OUTPUT: Title:&nbsp;&nbsp;Statics & Strength of Materials for Arch (w/CD)<br />

回答by loevborg

  1. Perhaps that's what the browser gets, and you'll just have to follow the 302redirect.

  2. If all else fails, you can monitor the dialogue between Firefox and the Web Server using FireBug or tcpdump or wireshark, and see which HTTP headers are different. Possibly it's just the User Agent:header.

  1. 也许这就是浏览器所得到的,您只需要遵循302重定向即可。

  2. 如果一切都失败了,您可以使用 FireBug 或 tcpdump 或 wireshark 监视 Firefox 和 Web 服务器之间的对话,并查看哪些 HTTP 标头不同。可能只是User Agent:标题。

回答by Mark

You might want to use the urllib2module which should handle redirects better. Here's an example of POSTINGwith urllib2.

您可能想要使用应该更好地处理重定向urllib2模块。下面是一个例子POSTING用的urllib2。