如何在Python中实现curl -u命令?

14

我正在尝试使用http://developer.github.com/v3/来获取项目问题。这个能正常工作:

curl -u "Littlemaple:mypassword" https://api.github.com/repos/MyClient/project/issues

它返回了我的客户项目的所有私有问题。然而,我无法找到如何在Python中实现它。我发现的两种方式(例如Python urllib2 Basic Auth Problem)都不起作用,它们返回404或403错误:

def fetch(url, username, password):
    """Wonderful method found on forums which does not work.""""
    passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
    passman.add_password(None, url, username, password)
    urllib2.install_opener(urllib2.build_opener(urllib2.HTTPBasicAuthHandler(passman)))

    req = urllib2.Request(url)
    f = urllib2.urlopen(req)
    return f.read()

...并且:

def fetch(url, username, password):
    """Wonderful method found on forums which does not work neither.""""
    request = urllib2.Request(url)
    base64string = base64.encodestring('%s:%s' % (username, password)).replace('\n', '')
    request.add_header("Authorization", "Basic %s" % base64string)   
    return urllib2.urlopen(request).read()

有什么想法吗?提前感谢!


你可以通过传递 -v 选项来窥视 curl 实际上正在做什么,以查看是否缺少任何重要的交互。这可能会为你提供一些线索,以更接近在 Python 中模拟其行为。 - SingleNegationElimination
4个回答

19
r = requests.get('https://api.github.com', auth=('user', 'pass'))

Python requests是最好的选择。我在工作和家里经常使用requests与各种Web服务进行交互,相比之前使用的工具来说,它非常易用。需要注意的是,auth关键字参数适用于任何需要身份验证的调用。因此,你可以谨慎地使用它,即不需要每次调用GitHub时都使用它,只需要对那些需要登录的调用使用即可。例如:

r = requests.get('https://api.github.com/gists/starred', auth=('user', 'pass'))

GitHub的登录方式在这里有文档:

http://pypi.python.org/pypi/requests/0.6.1


1
请求(Requests)是一个很棒的库。真希望在需要解决这个问题时我就知道它了。如果你不是特别需要使用 cURL,用 Python 的 Requests 库比使用 cURL 更好。感谢提到这个库,然而它并没有完全回答给定的问题,所以我必须接受 Ken 的答案。 - Honza Javorek
没问题。你对Ken的回答是正确的。我只是想确保像我一样第一次尝试解决问题时没有硬性要求使用curl的人能够得到简短的答案。 - David Watson

6

如果是404错误,你可能只是输入了错误的URL。如果是403错误,也许你输入的领域不正确。

首先,你应该只传递基本URL到add_password中,而不是整个URL。此外,你应该创建一个新的opener,而不是使用install_opener。

看这个示例

class NoOpHandler(urllib2.HTTPRedirectHandler):
    def redirect_request(self, req, fp, code, msg, headers, newUrl):
        return None

passmanager = urllib2.HTTPPasswordMgrWithDefaultRealm()
passmanager.add_password(None, baseurl, username, password)
auth_handler = urllib2.HTTPBasicAuthHandler(passmanager)
opener = urllib2.build_opener(auth_handler, NoOpHandler())

最佳答案,但它就是不起作用。我认为问题出在 GitHub API 的某个地方。因为这只是一个简单的同步脚本,最终我只使用了 subprocess 并调用了 curl 本身。虽然有点粗糙,但是是最简单和最快速的解决方案。无论如何还是谢谢!特别是那个链接 :) - Honza Javorek

3
你也可以这样做。
 r = requests.get('https://user:pass@api.github.com')

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接