在python2和python3中,似乎存在不同之处,涉及到默认情况下启用哈希随机化,自python3.3以来,服务器需要至少将cgi字段放在最前面,以下代码可以复现:
good = requests.post('http://evds.tcmb.gov.tr/cgi-bin/famecgi', data=([
('cgi', '$ozetweb'),
('ARAVERIGRUP', 'bie_yymkpyuk.db'),
('DIL', 'UK'),
('ONDALIK', '5'),
('wfmultiple_selection', 'ZAMANSERILERI'),
('f_begdt', '07-01-2005'),
('f_enddt', '07-10-2016'),
('ZAMANSERILERI',
['TP.PYUK1', 'TP.PYUK2', 'TP.PYUK21', 'TP.PYUK22', 'TP.PYUK3', 'TP.PYUK4', 'TP.PYUK5', 'TP.PYUK6']),
('YON', '3'),
('SUBMITDEG', 'Report'),
('GRTYPE', '1'),
('EPOSTA', 'xxx'),
('RESIMPOSTA', '***')]))
bad = requests.post('http://evds.tcmb.gov.tr/cgi-bin/famecgi', data=([
('ARAVERIGRUP', 'bie_yymkpyuk.db'),
('cgi', '$ozetweb'),
('DIL', 'UK'),
('wfmultiple_selection', 'ZAMANSERILERI'),
('ONDALIK', '5'),
('f_begdt', '07-01-2005'),
('f_enddt', '07-10-2016'),
('ZAMANSERILERI',
['TP.PYUK1', 'TP.PYUK2', 'TP.PYUK21', 'TP.PYUK22', 'TP.PYUK3', 'TP.PYUK4', 'TP.PYUK5', 'TP.PYUK6']),
('YON', '3'),
('SUBMITDEG', 'Report'),
('GRTYPE', '1'),
('EPOSTA', 'xxx'),
('RESIMPOSTA', '***')]))
使用Python2运行上述代码:
In [6]: print(good.request.body)
...: print(bad.request.body)
...:
...: print(len(good.text), len(bad.text))
...:
cgi=%24ozetweb&ARAVERIGRUP=bie_yymkpyuk.db&DIL=UK&ONDALIK=5&wfmultiple_selection=ZAMANSERILERI&f_begdt=07-01-2005&f_enddt=07-10-2016&ZAMANSERILERI=TP.PYUK1&ZAMANSERILERI=TP.PYUK2&ZAMANSERILERI=TP.PYUK21&ZAMANSERILERI=TP.PYUK22&ZAMANSERILERI=TP.PYUK3&ZAMANSERILERI=TP.PYUK4&ZAMANSERILERI=TP.PYUK5&ZAMANSERILERI=TP.PYUK6&YON=3&SUBMITDEG=Report&GRTYPE=1&EPOSTA=xxx&RESIMPOSTA=%2A%2A%2A
ARAVERIGRUP=bie_yymkpyuk.db&cgi=%24ozetweb&DIL=UK&wfmultiple_selection=ZAMANSERILERI&ONDALIK=5&f_begdt=07-01-2005&f_enddt=07-10-2016&ZAMANSERILERI=TP.PYUK1&ZAMANSERILERI=TP.PYUK2&ZAMANSERILERI=TP.PYUK21&ZAMANSERILERI=TP.PYUK22&ZAMANSERILERI=TP.PYUK3&ZAMANSERILERI=TP.PYUK4&ZAMANSERILERI=TP.PYUK5&ZAMANSERILERI=TP.PYUK6&YON=3&SUBMITDEG=Report&GRTYPE=1&EPOSTA=xxx&RESIMPOSTA=%2A%2A%2A
(71299, 134)
还有 Python3:
In [4]: print(good.request.body)
...: print(bad.request.body)
...:
...: print(len(good.text), len(bad.text))
...:
cgi=%24ozetweb&ARAVERIGRUP=bie_yymkpyuk.db&DIL=UK&ONDALIK=5&wfmultiple_selection=ZAMANSERILERI&f_begdt=07-01-2005&f_enddt=07-10-2016&ZAMANSERILERI=TP.PYUK1&ZAMANSERILERI=TP.PYUK2&ZAMANSERILERI=TP.PYUK21&ZAMANSERILERI=TP.PYUK22&ZAMANSERILERI=TP.PYUK3&ZAMANSERILERI=TP.PYUK4&ZAMANSERILERI=TP.PYUK5&ZAMANSERILERI=TP.PYUK6&YON=3&SUBMITDEG=Report&GRTYPE=1&EPOSTA=xxx&RESIMPOSTA=%2A%2A%2A
ARAVERIGRUP=bie_yymkpyuk.db&cgi=%24ozetweb&DIL=UK&wfmultiple_selection=ZAMANSERILERI&ONDALIK=5&f_begdt=07-01-2005&f_enddt=07-10-2016&ZAMANSERILERI=TP.PYUK1&ZAMANSERILERI=TP.PYUK2&ZAMANSERILERI=TP.PYUK21&ZAMANSERILERI=TP.PYUK22&ZAMANSERILERI=TP.PYUK3&ZAMANSERILERI=TP.PYUK4&ZAMANSERILERI=TP.PYUK5&ZAMANSERILERI=TP.PYUK6&YON=3&SUBMITDEG=Report&GRTYPE=1&EPOSTA=xxx&RESIMPOSTA=%2A%2A%2A
71299 134
将您的字典作为Python2中发布的方式传递:
In [4]: response.request.body
Out[4]: 'cgi=%24ozetweb&DIL=UK&f_enddt=07-10-2016&YON=3&RESIMPOSTA=%2A%2A%2A&wfmultiple_selection=ZAMANSERILERI&ARAVERIGRUP=bie_yymkpyuk.db&GRTYPE=1&SUBMITDEG=Report&f_begdt=07-01-2005&ZAMANSERILERI=TP.PYUK1&ZAMANSERILERI=TP.PYUK2&ZAMANSERILERI=TP.PYUK21&ZAMANSERILERI=TP.PYUK22&ZAMANSERILERI=TP.PYUK3&ZAMANSERILERI=TP.PYUK4&ZAMANSERILERI=TP.PYUK5&ZAMANSERILERI=TP.PYUK6&ONDALIK=5&EPOSTA=xxx'
In [5]: len(response.text)
Out[5]: 71299
同样的字典在Python3中:
In [3]: response.request.body
Out[3]: 'EPOSTA=xxx&ARAVERIGRUP=bie_yymkpyuk.db&DIL=UK&SUBMITDEG=Report&cgi=%24ozetweb&GRTYPE=1&f_enddt=07-10-2016&wfmultiple_selection=ZAMANSERILERI&ONDALIK=5&f_begdt=07-01-2005&RESIMPOSTA=%2A%2A%2A&YON=3&ZAMANSERILERI=TP.PYUK1&ZAMANSERILERI=TP.PYUK2&ZAMANSERILERI=TP.PYUK21&ZAMANSERILERI=TP.PYUK22&ZAMANSERILERI=TP.PYUK3&ZAMANSERILERI=TP.PYUK4&ZAMANSERILERI=TP.PYUK5&ZAMANSERILERI=TP.PYUK6'
In [4]: len(response.text)
Out[4]: 134
在启动另一个ipython2 shell之前运行~$ export PYTHONHASHSEED=1234
:
In [4]: response.request.body
Out[4]: 'DIL=UK&GRTYPE=1&ARAVERIGRUP=bie_yymkpyuk.db&f_begdt=07-01-2005&RESIMPOSTA=%2A%2A%2A&ONDALIK=5&EPOSTA=xxx&YON=3&SUBMITDEG=Report&wfmultiple_selection=ZAMANSERILERI&cgi=%24ozetweb&ZAMANSERILERI=TP.PYUK1&ZAMANSERILERI=TP.PYUK2&ZAMANSERILERI=TP.PYUK21&ZAMANSERILERI=TP.PYUK22&ZAMANSERILERI=TP.PYUK3&ZAMANSERILERI=TP.PYUK4&ZAMANSERILERI=TP.PYUK5&ZAMANSERILERI=TP.PYUK6&f_enddt=07-10-2016'
In [5]: os.environ["PYTHONHASHSEED"]
Out[5]: '1234'
In [6]: len(response.text)
Out[6]: 134
你可以运行代码多次以达到相同的目的,但是一定要让
('cgi', '$ozetweb')
首先出现才能使代码正常工作,有时候使用 Python3 时由于键的顺序不确定,
cgi 会首先出现从而让代码偶尔能够正常工作。关于哈希主题还有更多内容,请参考
hashing topic。
POST
通常会修改服务器上的数据。你为什么期望它每次都返回相同的结果呢? - wimfrom __future__ import unicode_literals
,然后再次检查 Python2 的行为。因为如果不这样做,实际上请求并不相同(Python2 具有字节数据,而 Python3 具有字符串数据)。 - wimprint(good.text)
和print(bad.text)
,我敢打赌只有好的会输出你想要的结果。我认为顺序确实很重要,因为Python3和Python2中哈希算法的工作方式不同,这就是你看到差异的原因。 - Padraic Cunningham