我正在使用Python从许多具有简单HTML输入表单的网页中抓取数据,例如本页底部的“用户名:”表单:
http://www.w3schools.com/html/html_forms.asp(这只是一个简单的例子来说明问题)
Firefox Inspect Element表示此表单字段具有以下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>
我想要做的就是填写此表单并获取结果页面:
http://www.w3schools.com/html/html_form_action.asp?user=ThisIsMyUserName
通过在“用户名”字段中输入“ThisIsMyUserName”并按“提交”,我的浏览器会生成这些内容。但是,我尝试的每个方法(详情如下)都会返回包含未更改形式的原始页面的内容,而没有任何迹象表明我提交的表单数据已被识别,即我从上面的第一个链接获取内容以响应我的请求,当我希望收到第二个链接的内容时。
我怀疑问题与上面表格中的action="html_form_action.asp"
有关,或者是某些我遗漏的隐藏字段(我不知道该寻找什么 - 我是新来的表单提交)。有什么建议吗?
在Python 3中使用urllib.requests:
import urllib.request
import urllib.parse
# Create dict of form values
example_data = urllib.parse.urlencode({'user': 'ThisIsMyUserName'})
# Encode dict
example_data = example_data.encode('utf-8')
# Create request
example_url = 'http://www.w3schools.com/html/html_forms.asp'
request = urllib.request.Request(example_url, data=example_data)
# Create opener and install
my_url_opener = urllib.request.build_opener() # no handlers
urllib.request.install_opener(my_url_opener)
# Open the page and read content
web_page = urllib.request.urlopen(request)
content = web_page.read()
# Save content to file
my_html_file = open('my_html_file.html', 'wb')
my_html_file.write(content)
但是返回给我并保存在'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())
产生以下输出:
GET或POST? POST
DATA:b'user = ThisIsMyUserName'
HEADERS:[('Content-length','21'),('Content-type','application / x-www-form-urlencoded'),('User-agent','Python-urllib / 3.3'),('主持人','www.w3schools.com')]
所以看来POST请求的结构是正确的。重新阅读之后 我没有文档,也没有成功地在网上搜索这个问题的答案 转到另一个工具:请求模块。我试图执行相同的任务:
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)
这会为final_url吐出以下值:
qqqhttp://www.w3schools.com/html/html_forms.asp用户= ThisIsMyUserName
我将它插入我的浏览器,我看到这个页面完全相同 原始页面,这正是我的程序正在下载的内容。
我还尝试添加额外的标头和Cookie支持无济于事。
我已经尝试了我能想到的一切。知道会出现什么问题吗?
答案 0 :(得分:3)
表格陈述行动和方法;你忽略了两者。该方法声明表单使用的是GET
,而不是POST
,操作会告诉您将表单数据发送到html_form_action.asp
。
action
属性的行为与HTML页面中的任何其他URL说明符相同;除非它以方案开头(因此使用http://...
,https://...
等),它相对于页面的当前基本URL。
GET
HTTP方法将带网址编码的表单参数添加到目标网址,并带有问号:
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')))
或使用requests
:
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文本的响应(使用requests
属性,response.text
使{{1}}更容易。