在Siteminder中使用Python请求

在Siteminder中使用Python请求,python,python-3.x,python-requests,urllib,siteminder,Python,Python 3.x,Python Requests,Urllib,Siteminder,我在使用请求从网页检索某些数据时遇到一些问题。它使用Siteminder,初始表单只有三个字段,但当我提交它时,我的密码更改为十六进制,并添加了其他字段。似乎根本无法让它工作。我不断返回一条错误消息 非常感谢您的帮助,我为这篇冗长的文章道歉 编辑:包含两个JavaScript函数,因为它们更改了数据 Python: from requests import session with session() as s: headers = { 'User-Agent': 'M

我在使用请求从网页检索某些数据时遇到一些问题。它使用Siteminder,初始表单只有三个字段,但当我提交它时,我的密码更改为十六进制,并添加了其他字段。似乎根本无法让它工作。我不断返回一条错误消息

非常感谢您的帮助,我为这篇冗长的文章道歉

编辑:包含两个JavaScript函数,因为它们更改了数据

Python:

from requests import session
with session() as s:

    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'
    }
    payload = {
        'USER': 'username',
        'PASSWORD': 'pw',
        'TARGET': 'https://www.THISSITE.com/pg'
    }

    resp = s.post('https://www.THISSITE.com/THIS/fcc/THISSITE.fcc', headers=headers, data=payload )
    html = resp.text
    print(html)
表格:

hexEncode(str):


hexEncode
函数获取一个字符串,并将其UTF8编码表示的组成字节转换为一系列十六进制表示。Python中的等效方法是将输入的unicode字符串编码为UTF-8,然后将其结果重新编码为十六进制,例如

注意:在Python2.7中,这将是-

如果您使用示例密码进行测试,它将产生与网站相同的输出,但有一个警告

hexEncode('d')
"64000000"
请注意,Javascript添加了许多尾随的0,使字符串的长度为8的倍数。我们需要填充结果,以获得相同的输出

>>> s = binascii.hexlify('d'.encode('utf-8'))
>>> n = len(s)
>>> from math import ceil
>>> next_8_multiple = int(ceil(n/8.0) * 8)
>>> s.ljust(next_8_multiple, b'0')
b'6400000000'
我们可以将其总结为一个完整的函数:

from math import ceil
import binascii

def hex_encode_and_pad(s):
    hex = binascii.hexlify(s.encode('utf-8'))
    n = len(hex)
    next_8_multiple = int(ceil(n/8.0) * 8)
    zeros_to_append = next_8_multiple - n
    return hex.ljust(next_8_multiple, b'0')
>>> hex_encode_and_pad('d')
'64000000'
现在,这将给出与Javascript函数相同的结果:

from math import ceil
import binascii

def hex_encode_and_pad(s):
    hex = binascii.hexlify(s.encode('utf-8'))
    n = len(hex)
    next_8_multiple = int(ceil(n/8.0) * 8)
    zeros_to_append = next_8_multiple - n
    return hex.ljust(next_8_multiple, b'0')
>>> hex_encode_and_pad('d')
'64000000'
下一步是将其包装为JSON的字符串表示形式。您可以通过手工编码字符串+插入标记来实现这一点,例如

value = '{"TokenId":"%s","Password":""}' % token
或者从Python字典中创建JSON字符串-

import json
data = {'TokenId': token, 'Password': ''}
value = json.dumps(data)
基于上述示例请求的完整代码如下:

import binascii
import json
from math import ceil
from requests import session

def hex_encode_and_pad(s):
    hex = binascii.hexlify(s.encode('utf-8'))
    n = len(hex)
    next_8_multiple = int(ceil(n/8.0) * 8)
    zeros_to_append = next_8_multiple - n
    return hex.ljust(next_8_multiple, b'0')

with session() as s:

    password = u'your_password'

    token = hex_encode_and_pad(password)
    data = {'TokenId': token, 'Password': ''}

    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'
    }
    payload = {
        'USER': 'username',
        'PASSWORD': json.dumps(data),
        'TARGET': 'https://www.THISSITE.com/pg'
    }

    resp = s.post('https://www.THISSITE.com/THIS/fcc/THISSITE.fcc', headers=headers, data=payload )
    html = resp.text
    print(html)

为什么这行
form.PASSWORD.value=JSON.stringify(info)?@PPJN我的答案能解决你的问题吗?@mfitzp我明天上午会查一下。我离开信用证了。谢谢你的回复!我得到以下错误:“bytes”对象没有属性“encode”看起来像是在hex_encode_和_pad函数的第一行抛出的,这是因为您使用的是Python3,将对其进行返工,但我仍然无法通过python登录页面:(@PPJN您可以通过浏览器登录(使用假登录/通过)吗)并粘贴浏览器发送的内容?查看Chrome Dev toolsHad中的“网络”选项卡,将密码dict包装为json.dumps。可以进入!
>>> hex_encode_and_pad('d')
'64000000'
value = '{"TokenId":"%s","Password":""}' % token
import json
data = {'TokenId': token, 'Password': ''}
value = json.dumps(data)
import binascii
import json
from math import ceil
from requests import session

def hex_encode_and_pad(s):
    hex = binascii.hexlify(s.encode('utf-8'))
    n = len(hex)
    next_8_multiple = int(ceil(n/8.0) * 8)
    zeros_to_append = next_8_multiple - n
    return hex.ljust(next_8_multiple, b'0')

with session() as s:

    password = u'your_password'

    token = hex_encode_and_pad(password)
    data = {'TokenId': token, 'Password': ''}

    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'
    }
    payload = {
        'USER': 'username',
        'PASSWORD': json.dumps(data),
        'TARGET': 'https://www.THISSITE.com/pg'
    }

    resp = s.post('https://www.THISSITE.com/THIS/fcc/THISSITE.fcc', headers=headers, data=payload )
    html = resp.text
    print(html)