Python 2&;3:urllib和;请求POST数据神秘消失

Python 2&;3:urllib和;请求POST数据神秘消失,python,post,urllib2,form-submit,python-requests,Python,Post,Urllib2,Form Submit,Python Requests,我正在使用Python从许多具有简单HTML输入表单的网页中提取数据,如页面底部的“Username:”表单: (这只是一个简单的例子来说明问题) Firefox Inspect元素表示此表单字段具有以下HTML结构: <form name="input0" target="_blank" action="html_form_action.asp" method="get"> Username: <input name="user" size="20" type="text"

我正在使用Python从许多具有简单HTML输入表单的网页中提取数据,如页面底部的“Username:”表单:

(这只是一个简单的例子来说明问题)

Firefox Inspect元素表示此表单字段具有以下HTML结构:

<form name="input0" target="_blank" action="html_form_action.asp" method="get">
Username: 
<input name="user" size="20" type="text"></input>
<input value="Submit" type="submit"></input>
</form>
但是返回给我并保存在“my_html_file.html”中的是包含 未更改的表单,没有任何迹象表明我的表单数据已被识别,即我得到此页面作为响应:qqqhttp://www.w3schools.com/html/html_forms.asp

…如果我在没有得到批准的情况下提出这个请求,我也会想到这一点 数据参数(将请求从POST更改为GET)

当然,我做的第一件事就是检查我的请求是否正确构建:

# Just double-checking the request is set up correctly
print("GET or POST?", request.get_method())
print("DATA:", request.data)
print("HEADERS:", request.header_items())
将生成以下输出:

得到还是邮寄?职位

数据:b'user=thismyusername'

标题:[('Content-length','21'),('Content-type','application/x-www-form-urlencoded'),('User-agent','Python-urllib/3.3'),('Host','www.w3schools.com')]

因此,POST请求的结构似乎是正确的。在重新阅读 文档和在web上搜索此问题的答案失败,我 转到另一个工具:请求模块。我尝试执行相同的任务:

import requests

example_url = 'http://www.w3schools.com/html/html_forms.asp'
data_to_send = {'user': 'ThisIsMyUserName'}
response = requests.post(example_url, params=data_to_send)
contents = response.content
我得到了同样精确的结果。在这一点上,我想这可能是一个Python 3 问题因此,我启动了可靠的Python 2.7并尝试以下操作:

import urllib, urllib2

data = urllib.urlencode({'user' : 'ThisIsMyUserName'})
resp = urllib2.urlopen('http://www.w3schools.com/html/html_forms.asp', data)
content = resp.read()
我又得到了同样的结果!为了彻底,我想我会努力达到目标 通过将字典值编码到url并尝试GET请求,可以获得相同的结果:

# Using Python 3

# Construct the url for the GET request
example_url = 'http://www.w3schools.com/html/html_forms.asp'
form_values = {'user': 'ThisIsMyUserName'}
example_data = urllib.parse.urlencode(form_values)
final_url = example_url + '?' + example_data
print(final_url)
这将为最终url输出以下值:

qqqhttp://www.w3schools.com/html/html_forms.asp?user=ThisIsMyUserName

我把它插入我的浏览器,我看到这个页面与 原始页面,这正是我的程序正在下载的内容

我还尝试添加额外的头文件和cookie支持,但没有效果


我已经尝试了我能想到的一切。知道会出什么问题吗?

表单说明了一个操作和一个方法;你忽视了两者。该方法说明表单使用的是
GET
,而不是
POST
,操作告诉您将表单数据发送到
html\u form\u action.asp

action
属性的作用类似于HTML页面中的任何其他URL说明符;除非它是从一个方案开始的(比如
http://...
https://...
等)它是相对于页面的当前基本URL的

GET
HTTP方法使用问号将URL编码的表单参数添加到目标URL:

import urllib.request 
import urllib.parse

# Create dict of form values
example_data = urllib.parse.urlencode({'user': 'ThisIsMyUserName'})

# Create request
example_url = 'http://www.w3schools.com/html/html_form_action.asp'
get_url = example_url + '?' + example_data

# Open the page and read content
web_page = urllib.request.urlopen(get_url)
print(web_page.read().decode(web_page.info().get_param('charset', 'utf8')))
或者,使用
请求

import requests

example_url = 'http://www.w3schools.com/html/html_form_action.asp'
data_to_send = {'user': 'ThisIsMyUserName'}
response = requests.get(example_url, params=data_to_send)
contents = response.text
print(contents)

在这两个示例中,我还对Unicode文本的响应进行了解码(一些
请求
使得使用
response.text
属性对我来说更容易);你忽视了两者。该方法说明表单使用的是
GET
,而不是
POST
,操作告诉您将表单数据发送到
html\u form\u action.asp

action
属性的作用类似于HTML页面中的任何其他URL说明符;除非它是从一个方案开始的(比如
http://...
https://...
等)它是相对于页面的当前基本URL的

GET
HTTP方法使用问号将URL编码的表单参数添加到目标URL:

import urllib.request 
import urllib.parse

# Create dict of form values
example_data = urllib.parse.urlencode({'user': 'ThisIsMyUserName'})

# Create request
example_url = 'http://www.w3schools.com/html/html_form_action.asp'
get_url = example_url + '?' + example_data

# Open the page and read content
web_page = urllib.request.urlopen(get_url)
print(web_page.read().decode(web_page.info().get_param('charset', 'utf8')))
或者,使用
请求

import requests

example_url = 'http://www.w3schools.com/html/html_form_action.asp'
data_to_send = {'user': 'ThisIsMyUserName'}
response = requests.get(example_url, params=data_to_send)
contents = response.text
print(contents)

在这两个示例中,我还对Unicode文本的响应进行了解码(一些
请求
使得使用
response.text
属性对我来说更容易);你忽视了两者。该方法说明表单使用的是
GET
,而不是
POST
,操作告诉您将表单数据发送到
html\u form\u action.asp

action
属性的作用类似于HTML页面中的任何其他URL说明符;除非它是从一个方案开始的(比如
http://...
https://...
等)它是相对于页面的当前基本URL的

GET
HTTP方法使用问号将URL编码的表单参数添加到目标URL:

import urllib.request 
import urllib.parse

# Create dict of form values
example_data = urllib.parse.urlencode({'user': 'ThisIsMyUserName'})

# Create request
example_url = 'http://www.w3schools.com/html/html_form_action.asp'
get_url = example_url + '?' + example_data

# Open the page and read content
web_page = urllib.request.urlopen(get_url)
print(web_page.read().decode(web_page.info().get_param('charset', 'utf8')))
或者,使用
请求

import requests

example_url = 'http://www.w3schools.com/html/html_form_action.asp'
data_to_send = {'user': 'ThisIsMyUserName'}
response = requests.get(example_url, params=data_to_send)
contents = response.text
print(contents)

在这两个示例中,我还对Unicode文本的响应进行了解码(一些
请求
使得使用
response.text
属性对我来说更容易);你忽视了两者。该方法说明表单使用的是
GET
,而不是
POST
,操作告诉您将表单数据发送到
html\u form\u action.asp

action
属性的作用类似于HTML页面中的任何其他URL说明符;除非它是从一个方案开始的(比如
http://...
https://...
等)它是相对于页面的当前基本URL的

GET
HTTP方法使用问号将URL编码的表单参数添加到目标URL:

import urllib.request 
import urllib.parse

# Create dict of form values
example_data = urllib.parse.urlencode({'user': 'ThisIsMyUserName'})

# Create request
example_url = 'http://www.w3schools.com/html/html_form_action.asp'
get_url = example_url + '?' + example_data

# Open the page and read content
web_page = urllib.request.urlopen(get_url)
print(web_page.read().decode(web_page.info().get_param('charset', 'utf8')))
或者,使用
请求

import requests

example_url = 'http://www.w3schools.com/html/html_form_action.asp'
data_to_send = {'user': 'ThisIsMyUserName'}
response = requests.get(example_url, params=data_to_send)
contents = response.text
print(contents)

在这两个示例中,我还对Unicode文本的响应进行了解码(使用
response.text
属性,
requests
使我更容易理解)。

Martijn,感谢您的快速响应。现在有道理了!快速跟进:在html表单中遇到“action=any.value”时,解决方案是否总是简单地将GET url的最后一段替换为“any.value”?如何处理需要POST方法的表单,该方法还指定了一个操作?该操作应该像HTML中的任何URL一样处理;如果不是绝对的(从方案开始,所以
http://...
https://...
则它是相对于当前基本URL的。这与
上指定的其他配置无关