Python: отключить http_proxy в urllib2

Я использую прокси-набор как переменную среды (экспорт http_proxy = example.com). Для одного вызова с использованием urllib2 мне нужно временно отключить это, т.е. отключите http_proxy. Я пробовал различные методы, предлагаемые в документации и interwebs, но до сих пор не смог отключить прокси. До сих пор я пробовал:

# doesn't work
req = urllib2.Request('http://www.google.com')
req.set_proxy(None,None)
urllib2.urlopen(req)

# also doesn't work
urllib.getproxies = lambda x = None: {}

Ответ 1

Документация urllib2 предлагает, что следующее должно работать. Это один из подходов, которые вы пробовали?

import urllib2

proxy_handler = urllib2.ProxyHandler({})
opener = urllib2.build_opener(proxy_handler)
page = opener.open('http://www.google.com')

Ответ 2

Вы можете поместить это перед кодом, в котором вы хотите отключить системные прокси.

import urllib2
urllib2.getproxies = lambda: {}

Иногда это лучше, чем создание пустого ProxyHandler, потому что оно работает для внешних библиотек, даже если они создают свои собственные открыватели urllib2.

Также возможен способ временного отключения прокси с contextmanager decorator, но я не могу делать ставку на то, что он будет работать с несколькими потоками:

import selenium
import urllib2
from contextlib import contextmanager

@contextmanager
def no_proxies():
    orig_getproxies = urllib2.getproxies
    urllib2.getproxies = lambda: {}
    yield
    urllib2.getproxies = orig_getproxies

with no_proxies():
    driver = selenium.webdriver.Ie()
    driver.get("http://google.com")

В этом примере мы запрещаем python-selenium использовать системный прокси-сервер, который влечет за собой такие ошибки:

IE и Chrome не работают с Selenium2 Python

Невозможно запустить IEDriverServer.exe с прокси-сервером, установленным в Internet Explorer

Ответ 3

Если вы хотите избежать использования прокси-сервера для известного набора сайтов, вы можете использовать переменную среды no_proxy следующим образом:

$ export no_proxy="google.com,stackoverflow.com,mysite.org:8080"

(список суффиксов, разделенных запятыми, также можно указать порт)

Это должно работать как с urllib, так и urllib2.

Ответ 4

Другой способ - обезврежить библиотеку носков следующим образом:

import socks, socket, urllib2
def create_connection(address, timeout=None, source_address=None):
    sock = socks.socksocket()
    sock.connect(address)
    return sock

socks.setdefaultproxy(None, None) # this does ["0.0.0.0"], [0]
socket.socket = socks.socksocket
socket.create_connection = create_connection
print urllib2.urlopen("http://httpbin.org/ip").read()

Итак, кажется, что если вы установите его как 0.0.0.0 на порт 0, по крайней мере, следует избегать его использования, потому что библиотека inet_aton() не принимает 0.0.0.0 как действительный IP.

Очевидно, я действительно не проверял, почему что... но действительно работает. Самый простой способ проверить сначала установить прокси, получить URL-адрес с любой библиотекой и повторить попытку без установки прокси-сервера. Вы получите привязанный последний установленный прокси-сервер:), если вы не "отмените" его для следующих подключений.