Как загрузить и записать файл с Github с помощью запросов

Допустим, есть файл, который находится в репозитории 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, но не содержимое файла. Что я делаю неправильно?


person Fomite    schedule 02.01.2013    source источник
comment
Вы действительно должны использовать os.path.join() для объединения путей. getcwd() не обязательно возвращает имя каталога, заканчивающееся разделителем пути.   -  person Martijn Pieters    schedule 02.01.2013


Ответы (3)


Содержимое рассматриваемого файла включается в возвращаемые данные. Вы получаете полное представление 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. ...]
person Martijn Pieters    schedule 02.01.2013
comment
если вы хотите получить доступ к файлу в частном репозитории, обычная аутентификация работает отлично: .github.com/myfile.txt', auth=('имя пользователя', 'пароль')) - person linqu; 08.11.2013
comment
arg, фрагмент кода перепутался, вот снова: requests.get('https://raw.github.com/myfile.txt', auth=('username', 'passwd')) - person linqu; 08.11.2013

Вам необходимо запросить необработанную версию файла у https://raw.github.com.

Увидеть разницу:

https://raw.github.com/django/django/master/setup.py по сравнению с https://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'
person Burhan Khalid    schedule 02.01.2013
comment
Это гораздо более простая реализация, чем принятый ответ, и она отлично подойдет для меня. Спасибо! - person dslosky; 10.02.2017
comment
Вдым это же он только пример не привел??? лел - person Max; 11.05.2020

В качестве обновления https://raw.github.com был перенесен в https://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), как в ответе Мартейна.

person Tom    schedule 21.02.2021