Использование urllib2 с прокси SOCKS

Можно ли извлекать страницы с urllib2 через прокси-сервер SOCKS на одном сервере socks для каждого базового элемента? Я видел решение с использованием метода setdefaultproxy, но мне нужно иметь разные носки в разных открывателях.

Итак, есть библиотека SocksiPy, которая отлично работает, но ее нужно использовать следующим образом:

import socks
import socket
socket.socket = socks.socksocket
import urllib2
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, "x.x.x.x", y)

То есть он устанавливает тот же самый прокси для всех запросов urllib2. Как я могу использовать разные прокси для разных открывателей?

Ответы

Ответ 1

Попробуйте pycurl:

import pycurl
c1 = pycurl.Curl()
c1.setopt(pycurl.URL, 'http://www.google.com')
c1.setopt(pycurl.PROXY, 'localhost')
c1.setopt(pycurl.PROXYPORT, 8080)
c1.setopt(pycurl.PROXYTYPE, pycurl.PROXYTYPE_SOCKS5)

c2 = pycurl.Curl()
c2.setopt(pycurl.URL, 'http://www.yahoo.com')
c2.setopt(pycurl.PROXY, 'localhost')
c2.setopt(pycurl.PROXYPORT, 8081)
c2.setopt(pycurl.PROXYTYPE, pycurl.PROXYTYPE_SOCKS5)

c1.perform() 
c2.perform() 

Ответ 2

Да, вы можете. Я повторяю свой ответ на Как использовать прокси-сервер SOCKS 4/5 с urllib2? Вам нужно создать открыватель для каждого прокси-сервера, как и с прокси-сервером http. Код для добавления этой функции в SocksiPy доступен в GitHub https://gist.github.com/869791 и прост как:

opener = urllib2.build_opener(SocksiPyHandler(socks.PROXY_TYPE_SOCKS4, 'localhost', 9999))
print opener.open('http://www.whatismyip.com/automation/n09230945.asp').read()

Для получения дополнительной информации я написал пример, в котором запущено несколько экземпляров Tor, чтобы вести себя как вращающийся прокси: Распределенная сортировка с несколькими цепами Tor

Ответ 3

== EDIT == (старый пример HTTP-прокси был здесь..)

Моя ошибка.. urllib2 не имеет встроенной поддержки проксирования SOCKS..

Есть некоторые "хаки", добавляющие SOCKS к urllib2 (или вообще к объекту сокета) здесь.
Но я почти не подозреваю, что это будет работать с несколькими прокси-серверами, как вам это нужно.

Пока вы не хотите зацепить/подкласс urllib2.ProxyHandler, я бы предложил пойти с pycurl.

Ответ 4

У вас есть только один сокет для всех открывателей, а реализация носков - в уровне сокета. Итак, вы не можете. Я предлагаю вам использовать библиотеку pycurl, она намного более гибкая.

Ответ 5

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

import socks
import socket
import thread
lock = thread.allocate_lock()
socket.socket = socks.socksocket

def GetConn():
    lock.acquire()
    import urllib2
    socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, "x.x.x.x", y)
    conn = urllib2.urlopen(ARGUMENTS HERE)
    lock.release()
    return conn

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

urllib2 = execfile('urllib2.py')
urllib2.socket = dummy_class() # dummy_class needs the socket module methods

Это, очевидно, не фантастические решения, но я все равно вложил 2 ¢: -)

Ответ 6

Громоздким, но работающим решением для использования прокси-сервера SOCKS является создание прокси с цепочкой прокси, а затем установка HTTP_PROXY, предоставляемого privoxy через системную переменную или любым другим способом.

Ответ 7

Вы можете сделать это, установив переменную окружения HTTP_PROXY в следующем формате:

пользователь: пароль @прокси: порт

или если вы используете bat/cmd, добавьте перед вызовом script:

установить HTTP_PROXY = пользователь: pass @proxy: port

Я использую такой cmd файл, чтобы сделать работу easy_install под прокси.