【问题标题】:Simulate curl command using urllib in Python - httplib.InvalidURL: nonnumeric port:在 Python 中使用 urllib 模拟 curl 命令 - httplib.InvalidURL: nonnumeric port:
【发布时间】:2016-03-16 09:14:01
【问题描述】:

我正在尝试在 Python 中复制以下 CURL 命令(我正在尝试使用特定 IP 上的一些数据发出 POST 请求):

curl -k --data "phonenr=a_number&smstxt=Test&Submit=SendSms" https://admin:pass@ip/txsms.cgi

ip 是远程服务器的 IP,admin:pass 是所需的凭据。

此 CURL 命令执行正确,响应为 200

使用以下 python 代码,我收到:

httplib.InvalidURL: nonnumeric port: 'pass@91.195.144.248'

谁能告诉我我做错了什么?

import urllib2 as urllib
from os.path import join as joinPath
from urllib import urlencode

# constant
APPLICATION_PATH = '/srv/sms_alert/'
ALERT_POINT_PATH = joinPath(APPLICATION_PATH, 'alert_contact')
URL_REQUEST_TIMEOUT = 42

SMS_BOX_URL = 'https://admin:pass@ip/txsms.cgi'

with open(ALERT_POINT_PATH, 'r') as alertContactFile:
    for line in alertContactFile:
        line = line.strip('\n')
        data = {
            'phonenr': line,
            'smstext': 'Test',
            'Submit': 'SendSms'
        }
        url_data = urlencode(data)
        url_data = url_data.encode('UTF-8')
        req = urllib.Request(SMS_BOX_URL, url_data)
        with urllib.urlopen(req) as response:
            print(response.read())

【问题讨论】:

    标签: python http-post urllib2


    【解决方案1】:

    好的,看看你的导入,代码应该可以正常工作。问题是首先您将 urllib2 导入为 urllib,然后从 urllib 导入 urlencode,因此您无法获得所需的功能。

    查看从 urllib2 文档中检索到的以下代码:

    链接:URLLIB2 documentation

    import urllib
    import urllib2
    
    url = 'http://www.someserver.com/cgi-bin/register.cgi'
    values = {'name' : 'Michael Foord',
              'location' : 'Northampton',
              'language' : 'Python' }
    
    data = urllib.urlencode(values)
    req = urllib2.Request(url, data)
    response = urllib2.urlopen(req)
    the_page = response.read()
    

    祝你好运!

    【讨论】:

      【解决方案2】:

      问题是身份验证(我们将假设它是基本身份验证)不能像 curl 命令一样发送,urllib 会将用户视为主机名,将 ':' 后面的内容视为端口,这就是为什么你有这个错误,

      您将不得不尝试使用您的凭据设置一个 urllib 打开器,如下所示:

      import urllib2 as urllib
      SMS_BOX_URL = 'https://hostname/txsms.cgi'
      # Prepare an authentication handler
      auth_handler = urllib.HTTPBasicAuthHandler()
      # Set your authentication Handler (catch the realm by parsing the authentication request with your navigator
      auth_handler.add_password('realm', 'the realm of the authent', 'admin', 'pass')
      opener = urllib.build_opener(auth_handler)
      # Install your opener for later use
      urllib.install_opener(opener)
      
      # use it
      url_data = urlencode(data)
      url_data = url_data.encode('UTF-8')
      req = urllib.Request(SMS_BOX_URL, url_data)
      with urllib.urlopen(req) as response:
        print(response.read())
      

      这应该可以,
      开启者只需要实例化一次

      ref

      【讨论】:

      • 我应该写什么而不是:'realm', 'the realm of the authent'
      • 你应该在解析服务器请求标头时看到它,例如:WWW-Authenticate: Basic realm="WallyWorld"。您可以尝试无(不带引号)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-26
      相关资源
      最近更新 更多