Как использовать proxy в python
Отправка http запроса через прокси сервер с авторизацией Python
Прокси-сервер, теория
Прокси-сервер — это промежуточное звено в Вашем общении со всемирной паутиной.
Вы отправляете запрос на сервер, он поступает на прокси-сервер, оттуда уже запрос отправляется дальше и дальше до тех пор, пока не будет получен достаточный ответ. После того, как прокси-сервер получил качественный ответ, он отправляет его клиенту совершившему запрос.
Существуют различные виды прокси-серверов. Некоторые дополнительно предоставляют анонимность, некоторые элементарно служат «почтальонами» пересылающими запросы и ответы. Какие-то используют высоко производительные машины под свою деятельность, какие-то более слабые. Однако существуют ещё и такие прокси-сервера, которые за свои услуги просят денежные взносы, бесплатные же могут использовать Ваш сетевой трафик в своих целях: продавать сведения о Вашей интернет-деятельности рекламщикам для анализа усовершенствования маркетинговой политики, например. Будьте бдительны и внимательны при выборе какой использовать прокси-сервер, идеально безопасной сети не бывает.
Использование прокси для своего сёрфинга в интернете не обязательно, но порой возникает необходимость обезопасить себя из-за участившихся хакерских атак, Вас чрезвычайно сильно беспокоит анонимность в интернете или Вас элементарно достала однородная поисковая выдача в связи с недавними многочисленными целенаправленными поисками некоторой вещицы.
Существуют прокси с авторизацией, то есть для того, чтобы взаимодействовать с данным промежуточным звеном требуется знание логина и соответствующего пароля. Также, имеются в миру и не требующие авторизации и ими можно пользоваться абсолютно свободно.
Рассмотрим как отправить запрос используя оба способа.
Программное обеспечение
Для языка программирования Python был создан один крайне полезный модуль под названием requests. Задача его скромна и крайне значима — помочь во взаимодействии с глобальной всемирной паутиной. Он не идёт из коробки для Python 3.x.x, а потому требует отдельной инсталляции. О том, как установить модуль можете прочесть здесь.
Прокси без авторизации
Рассмотрим пример использования случайного прокси-сервера не требующего авторизации. Импортируйте модуль requests, затем определите используемый прокси-сервер с используемым протоколом передачи (SOCKS4, HTTP, HTTPS, и так далее) и указанным портом, создайте запрос с прописанными ранее данными прокси-сервера, отправьте запрос и получите ответ. В ответе нас будет интересовать только статус — запрос выполнен успешно или же провалился.
Схема создания записи данных прокси-сервера и отправки запроса следующая, необходимые данные предоставляется поставщиком прокси:
Как использовать прокси для перебора IP-адресов в Python
В этой статье, мы научимся выполнять парсинг веб-сайтов, не позволяя им блокировать наш IP-адрес с помощью различных методов, использующих прокси в Python.
Другими словами при использовании прокси-сервера вместо прямого подключения к целевому серверу и отправки запроса ему непосредственно, вы направляете запрос на прокси-сервер, который обрабатывает его, выполняет его и возвращает ответ. Рисунок ниже демонстрирует, проще чем в Википедии, принцип работы прокси-сервера:
Специалисты по парсингу часто используют более одного прокси, чтобы веб-сайты не блокировали их IP-адрес. Кроме того прокси-серверы имеют ряд других преимуществ, в том числе обход различных фильтров и цензуры, скрытие вашего реального IP-адреса и т.д.
В этом руководстве вы узнаете, как использовать прокси-серверы в Python с помощью библиотеки requests, мы также будем использовать библиотеку stem, библиотекой позволяющей работать с помощью Python контролером Tor, то есть программно отправлять и получать от него команды. Также мы будем использовать библиотеку BeautifulSoup для обработки полученного содержимого страниц. И так давайте установим их:
Используем адреса активных бесплатных прокси
В сети есть несколько веб-сайтов, которые предлагают бесплатный список прокси-серверов. И я создал функцию для автоматического получения их списка:
Однако, когда я попытался использовать их, у большинства из них был слишком большой тайм-аут, и я отфильтровал только рабочие:
Этот список может оказаться весьма недолговечным, так как большинство из адресов перестанут работать, уже когда вы прочтете это руководство (поэтому вам следует выполнять указанную выше функцию каждый раз, когда вам понадобятся новые адреса прокси-серверов).
Давайте проверим этот код, отправив запрос на веб-сайт, который возвращает наш IP-адрес:
В результате получим:
Как видите, это IP-адреса рабочих прокси-серверов, а не наш реальный IP-адрес (попробуйте посетить этот веб-сайт в своем браузере, и вы увидите свой реальный IP-адрес).
Использование Tor в качестве прокси
Вы также можете использовать сеть Tor для ротации IP-адресов:
Примечание. Приведенный выше код должен работать только в том случае, если на вашем компьютере установлен Tor (перейдите по этой ссылке, чтобы правильно установить его) и правильно настроен (включен ControlPort 9051, см. этот ответ в stackoverflow о переполнении стека для получения дополнительных сведений).
Этот код создает новую сессию с IP-адресом Tor и отправляет HTTP запрос, а затем обновляет соединение, отправив в сеть сигнал NEWNYM (который сообщает Tor, что устанавливается новое соединение), чтобы изменить IP-адрес и делает следующий запрос. В результате получим:
Все получилось. Однако, когда вы попробуете веб-парсинг с использованием сети Tor, вы скоро поймете, что в большинстве случаев это довольно медленно, поэтому рекомендуемый мною способ мы рассмотрим ниже.
Используем Crawlera
Crawlera от Scrapinghub позволяет вам осуществлять парсинг быстро и надежно, управляя прокси-серверами, автоматически меняя их адреса, поэтому, если вас забанят, он автоматически обнаружит это и изменит IP-адрес за вас.
Crawlera — это интеллектуальная прокси-сеть, специально разработанная для парсинга и сканирования веб-страниц. Ее задача проста: облегчить вам жизнь в качестве парсера. Она помогает получать успешные запросы и извлекать данные в любом масштабе с любого веб-сайта с помощью любого инструмента для разбора содержимого веб-страниц.
Благодаря простому API запрос, который вы делаете при парсинге, будет маршрутизироваться через пул высококачественных прокси. При необходимости он автоматически вводит задержки между запросами и удаляет/добавляет IP-адреса для решения различных проблем сканирования.
Вот как можно использовать Crawlera с библиотекой requests используя Python:
Итак, вот что делает для вас Crawlera:
Заключение
Существует несколько типов прокси, включая прозрачные прокси, анонимные прокси, «элитные» прокси. Если ваша цель использования прокси, чтобы не дать веб-сайтам блокировать ваши парсеры, то «элитные» прокси ваш оптимальный выбор.
Кроме того, дополнительной мерой защиты от блокирования ваших парсеров является использование ротации типов и свойств пользовательских агентов user agents. То есть вы каждый раз должны отправлять новый поддельный заголовок запроса, имитируя браузер обычного пользователя.
Продвинутое руководство по библиотеке Python Requests
В этом материале описаны продвинутые функции библиотеки Requests.
Объекты Session
Объект Session включает все методы основного API Requests.
Попробуем передать куки между запросами:
Session могут также использоваться для предоставления данных по умолчанию для методов запроса. Для этого их нужно передать в параметры объекта:
Любые словари, переданные методу запроса? будут объединены с заданными значениями уровня сессии. Параметры уровня методов перезаписывают параметры сессии.
Удалите значение из параметра словаря:
Иногда нужно будет не включать ключи уровня сессии в параметры словаря. Для этого необходимо установить значения ключа None в параметре уровня методов. Они будут пропускаться автоматически.
Все значения, содержащиеся в сессии, прямо доступны. Подробнее об этом в документации API Session.
Объекты запросов и ответов
Если нужно получить доступ к заголовкам, которые вернул сервер, делается следующее:
А если нужны те, что были направлены серверу, тогда сперва нужно получить доступ к запросу, а потом — к его заголовкам:
Подготовка запросов
Проверка сертификата SSL
Библиотека Requests может верифицировать SSL-сертификаты для HTTPS-запросов так же, как и браузер. Для проверки сертификата хоста, нужно просто добавить аргумент verify :
Если такового нет или он недействителен, вернется ошибка SSLError. Но у Github, например, есть:
Можно также определить файл локального сертификата в виде пути или пары ключ-значение:
Если указан неправильный путь или недействительный сертификат, произойдет следующее:
Работа с содержанием ответа
Сейчас загружаются только заголовки ответа, а соединение остается открытым. Это позволяет сделать получение контента по условию:
Постоянное соединение
Благодаря urllib3 постоянное соединение поддерживается на 100% автоматически прямо в сессии. Любые запросы в сессии будут автоматически использовать соответствующее соединение.
Потоковые загрузки
Requests поддерживает потоковые загрузки, которые позволяют отправлять крупные потоки или файлы без их чтения прямо в память. Для этого нужно предоставить файловый объект в data :
Запросы для данных, разбитых на части (chunk-encoded)
Requests также поддерживает механизм передачи с разбиением на части для входящих и исходящих запросов. Для отправления такого нужно предоставить генератор (или любой итератор без определенной длины) в data :
POST для нескольких файлов типа multipart
Можно отправить несколько файлов одним запросом. Например, предположим, необходимо загрузить файлы изображений в HTML-форму images для нескольких файлов :
Чтобы сделать это, просто представьте файлы в виде списка кортежей такого формата (form_field_name, file_info) :
Хуки (перехват управления)
В Requests есть система хуков, которую можно использовать для управления частями процесса запроса или обработки событий.
Можно назначать функцию перехвата для каждого запроса, передавая словарь
callback_function получит кусок данных в качестве первого аргумента.
Если при выполнении обратного вызова произойдет ошибка, отобразится предупреждение.
Если функция вернет значение, предполагается, что оно должно заменить данные, которые были переданы. Когда функция не возвращает ничего, нет никакого эффекта.
Выведем некоторые аргументы метода запроса:
Собственная аутентификация
Requests позволяет указать собственный механизм аутентификации.
Любой вызываемый объект, передаваемый в качестве аргумента auth методу запроса, может изменить запрос до его отправки.
Представим, что есть веб-сервис, который отвечает только в том случае, если значение заголовка X-Pizza — значение пароля. Такое маловероятно, но мало ли.
Теперь можно сделать запрос с помощью PizzaAuth :
Потоковые запросы
С помощью requests.Response.iter_lines() можно запросто перебирать потоковые API, такие как Twitter Streaming API.
Используем его для отслеживания ключа словаря requests :
Прокси
Если есть необходимость использовать прокси, можно настроить индивидуальные запросы с помощью аргумента proxies для любого метода запроса:
Для использования HTTP Basic Auth (аутентификации) со своим прокси, используется синтаксис http://user:password@host/ :
SOCKS
В дополнение к базовым прокси HTTP Requests также поддерживает прокси с помощью протокола SOCKS. Это опциональная функция, требующая дополнительных библиотек. Их можно получить с помощью pip :
После установки использовать прокси SOCKS так же просто, как и HTTP:
Соответствие стандартам
Requests соответствует всем актуальным спецификациям и RFC (технические стандарты, применяемые в сети) там, где подобное соответствие не создает трудностей для пользователей. Такое внимание к спецификациям может привести к необычному поведению, которое покажется необычным для тех, кто не знаком с ними.
Кодировки
Методы HTTP
Нужно подтвердить, что GitHub ответил правильно. Если да — необходимо определить тип контента. Это делается следующим образом:
Эта документация была добавлена в ответ на “Issue #482”. Возьмем ее в качестве примера.
Есть три комментария. Рассмотрим последний из них.
Можем сообщить автору, что он не прав. Но сперва узнаем, кто это.
Похоже, нужно авторизоваться. В Requests можно выполнить любой вид аутентификации, включая базовую.
С баловством покончено. Используем DELETE для удаления сообщения.
Напоследок можно посмотреть, как много запросов было использовано. Для этого нужно сделать запрос HEAD к заголовкам и не скачивать целую страницу.
Осталось написать программу на Python, которая бы использовала остальные 4995 запросов.
Заголовки Link
Requests автоматически парсит эти ссылки и позволяет с легкостью их использовать.
Пользовательские HTTP-методы
Таким образом можно использовать любой метод, разрешенный сервером.
Transport Adapters
Начиная с версии v1.0.0, Requests использует внутренний модульный дизайн. Одна из причин — внедрение Transport Adapters. Они предоставляют средство для определения методов взаимодействия с HTTP. В частности, позволяют применять настройку для каждого сервиса по отдельности.
Requests дают возможность пользователям создавать и использовать собственные Transport Adapters с конкретной функциональностью. После создания Transport Adapter может быть прикреплен к объему Session вместе с указанием сервисов, к которым он должен применяться.
Вызов mount регистрирует экземпляр Transport Adapter в префиксе. После этого HTTP-запросы, сделанные с помощью этого Session и URL которых начинается с этого префикса, будут использовать указанный Transport Adapter.
Многие подробности использования Transport Adapter лежат за рамками этого материала, но вы сможете разобраться лучше на следующем примере.
Пример: конкретная версия SSL
Блокирующий или не-блокирующий
С Transport Adapter по умолчанию Requests не предоставляет никакого не-блокирующего IO (ввода-вывода). Свойство Response.content будет блокировать до тех пор, пока весь ответ не загрузится. Если требуется большая детализация, потоковые возможности библиотеки позволяют получать маленькие порции ответа в определенное время. Но и эти вызовы будут блокироваться.
Если не хочется использовать блокировку IO, есть масса проектов, совмещающих Requests с одним из асинхронных фреймворков Python. Например, requests-threads, grequests, requests-futures и requests-async.
Порядок заголовков
Таймауты
У большинства запросов к внешнем серверам есть прикрепленный таймаут в том случае, если сервер не отвечает вовремя. По умолчанию запросы не прерываются, только если время не указано явно. Без таймаута код может висеть по несколько минут.
connect — это количество секунд, которые Requests будет выжидать для настройки соединения с вызовом удаленной машины (соответствующей connect() ) в сокете. Хорошей практикой считается настраивать это время чуть больше значения кратного 3, что является стандартным окном ретрансляции пакета TCP.
Когда клиент подключился к серверу и отправил HTTP-запрос, таймаут read — это количество секунд, которые клиент будет ждать ответа от сервера. (Если точнее, это то количество секунд, которое клиент прождет между отправкой байтов с сервера. В 99,9% случаев оно меньше того времени с момента, когда сервер отправляет первый байт).
Если определить одно значение для таймаута, вот так:
HTTP-прокси или SOCKS-прокси с модулем requests в Python.
Запросы к сайтам через HTTP-прокси или SOCKS-прокси.
Содержание:
Запросы через HTTP-прокси.
В качестве альтернативы можно настроить список прокси один раз для всего сеанса/сессии:
Чтобы использовать HTTP Basic Auth с прокси, необходимо использовать синтаксис http://user:password@host/ в любой из приведенных выше записей конфигурации:
Предупреждение. Хранение конфиденциальной информации в открытом виде об имени пользователя и пароле в переменных средах или файле с кодом представляет собой угрозу безопасности и настоятельно не рекомендуется.
Чтобы предоставить прокси-сервер для конкретной схемы и хоста, используйте форму scheme://hostname для ключа. Это будет соответствовать для любого запроса заданной схеме и точному имени хоста.
Обратите внимание, что URL-адреса прокси должны включать схему.
Наконец, обратите внимание, что использование прокси-сервера для HTTPS-соединений обычно требует, чтобы локальный компьютер доверял корневому сертификату прокси. По умолчанию список сертификатов, которым доверяют запросы, можно найти с помощью:
Можно переопределить этот набор сертификатов по умолчанию, установив для стандартной переменной среды curl_ca_bundle другой путь к файлу:
Запросы через SOCKS-прокси.
Новое в версии 2.10.0.
Помимо основных HTTP-прокси, библиотека requests также поддерживает прокси, использующие протокол SOCKS. Это дополнительная функция, для которой перед использованием необходимо установить дополнительные сторонние библиотеки.
Вы можете получить зависимости для этой функции из pip:
После того как установили эти зависимости, использовать SOCKS-прокси так же просто, как и HTTP-прокси:
100 строк кода: Прокси-сервер на Python
Что такое прокси-сервер?
Прокси-сервер (proxy server) – это сервер, исполняющий роль посредника между клиентом и целевым сервером. Прокси-сервер действует «от лица» клиента и, в зависимости от поставленной задачи, может выполнять различные преобразования данных. На рисунке ниже показана логика работы прокси-сервера:
Мы поставили перед собой задачу разработать прокси-сервер, используя только стандартные библиотеки Python. Перед началом разработки были сформулированы следующие критерии функциональности приложения:
Ниже представлен код готового приложения:
Пояснение
Класс Forward
Устанавливает соединение между прокси-сервером и целевым сервером.
Класс TheServer
Основной класс приложения.
Метод TheServer.main_loop()
Список input_list содержит все доступные сокеты, управление которыми осуществляется с помощью select.select(). Первым в список добавляется серверный сокет самого прокси-сервера. Каждое новое подключение к этому сокету будет инициировать вызов метода on_accept().
Если текущий сокет из списка inputready, возвращенного select.select(), не предполагает новое соединение, значит, мы имеем дело с входящими данными (возможно от целевого сервера, возможно от клиента). Если размер данных равен нулю, значит, это запрос на закрытие соединения, в противном случае пакет необходимо переслать в соответствующее место назначения.
Метод TheServer.on_accept()
Этот метод устанавливает новое соединение с целевым сервером, а также принимает подключение текущего клиента. Оба сокета добавляются в список input_list для дальнейшей обработки в методе main_loop(). Оба сокета также сохраняются в словаре channel для сопоставления конечных точек назначения (клиент целевой сервер).
Метод TheServer.on_recv()
Этот метод выполняет обработку данных (при необходимости) и пересылает их по месту назначения (клиент целевой сервер).
Метод TheServer.on_close()
Данный метод закрывает соединение между прокси-сервером и целевым сервером, а также между прокси-сервером и клиентом. Соответствующие объекты удаляются.
Заключение
Перед вами полноценный прокси-сервер. Как видите, компактное приложение решает все поставленные задачи.