【问题标题】:How to download and write a file from Github using Requests如何使用 Requests 从 Github 下载和写入文件
【发布时间】:2012-12-16 17:29:28
【问题描述】:

假设有一个文件存在于 github 存储库中:

https://github.com/someguy/brilliant/blob/master/somefile.txt

我正在尝试使用请求来请求此文件,将其内容写入当前工作目录中的磁盘,以便以后使用。现在,我正在使用以下代码:

import requests
from os import getcwd

url = "https://github.com/someguy/brilliant/blob/master/somefile.txt"
directory = getcwd()
filename = directory + 'somefile.txt'
r = requests.get(url)

f = open(filename,'w')
f.write(r.content)

无疑是丑陋的,更重要的是,不工作。我得到的不是预期的文本:

<!DOCTYPE html>
<!--

Hello future GitHubber! I bet you're here to remove those nasty inline styles,
DRY up these templates and make 'em nice and re-usable, right?

Please, don't. https://github.com/styleguide/templates/2.0

-->
<html>
  <head>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
    <title>Page not found &middot; GitHub</title>
    <style type="text/css" media="screen">
      body {
        background: #f1f1f1;
        font-family: "HelveticaNeue", Helvetica, Arial, sans-serif;
        text-rendering: optimizeLegibility;
        margin: 0; }

      .container { margin: 50px auto 40px auto; width: 600px; text-align: center; }

      a { color: #4183c4; text-decoration: none; }
      a:visited { color: #4183c4 }
      a:hover { text-decoration: none; }

      h1 { letter-spacing: -1px; line-height: 60px; font-size: 60px; font-weight: 100; margin: 0px; text-shadow: 0 1px 0 #fff; }
      p { color: rgba(0, 0, 0, 0.5); margin: 20px 0 40px; }

      ul { list-style: none; margin: 25px 0; padding: 0; }
      li { display: table-cell; font-weight: bold; width: 1%; }
      #error-suggestions { font-size: 14px; }
      #next-steps { margin: 25px 0 50px 0;}
      #next-steps li { display: block; width: 100%; text-align: center; padding: 5px 0; font-weight: normal; color: rgba(0, 0, 0, 0.5); }
      #next-steps a { font-weight: bold; }
      .divider { border-top: 1px solid #d5d5d5; border-bottom: 1px solid #fafafa;}

      #parallax_wrapper {
        position: relative;
        z-index: 0;
      }
      #parallax_field {
        overflow: hidden;
        position: absolute;
        left: 0;
        top: 0;
        height: 370px;
        width: 100%;
      }

等等等等

来自 Github 的内容,但不是文件的内容。我做错了什么?

【问题讨论】:

  • 你真的应该使用os.path.join() 来组合路径。 getcwd() 不一定返回以路径分隔符结尾的目录名称。

标签: python github python-requests


【解决方案1】:

相关文件的内容包含在返回的数据中。您将获得该文件的完整 GitHub 视图,而不仅仅是内容。

如果您想只下载该文件,您需要使用页面顶部的Raw 链接,该链接将是(以您的示例为例):

https://raw.github.com/someguy/brilliant/master/somefile.txt

注意域名的变化,路径的blob/部分不见了。

使用requests GitHub 存储库本身来证明这一点:

>>> import requests
>>> r = requests.get('https://github.com/kennethreitz/requests/blob/master/README.rst')
>>> 'Requests:' in r.text
True
>>> r.headers['Content-Type']
'text/html; charset=utf-8'
>>> r = requests.get('https://raw.github.com/kennethreitz/requests/master/README.rst')
>>> 'Requests:' in r.text
True
>>> r.headers['Content-Type']
'text/plain; charset=utf-8'
>>> print r.text
Requests: HTTP for Humans
=========================


.. image:: https://travis-ci.org/kennethreitz/requests.png?branch=master
[... etc. ...]

【讨论】:

  • 如果您想访问私有存储库中的文件,基本身份验证可以正常工作:requests.get('raw.github.com/myfile.txt', auth=('username', 'passwd'))跨度>
  • arg,sn-p 代码搞砸了,这里又是:requests.get('https://raw.github.com/myfile.txt', auth=('username', 'passwd'))
  • 请注意,原始链接的缓存时间为 5 分钟。因此对文件的更改将在几分钟后反映在原始链接中。
【解决方案2】:

您需要从https://raw.github.com 请求文件的原始版本。

看看区别:

https://raw.github.com/django/django/master/setup.pyhttps://github.com/django/django/blob/master/setup.py

另外,您可能应该在您的目录和文件名之间添加一个/

>>> getcwd()+'foo.txt'
'/Users/burhanfoo.txt'
>>> import os
>>> os.path.join(getcwd(),'foo.txt')
'/Users/burhan/foo.txt'

【讨论】:

  • 这是一个比接受的答案简单得多的实现,并且对我来说非常适合。谢谢!
  • Wdym 和他没有举个例子一模一样???勒尔
【解决方案3】:

作为更新,https://raw.github.com was migratedhttps://raw.githubusercontent.com。所以一般格式是:

url = "https://raw.githubusercontent.com/user/repo/branch/[subfolders]/file"

例如https://raw.githubusercontent.com/earnestt1234/seedir/master/setup.py。仍然使用 requests.get(url) 就像在 Martijn 的回答中一样。

【讨论】:

    【解决方案4】:

    添加一个准备复制+粘贴的工作示例:

    import requests
    from requests.structures import CaseInsensitiveDict
    
    url = "https://raw.githubusercontent.com/organization/repo/branch/folder/file"
    
    # If repo is private - we need to add a token in header:
    headers = CaseInsensitiveDict()
    headers["Authorization"] = "token TOKEN"
    
    resp = requests.get(url, headers=headers)
    print(resp.status_code)
    

    (*) 如果 repo 不是私有的 - 删除标题部分。


    奖励:
    查看thisCurl Python-requests 在线转换器。

    【讨论】:

      猜你喜欢
      • 2013-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-01
      • 2016-01-09
      相关资源
      最近更新 更多