Как скачать файл через requests python
Перейти к содержимому

Как скачать файл через requests python

  • автор:

Я хочу стянуть информацию с сайта. Как это сделать?

Допустим, нам нужно получить данные с сайта, сбор которых вручную нецелесообразен или невозможен из-за объёма. В таком случае мы можем автоматизировать процесс, используя инструменты, описанные далее.

Библиотека requests

Python-библиотека для выполнения запросов к серверу и обработки ответов. Фундамент скрипта для парсинга и наше основное оружие. Пользуясь данной библиотекой мы получаем содержимое страницы в виде html для дальнейшего парсинга.

import requests response = requests.get('https://ya.ru') # get-запрос print(response.text) # вывод содержимого страницы payload = 'key1': 'value1', 'key2': 'value2'> response = requests.get('http://httpbin.org/get', params=payload) # запрос с параметрами headers = 'user-agent': 'my-app/0.0.1'> response = requests.get(url, headers=headers) # запрос с определенными html заголовками 

API

Application programming interface — программный интерфейс приложения, предоставляемый владельцем веб-приложения для других разработчиков. Отсутствие API, способного удовлетворить наши нужды — первое в чем стоит убедиться прежде чем бросаться анализировать исходный код страницы и писать для нее парсер. Множество популярных сайтов имеет собственное api и документацию, которая объясняет как им пользоваться. Мы можем использовать api таким образом — формируем http-запрос согласно документации, и получаем ответ при помощи requests.

BS4

Beautifulsoup4 — это библиотека для парсинга html и xml документов. Позволяет получить доступ напрямую к содержимому любых тегов в html.

from bs4 import BeautifulSoup soup = BeautifulSoup(raw_html, 'html.parser') print(soup.find("p", class_="some-class").text) # вывод содержимого тэга 'p' классом 'some-class' 

Selenium Web Driver

Данные на сайте могут генерироваться динамически при помощи javascript. В таком случае спарсить эти данные силами requests+bs4 не удастся. Дело в том, что bs4 парсит исходный код страницы, не исполняя js. Для исполнения js кода и получения страницы, идентичной той, которую мы видим в браузере, можно использовать selenium web driver — это набор драйверов для различных браузеров, снабжающийся библиотеками для работы с этими драйверами.

А что делать, если там авторизация?

Предварительно авторизоваться, отправив post-запрос и инициировать сессию:

session = requests.Session() data = "login_username":"login", "login_password":"password"> url = "http://site.com/login.php" response = session.post(url, data=data) 

А что, если сайт банит за много запросов?

  • Установить задержку между запросами:
response = requests.get(url, timeout=(10, 0.01)) # таймаут на соединения, таймаут на чтение (в секундах) 
  • Притвориться браузером, используя selenium web driver или передав содержимое заголовка user-agent, формируя запрос:
user_agent = ('Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) ' 'Gecko/20100101 Firefox/50.0') request = requests.get(url, headers='User-Agent':user_agent>) 
  • Использовать прокси:
request = requests.get(url, proxies="http":"http://10.10.1.10:3128">) 

Попробуйте бесплатные уроки по Python

Получите крутое код-ревью от практикующих программистов с разбором ошибок и рекомендациями, на что обратить внимание — бесплатно.

Переходите на страницу учебных модулей «Девмана» и выбирайте тему.

Загрузка больших данных модулем requests в Python

Потоковая отправка/загрузка контента модулем requests

Содержание:

  • Управление процессом загрузки контента с сервера;
  • Потоковая передача данных для исходящих/входящих запросов;
  • Передача данных частями для исходящих/входящих запросов;
  • Поддержка соединения при больших объемах данных.

Управление процессом загрузки контента с сервера.

По умолчанию, когда отправляется запрос на сервер, тело ответа загружается немедленно. Можно переопределить такое поведение и отложить загрузку тела ответа сервера до тех пор, пока библиотека requests не получит доступ к атрибуту Response.content , который управляется аргументом stream , передаваемый при создании запроса.

tarball_url = 'https://github.com/psf/requests/tarball/master' resp = requests.get(tarball_url, stream=True) 

На данный момент загружены только заголовки ответов, и соединение остается открытым, что позволяет сделать загрузку нужного контента условным:

if int(resp.headers['content-length'])  TOO_LONG: content = resp.content . 

Можно дополнительно управлять рабочим процессом с помощью методов Response.iter_content() и Response.iter_lines() . Кроме того, можно прочитать не декодированное тело ответа сервера, которое возвращает атрибут Response.raw (из базового urllib3.HTTPResponse ).

Если установить для аргумента потока stream значение True при подготовке запроса или при его выполнении методом requests.get() , requests.post() и т.д., то библиотека не сможет освободить соединение обратно в пул, если клиент не прочитает все данные или не вызовет метод Response.close() . Это может привести к неэффективности подключений.

Если при использовании stream=True обнаружится, что тело запроса нужно прочитать частично (или вообще не надо читать), то запрос к серверу следует делать в контекстном менеджере with , чтобы он всегда смог автоматически закрыться:

with requests.get('https://httpbin.org/get', stream=True) as resp: # здесь делаем что-нибудь с ответом. 

Потоковая передача данных для исходящих/входящих запросов.

Библиотека requests поддерживают потоковую отправку/загрузку контента, которая позволяет отправлять/загружать большие потоки или файлы, не считывая их в память целиком.

Для потоковой передачи или загрузки просто предоставьте файлоподобный объект для тела запроса:

Пример отправки большого файла:

with open('massive-body', 'rb') as fp: requests.post('http://some.url/streamed', data=fp) 

Предупреждение. Настоятельно рекомендуется открывать файлы в двоичном режиме ‘rb’ . Это связано с тем, что запросы могут попытаться предоставить заголовок Content-Length , и если это произойдет, то это значение будет установлено на количество байтов в файле. При открытии файла в текстовом режиме могут возникнуть ошибки.

Передача данных частями для исходящих/входящих запросов.

Библиотека requests также поддерживает фрагментированную передачу контента для исходящих и входящих запросов. Чтобы отправить запрос с фрагментом тела запроса, просто предоставьте генератор (или любой итератор без указания длины) для тела запроса:

def gen(): yield 'hi' yield 'there' requests.post('http://some.url/chunked', data=gen()) 

Для фрагментированных закодированных ответов лучше всего перебирать данные с помощью Response.iter_content() . В идеальной ситуации нужно установить для запроса аргумент stream=True , и в этом случае можно выполнять итерацию по частям, вызывая метод .iter_content() с аргументом chunk_size=None . Если нужно установить максимальный размер блока, то можно установить параметр chunk_size в любое целое число.

Поддержка соединения при больших объемах данных.

Благодаря urllib3 поддержка соединения keep-alive работает на 100% автоматически в течение всего сеанса! Любые запросы, которые делаются в течение сеанса, автоматически повторно используют соответствующее соединение!

Обратите внимание, что соединения освобождаются обратно в пул для повторного использования только после того, как все данные тела были прочитаны. Обязательно установите stream=False или прочитайте до конца контент, находящийся в Response.content .

  • КРАТКИЙ ОБЗОР МАТЕРИАЛА.
  • GET и POST запросы c модулем requests
  • Получение/отправка заголовков сервера модулем requests
  • Извлечение и установка cookies с модулем requests
  • Сессии/сеансы Session() модуля requests
  • Объект ответа сервера Response модуля requests
  • Получение и отправка данных в виде JSON с модулем requests
  • Установка timeout для модуля requests
  • Объект PreparedRequest модуля requests
  • Загрузка файлов на сервер модулем requests
  • Загрузка больших данных модулем requests
  • HTTP-прокси или SOCKS-прокси с модулем requests
  • Использование хуков модуля requests
  • Аутентификация с модулем requests
  • SSL и модуль requests

Скачивание и распаковка .gz файла в Python: requests, shutil

Для того, чтобы безопасно загрузить файл по http-адресу и сохранить его на диске, в Python, рекомендуется использовать библиотеку requests :

Скопировать код

import requests response = requests.get('http://example.com/file.txt') response.raise_for_status() # Если скрипт пришел до этой строки, значит, загрузка прошла успешно.�� with open('local_file.txt', 'wb') as file: file.write(response.content)

Приведенный выше код скачает файл с адреса ‘http://example.com/file.txt’ и сохранит его на вашем устройстве под именем ‘local_file.txt’ .

Как справиться с загрузкой больших файлов

В случае работы с большими файлами рекомендуется использовать потоковую загрузку, чтобы избежать перерасхода памяти:

Скопировать код

import requests response = requests.get('http://example.com/largefile.zip', stream=True) response.raise_for_status() with open('large_file.zip', 'wb') as file: for chunk in response.iter_content(chunk_size=8192): if chunk: file.write(chunk)

Данный подход позволяет загружать большие файлы, не расходуя избыточного объема памяти.

Обработка архивных файлов

Если вам нужно работать с файлом в формате .gz , модуль gzip сможет распаковать его после загрузки:

Скопировать код

import gzip import shutil with gzip.open('file.gz', 'rb') as f_in: with open('file.txt', 'wb') as f_out: shutil.copyfileobj(f_in, f_out)

Выполнив это, gz-файл будет распакован и готов к использованию.

Продвинутое использование библиотеки requests

requests предоставляет множество дополнительных функций для совершенствования вашего кода, в том числе: обработку ошибок и использование сессий:

Скопировать код

from requests.exceptions import HTTPError try: with requests.Session() as session: response = session.get('http://example.com/file.txt') response.raise_for_status() # Успешная загрузка файлов – непосредственная цель! # Здесь должен быть весь последующий код вашей программы. except HTTPError as http_err: print(f'HTTP ошибка: ') # Конкретизация сообщения об ошибке except Exception as err: print(f'Ошибка: ') # Осуществление широкого перехвата исключений для обеспечения стабильности кода

Визуализация

Скопировать код

Загрузка файла: �� ↔️ �� 1. **Установка сетевого соединения:** `with urllib.request.urlopen('http://example.com/file') as response:` 2. **Чтение данных файла:** `data = response.read()` Сохранение файла на диск: �� ↔️ �� 1. **Создание локального файла:** `with open('downloaded_file', 'wb') as file:` 2. **Запись данных в файл:** `file.write(data)`

Подумайте о переменной data как о ценном ресурсе, который вы сначала загружаете из интернета (��) при помощи urllib.request , а затем сохраняете на своем устройстве (��).

Альтернативы для профессионалов

Для упрощенной загрузки файлов вы можете использовать wget :

Использование библиотеки Requests в Python

Для начала давайте разберемся, что же вообще такое библиотека Requests.

Requests — это HTTP-библиотека, написанная на Python (под лицензией Apache2). Она спроектирована для взаимодействия людей с эим языком. Это означает, что вам не нужно вручную добавлять строки запроса в URL-адреса или заносить данные в форму для POST -запроса. Если это кажется вам бессмысленным, не волнуйтесь. В нужное время все прояснится.

Что же делает библиотека Requests?

Библиотека Requests дает вам возможность посылать HTTP/1.1-запросы, используя Python. С ее помощью вы можете добавлять контент, например заголовки, формы, многокомпонентные файлы и параметры, используя только простые библиотеки Python. Также вы можете получать доступ к таким данным.

В программировании библиотека — это набор или, точнее сказать, предварительно настроенный набор подпрограмм, функций и операций, которые в дальнейшем может использовать ваша программа. Эти элементы часто называют модулями, которые хранятся в объектном формате.

Библиотеки очень важны, потому что вы можете загрузить модуль и использовать все, что он предлагает, без явной связи с вашей программой. Они действительно автономны, так что вы можете создавать свои собственные программы с ними, и все же они остаются отделенными от ваших программ.

Таким образом, о модулях можно думать как о неких шаблонах кода.

Повторимся еще раз, Requests — это библиотека языка Python.

Как установить Requests

Сразу сообщим вам хорошую новость: существует множество способов для установки Requests. С полным списком можно ознакомиться в официальной документации библиотеки Requests.

Вы можете использовать pip, easy_install или tarball.

Если вам нужен исходный код, вы можете найти его на GitHub.

Мы для установки библиотеки воспользуемся менеджером pip.

В интерпретаторе Python введите следующую команду:

pip install requests

Импортирование модуля Requests

Для работы с библиотекой Requests в Python вам необходимо импортировать соответствующий модуль. Вы можете это сделать, просто поместив следующий код в начало вашей программы:

import requests

Разумеется, предварительно этот модуль должен быть установлен и доступен для интерпретатора.

Делаем запрос

Когда вы пингуете веб-сайт или портал для получения информации, то это как раз и называется созданием запроса.

Для получения веб-страницы вам нужно написать что-то в таком духе:

r = requests.get(‘https://github.com/timeline.json’)

Работаем с кодом ответа

Перед тем как вы будете что-то делать с веб-сайтом или URL, хорошей идеей будет проверить код ответа, который вернул вам сервер. Это можно сделать следующим образом:

r = requests.get('https://github.com/timeline.json') r.status_code >>200 r.status_code == requests.codes.ok >>> True requests.codes['temporary_redirect'] >>> 307 requests.codes.teapot >>> 418 requests.codes['o/'] >>> 200

Получаем содержимое страницы

После того как сервер вам ответил, вы можете получить нужный вам контент. Это также делается при помощи функции get библиотеки Requests.

import requests r = requests.get('https://github.com/timeline.json') print(r.text) # Библиотека Requests также имеет встроенный JSON-декодер на # тот случай, если вам понадобятся данные JSON import requests r = requests.get('https://github.com/timeline.json') print(r.json)

Работаем с заголовками

Используя словари Python, вы можете просмотреть заголовки ответа сервера. Особенностью работы библиотеки Requests является то, что для получения доступа к заголовкам вы можете использовать в ключах словаря как заглавные, так и строчные буквы.

Если вызываемого заголовка нет, будет возвращено значение None .

r.headers < 'status': '200 OK', 'content-encoding': 'gzip', 'transfer-encoding': 'chunked', 'connection': 'close', 'server': 'nginx/1.0.4', 'x-runtime': '148ms', 'etag': '"e1ca502697e5c9317743dc078f67693f"', 'content-type': 'application/json; charset=utf-8' >r.headers['Content-Type'] >>>'application/json; charset=utf-8' r.headers.get('content-type') >>>'application/json; charset=utf-8' r.headers['X-Random'] >>>None # Получаем заголовки данного URL resp = requests.head("http://www.google.com") print resp.status_code, resp.text, resp.headers

Кодирование

Библиотека Requests автоматически декодирует любой контент, извлеченный из сервера. Хотя большинство наборов символов Unicode в любом случае легко декодируются.

Когда вы делаете запрос к серверу, библиотека Requests делает обоснованное предположение о кодировке ответа. Это делается на основании заголовков HTTP. Предполагаемая кодировка будет использоваться при доступе к файлу r.text .

С помощью этого файла вы можете определить, какую кодировку использует библиотека Requests, и при необходимости изменить ее. Это возможно благодаря атрибуту r.encoding , который вы найдете в файле.

Когда вы измените значение кодировки, в дальнейшем библиотека Requests при вызове вами r.text будет использовать новый тип кодировки.

print(r.encoding) >> utf-8 >>> r.encoding = ‘ISO-8859-1’

Пользовательские заголовки

Если вы хотите добавить пользовательские заголовки в HTTP-запрос, вы должны передать их через словарь в параметр заголовков.

import json url = 'https://api.github.com/some/endpoint' payload = headers = r = requests.post(url, data=json.dumps(payload), headers=headers)

Переадресация и история

Библиотека Requests автоматически поддерживает переадресацию при выполнении команд GET и OPTION .

Например, GitHub из соображений безопасности автотоматически переадресует все HTTP -запросы на HTTPS .

Вы можете отслеживать статус переадресации при помощи метода history , который реализован для объекта response .

r = requests.get('http://github.com') r.url >>> 'https://github.com/' r.status_code >>> 200 r.history >>> []

Осуществление POST-запроса HTTP

Также с помощью библиотеки Requests вы можете работать и с POST -запросами:

r = requests.post(http://httpbin.org/post)

Но вы также можете выполнять и другие HTTP -запросы, такие как PUT , DELETE , HEAD , и OPTIONS .

r = requests.put("http://httpbin.org/put") r = requests.delete("http://httpbin.org/delete") r = requests.head("http://httpbin.org/get") r = requests.options("http://httpbin.org/get")

При помощи этих методов можно сделать массу разных вещей. Например, при помощи следующего кода вы можете создать репозиторий GitHub:

import requests, json github_url = "https://api.github.com/user/repos" data = json.dumps() r = requests.post(github_url, data, auth=('user', '*****')) print r.json

Ошибки и исключения

Есть ряд ошибок и исколючений, с которыми вам надо ознакомиться при использовании библиотеки Requests.

  • При проблемах с сетью, например с DNS , или отказе соединения, библиотека Requests вызовет исключение ConnectionError .
  • При недопустимом ответе HTTP библиотека Requests вызвоет исключение HTTPError , но это довольно редкий случай.
  • Если время запроса истекло, возникнет исключение Timeout .
  • Когда при запросе будет превышено заранее заданное количество переадресаций, возникнет исключение TooManyRedirects .

Все исключения, вызываемые библиотекой Requests, наследуются от объекта requests.exceptions.RequestException .

Дополнительные материалы

Более подробно про билиотеку Requests вы можете почитать, пройдя по следующим ссылкам:

  • http://docs.python-requests.org/en/latest/api/
  • http://pypi.python.org/pypi/requests
  • http://docs.python-requests.org/en/latest/user/quickstart/
  • http://isbullsh.it/2012/06/Rest-api-in-python/#requests

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *