【问题标题】:Python 3.5 / Pastebin "Bad API request, invalid api_option"Python 3.5 / Pastebin“错误的 API 请求,无效的 api_option”
【发布时间】:2015-10-24 23:57:51
【问题描述】:

我正在开发一个 twitch irc 机器人,我想要的组件之一是该机器人能够在关闭时将引号保存到 pastebin 粘贴,然后在启动时检索相同的引号。

我从保存部分开始,遇到了一个障碍,我似乎无法获得有效的帖子,而且我想不出方法。

#!/usr/bin/env python3

import urllib.parse
import urllib.request

# --------------------------------------------- Pastebin Requisites --------------------------------------------------

pastebin_key = 'my pastebin key'  # developer api key, required. GET: http://pastebin.com/api
pastebin_password = 'password'  # password for pastebin_username
pastebin_postexp = 'N'  # N = never expire
pastebin_private = 0  # 0 = Public 1 = unlisted 2 = Private
pastebin_url = 'http://pastebin.com/api/api_post.php'
pastebin_username = 'username'  # user corresponding with key


# --------------------------------------------- Value clean up --------------------------------------------------

pastebin_password = urllib.parse.quote(pastebin_password, safe='/')
pastebin_username = urllib.parse.quote(pastebin_username, safe='/')

# --------------------------------------------- Pastebin Functions --------------------------------------------------

def post(title, content):  # used for posting a new paste
    pastebin_vars = {'api_option': 'paste', 'api_user_key':     pastebin_username, 'api_paste_private': pastebin_private,
                 'api_paste_name': title, 'api_paste_expire_date': pastebin_postexp,  'api_dev_key': pastebin_key,
                 'api_user_password': pastebin_password, 'api_paste_code': content}
    try:
        str_to_paste = ', '.join("{!s}={!r}".format(key, val) for (key, val) in pastebin_vars.items())  # dict to str :D
        str_to_paste = str_to_paste.replace(":", "")  # remove :
        str_to_paste = str_to_paste.replace("'", "")  # remove '
        str_to_paste = str_to_paste.replace(")", "")  # remove )
        str_to_paste = str_to_paste.replace(", ", "&")  # replace dividers with &
        urllib.request.urlopen(pastebin_url, urllib.parse.urlencode(pastebin_vars)).read()
        print('did that work?')
    except:
        print("post submit failed :(")
        print(pastebin_url + "?" + str_to_paste)  # print the output for test

 post("test", "stuff")

我愿意导入更多的库和东西,在连续两天工作后不太确定我做错了什么:S

【问题讨论】:

  • edit您的问题并发布您遇到的任何错误或追溯的全文

标签: python python-3.x pastebin


【解决方案1】:

直到现在我才知道 pastebin。我阅读了他们的 api 并第一次尝试,它工作得非常好。

这就是我所做的:

  • 我登录是为了获取api_user_key
  • 将其与api_dev_key一起包含在帖子中。
  • 检查了网站,帖子在那里。

代码如下:

import urllib.parse
import urllib.request


def post(url, params):
    data = urllib.parse.urlencode(login_params).encode("utf-8")
    req = urllib.request.Request(login_url, data)
    with urllib.request.urlopen(req) as response:
       return response.read()


# Logging in to fetch api_user_key
login_url = "http://pastebin.com/api/api_login.php"
login_params = {"api_dev_key": "<the dev key they gave you",
                "api_user_name": "<username goes here>",
                "api_user_password": "<password goes here>"}
api_user_key = post(login_url, login_params)


# Posting some random text
post_url = "http://pastebin.com/api/api_post.php"
post_params = {"api_dev_key": "<the dev key they gave you",
               "api_option": "paste",
               "api_paste_code": "<head>Testing</head>",
               "api_paste_private": "0",
               "api_paste_name": "testing.html",
               "api_paste_expire_date": "10M",
               "api_paste_format": "html5",
               "api_user_key": api_user_key}
response = post(post_url, post_params)

发布内容只需要前三个参数,其余的都是可选的。

【讨论】:

    【解决方案2】:

    首先,您的 try/except 块正在丢弃实际错误。您几乎不应该在不捕获或重新引发原始异常的情况下使用“裸”except 子句。完整说明请参见this article

    删除try/except 后,您将看到根本错误:

    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "paste.py", line 42, in post
        urllib.request.urlopen(pastebin_url, urllib.parse.urlencode(pastebin_vars)).read()
      File "/usr/lib/python3.4/urllib/request.py", line 161, in urlopen
        return opener.open(url, data, timeout)
      File "/usr/lib/python3.4/urllib/request.py", line 461, in open
        req = meth(req)
      File "/usr/lib/python3.4/urllib/request.py", line 1112, in do_request_
        raise TypeError(msg)
    TypeError: POST data should be bytes or an iterable of bytes. It cannot be of type str.
    

    这意味着您正在尝试将 unicode 字符串传递给需要字节的函数。当您执行 I/O(例如在磁盘上读取/写入文件,或通过 HTTP 发送/接收数据)时,您通常需要将任何 unicode 字符串编码为字节。有关 unicode 与字节以及何时需要编码和解码的详细说明,请参阅 this presentation

    接下来,这一行:

    urllib.request.urlopen(pastebin_url, urllib.parse.urlencode(pastebin_vars)).read()
    

    正在丢弃响应,因此您无法知道 API 调用的结果。将此分配给一个变量或从您的函数中返回它,以便您可以检查该值。它可以是粘贴的 URL,也可以是来自 API 的错误消息。

    接下来,我认为您的代码向 API 发送了许多不必要的参数,而您的 str_to_paste 语句是不必要的。

    我能够使用以下更简单的代码进行粘贴:

    import urllib.parse
    import urllib.request
    
    PASTEBIN_KEY = 'my-api-key' # developer api key, required. GET: http://pastebin.com/api
    PASTEBIN_URL = 'http://pastebin.com/api/api_post.php'
    
    def post(title, content):  # used for posting a new paste
        pastebin_vars = dict(
            api_option='paste',
            api_dev_key=PASTEBIN_KEY,
            api_paste_name=title,
            api_paste_code=content,
        )
        return urllib.request.urlopen(PASTEBIN_URL, urllib.parse.urlencode(pastebin_vars).encode('utf8')).read()
    

    这里正在使用:

    >>> post("test", "hello\nworld.")
    b'http://pastebin.com/v8jCkHDB'
    

    【讨论】:

    • 这个答案包含了我需要时间才能真正理解它,谢谢
    • 哦,还有一个问题,我如何查看发送 post() 的服务器响应?
    • @Cyrohzin 没问题!只需将其分配给一个变量。 url = post("test", "hello\nworld.")
    • 我尝试使用此代码,只需将我的开发密钥添加到它并保留其他所有内容,我得到“未定义的帖子”错误。有任何想法吗?回溯(最后一次调用):文件“”,第 1 行,在 NameError: name 'post' is not defined
    • @Syperus post 是我定义的函数的名称,你是如何调用该函数的?您需要发布更多代码。
    【解决方案3】:

    在撰写本文时,API 似乎不接受 http 请求,因此请确保网址格式为 https://pas...

    【讨论】:

      【解决方案4】:
      import urllib.parse
      import urllib.request
      
      PASTEBIN_KEY = 'xxx'
      PASTEBIN_URL = 'https://pastebin.com/api/api_post.php'
      PASTEBIN_LOGIN_URL = 'https://pastebin.com/api/api_login.php'
      PASTEBIN_LOGIN = 'my_login_name'
      PASTEBIN_PWD = 'yyy'
      
      def pastebin_post(title, content):
          login_params = dict(
              api_dev_key=PASTEBIN_KEY,
              api_user_name=PASTEBIN_LOGIN,
              api_user_password=PASTEBIN_PWD
          )
      
          data = urllib.parse.urlencode(login_params).encode("utf-8")
          req = urllib.request.Request(PASTEBIN_LOGIN_URL, data)
      
          with urllib.request.urlopen(req) as response:
              pastebin_vars = dict(
                  api_option='paste',
                  api_dev_key=PASTEBIN_KEY,
                  api_user_key=response.read(),
                  api_paste_name=title,
                  api_paste_code=content,
                  api_paste_private=2,
              )
              return urllib.request.urlopen(PASTEBIN_URL, urllib.parse.urlencode(pastebin_vars).encode('utf8')).read()
      
      rv = pastebin_post("This is my title", "These are the contents I'm posting")
      print(rv)
      

      结合上面两个不同的答案给了我这个可行的解决方案。

      【讨论】:

        猜你喜欢
        • 2014-08-23
        • 1970-01-01
        • 2021-06-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多