使用 python-requests 实施 challenge/response 方案
Implementing challenge/response scheme with python-requests
我开始学习如何使用 python 请求模块。为了练习,我尝试解决一个 challenge/response 问题:我想访问 http://lema.rae.es/drae/srv/search?val=hacer
上的数据
使用 Firefox 的 "Tamper Data" 插件,我检查了必要的 HTTP 请求:
GET http://lema.rae.es/drae/srv/search?val=hacer
POST http://lema.rae.es/drae/srv/search?val=hacer
我复制了 Firefox 在两个 HTTP 请求中发送的确切 headers,并在 Python 中实现了 JavaScript "challenge" 功能。然后我正在做以下事情:
url = "http://lema.rae.es/drae/srv/search?val=hacer"
headers = { ... }
r1 = requests.get(url=url, headers=headers)
html = r1.content.decode("utf-8")
formdata = challenge(html)
headers = { ... }
r2 = requests.post(url=url, data=formdata, headers=headers)
不幸的是,服务器不会以预期的方式回答。我检查了我通过 "r.request.headers" 发送的所有 headers,它们与 firefox 发送的 headers 完全一致(根据 Tamper Data)
我做错了什么?
你可以在这里查看我的完整代码:http://pastebin.com/7JAZ9B4s
这是响应 header 我应该得到:
Date[Tue, 10 Feb 2015 17:13:53 GMT]
Vary[Accept-Encoding]
Content-Encoding[gzip]
Cache-Control[max-age=0, no-cache]
Keep-Alive[timeout=5, max=100]
Connection[Keep-Alive]
Content-Type[text/html; charset=UTF-8]
Set-Cookie[TS014dfc77=017ccc203c29467c4d9b347fb56ea0e89a7182e52b9d7b4a1174efbf134768569a005c7c85; Path=/]
Transfer-Encoding[chunked]
这是回应 header 我真的得到:
Content-Length[5798]
Content-Type[text/html]
Pragma[no-cache]
Cache-Control[no-cache]
我找到了我的代码不起作用的原因:
服务器期望 POSTDATA 的顺序与条目作为表单输入元素出现的顺序完全相同。在我的代码中,输入元素的值存储在 python 字典中。但是这种数据类型不保留声明值的顺序!
ruby 脚本(在评论中提到)确实有效,因为 ruby dict 数据类型似乎保留了声明的顺序!
此外,根本没有必要在 python 中重新实现 javascript challenge() 函数,因为服务器很乐意反复接受任何响应字符串(过去有效)再来一遍!
我开始学习如何使用 python 请求模块。为了练习,我尝试解决一个 challenge/response 问题:我想访问 http://lema.rae.es/drae/srv/search?val=hacer
上的数据使用 Firefox 的 "Tamper Data" 插件,我检查了必要的 HTTP 请求:
GET http://lema.rae.es/drae/srv/search?val=hacer
POST http://lema.rae.es/drae/srv/search?val=hacer
我复制了 Firefox 在两个 HTTP 请求中发送的确切 headers,并在 Python 中实现了 JavaScript "challenge" 功能。然后我正在做以下事情:
url = "http://lema.rae.es/drae/srv/search?val=hacer"
headers = { ... }
r1 = requests.get(url=url, headers=headers)
html = r1.content.decode("utf-8")
formdata = challenge(html)
headers = { ... }
r2 = requests.post(url=url, data=formdata, headers=headers)
不幸的是,服务器不会以预期的方式回答。我检查了我通过 "r.request.headers" 发送的所有 headers,它们与 firefox 发送的 headers 完全一致(根据 Tamper Data)
我做错了什么?
你可以在这里查看我的完整代码:http://pastebin.com/7JAZ9B4s
这是响应 header 我应该得到:
Date[Tue, 10 Feb 2015 17:13:53 GMT]
Vary[Accept-Encoding]
Content-Encoding[gzip]
Cache-Control[max-age=0, no-cache]
Keep-Alive[timeout=5, max=100]
Connection[Keep-Alive]
Content-Type[text/html; charset=UTF-8]
Set-Cookie[TS014dfc77=017ccc203c29467c4d9b347fb56ea0e89a7182e52b9d7b4a1174efbf134768569a005c7c85; Path=/]
Transfer-Encoding[chunked]
这是回应 header 我真的得到:
Content-Length[5798]
Content-Type[text/html]
Pragma[no-cache]
Cache-Control[no-cache]
我找到了我的代码不起作用的原因:
服务器期望 POSTDATA 的顺序与条目作为表单输入元素出现的顺序完全相同。在我的代码中,输入元素的值存储在 python 字典中。但是这种数据类型不保留声明值的顺序!
ruby 脚本(在评论中提到)确实有效,因为 ruby dict 数据类型似乎保留了声明的顺序!
此外,根本没有必要在 python 中重新实现 javascript challenge() 函数,因为服务器很乐意反复接受任何响应字符串(过去有效)再来一遍!