양말 프록시를 통해 파이썬 요청을 작동시키는 방법


83

Python 스크립트에서 훌륭한 Requests 라이브러리를 사용하고 있습니다.

import requests
r = requests.get("some-site.com")
print r.text

양말 프록시를 사용하고 싶습니다. 그러나 요청은 현재 HTTP 프록시 만 지원합니다.

어떻게 할 수 있습니까?

답변:


116

현대적인 방법 :

pip install -U requests[socks]

그때

import requests

resp = requests.get('http://go.to', 
                    proxies=dict(http='socks5://user:pass@host:port',
                                 https='socks5://user:pass@host:port'))

3
SOCKS 프록시를 사용할 때 요청은 전체 URL (예 : "GET / HTTP / 1.1"이 아닌 "GET example.com HTTP / 1.1")을 사용하여 HTTP 요청을 만들고이 동작으로 인해 문제가 발생할 수 있습니다. 슬프게도 지금은 더 나은 해결책이없는 것 같습니다.
a3nm

또한 프록시 설정에서 사용자 이름과 비밀번호를 사용하는 방법을 찾지 못했습니다. urllib2에 의지해야했습니다.
Encompass

9
나는 zsh를 사용하고 있고, bash -c "pip install -U requests[socks]"그렇지 않으면 zsh가 불평 할 것이다 zsh: no matches found: requests[socks].
Bruce Sun

3
Windows에서는 다음도 필요합니다. pip install win-inet-pton
rstaveley

4
@BruceSun은 pip install 'requests[socks]'충분하다
bakatrouble

55

현재 requests버전 2.10.0 2016년 4월 29일에 발표, requestsSOCKS를 지원합니다.

와 함께 설치할 수있는 PySocks 가 필요합니다 pip install pysocks.

사용 예 :

import requests
proxies = {'http': "socks5://myproxy:9191"}
requests.get('http://example.org', proxies=proxies)

3
pip install -U requests[socks] enogh입니다
dvska

8
제 경우에는 pip install -U requests [socks]만으로는 작동하지 않습니다. pip install pysocks는 필수입니다.
DenMark

이를 수정하려는 것과 마찬가지로 SOCKS (> 2.10.0) requests를 지원하는 버전으로의 버전을 수동으로 업그레이드 하려면 pip : (이 문서를 작성할 때 2.18.4)를 실행 하고 확인 : pypi. 최신 버전에 대한 python.org/pypi/requests (이 페이지는 최신 안정 버전이 무엇인지 상단 헤더에 표시되어야합니다). pip install requests==2.18.4
ntk4

나는 이것에 @DenMark와 함께 있습니다. 내 작업용 노트북은 Mac이고 요청 [양말]은 내가 무엇을 시도해도 설치를 거부했습니다. pysocks는 모든 것을 마술처럼 고쳤습니다.
Jeremy Logan 19 년

내 경우에는 거기 socks에 모듈 이름 충돌 qBittorrentI / 제거로 이동 필요, ~/.local/share/data/qBittorrent/nova3/socks.py그 제거 socks.pyc, 오류 메시지를 해결 module 'socks' has no attribute 'create_connection'하고 bad magic number in 'socks':각각.
Fruit

43

누군가가 이러한 모든 이전 답변을 시도했지만 여전히 다음과 같은 문제가 발생하는 경우 :

requests.exceptions.ConnectionError: 
   SOCKSHTTPConnectionPool(host='myhost', port=80): 
   Max retries exceeded with url: /my/path 
   (Caused by NewConnectionError('<requests.packages.urllib3.contrib.socks.SOCKSConnection object at 0x106812bd0>: 
   Failed to establish a new connection: 
   [Errno 8] nodename nor servname provided, or not known',))

기본적으로 연결 requests로컬 측 에서 DNS 쿼리를 확인하도록 구성되어 있기 때문일 수 있습니다 .

프록시 URL을에서 socks5://proxyhost:1234로 변경해보십시오 socks5h://proxyhost:1234. 추가 사항에 유의하십시오 h(호스트 이름 확인을 나타냄).

PySocks 패키지 모듈 기본값은 원격 해결을 수행하는 것이며 요청이 통합을 이렇게 모호하게 분산 시킨 이유는 모르겠지만 여기에 있습니다.


6
그것은 정확히 내 문제였습니다! 감사!
xbeta 2017

4
이것은 나에게 정확한 문제였습니다. 프록시를 통해 DNS 쿼리를 수행하지 않았습니다. h를 추가하자마자 모든 것이 제대로 작동했습니다.
jamescampbell

1
덕분에, socks5h접근 방식은 그래서 나는 내가 전에해야 할 거라고 걱정했다 원숭이 - 패치 해결 방법보다 훨씬 청소기.
Darien

1
아주 좋아. socks5h://프록시에 대한 Python 문서를 찾을 수 없습니다 . 잘못된 곳을 찾고 있었을 것입니다. 너무 사랑해.
Ligemer

1
@Ligemer는 때때로 코드를 볼 수있는 유일한 곳입니다. (하지만 코드를 살펴본 후 StackOverflow를 업데이트하면 두 가지 올바른 위치가 있습니다.))
Mahmoud Hashemi

18

pysocks를 설치해야합니다 . 내 버전은 1.0이고 코드는 저에게 적합합니다.

import socket
import socks
import requests
ip='localhost' # change your proxy's ip
port = 0000 # change your proxy's port
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, ip, port)
socket.socket = socks.socksocket
url = u'http://ajax.googleapis.com/ajax/services/search/images?v=1.0&q=inurl%E8%A2%8B'
print(requests.get(url).text)

큰! socks 5 proxy를 통해 패키지 (예 : flickrapi)를 사용하고 싶을 때 편리합니다
MZD

2
기본 소켓을 변경하고 실수를 할 수 있기 때문에 socks 프록시를 사용하는 좋은 방법이 아닙니다. 따라서 테스트 만해도 괜찮을 것이지만 실제는 아닙니다.
lqhcpsgbl

6

파이썬 requestsSOCKS5풀 리퀘스트 와 병합 되 자마자 proxies딕셔너리 를 사용하는 것처럼 간단 합니다 :

#proxy
        # SOCKS5 proxy for HTTP/HTTPS
        proxies = {
            'http' : "socks5://myproxy:9191",
            'https' : "socks5://myproxy:9191"
        }

        #headers
        headers = {

        }

        url='http://icanhazip.com/'
        res = requests.get(url, headers=headers, proxies=proxies)

SOCKS 프록시 지원 참조

기본 제공 모듈 이 없어 GoogleAppEngine에서와 같이 request사용할 수 없을 때 준비가 될 때까지 기다릴 수없는 경우를 대비 requesocks하여 위에서 언급 한 PySockpwd 을 사용 하는 방법도 있습니다.

  1. socks.py저장소 에서 파일을 가져 와서 루트 폴더에 사본을 넣으십시오.
  2. 추가 import socksimport socket

이 시점 urllib2에서 with를 사용하기 전에 다음 예에서 소켓을 구성하고 바인딩합니다 .

import urllib2
import socket
import socks

socks.set_default_proxy(socks.SOCKS5, "myprivateproxy.net",port=9050)
socket.socket = socks.socksocket
res=urllib2.urlopen(url).read()

2
# SOCKS5 proxy for HTTP/HTTPS
proxiesDict = {
    'http' : "socks5://1.2.3.4:1080",
    'https' : "socks5://1.2.3.4:1080"
}

# SOCKS4 proxy for HTTP/HTTPS
proxiesDict = {
    'http' : "socks4://1.2.3.4:1080",
    'https' : "socks4://1.2.3.4:1080"
}

# HTTP proxy for HTTP/HTTPS
proxiesDict = {
    'http' : "1.2.3.4:1080",
    'https' : "1.2.3.4:1080"
}

4
이것이 최신 요청 버전에서 작동하는 방식입니까? 없이 requesocks?
Gtx

이것은 현재 이미 병합되지 않은 proxies최신 requests풀 요청에 대한 사전입니다 . @see - github.com/kennethreitz/requests/pull/2953
loretoparisi

2

다음과 같이 urllib3에 pysocks와 monkey 패치 create_connection을 설치했습니다.

import socks
import socket
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS4, "127.0.0.1", 1080)

def create_connection(address, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
                      source_address=None, socket_options=None):
    """Connect to *address* and return the socket object.

    Convenience function.  Connect to *address* (a 2-tuple ``(host,
    port)``) and return the socket object.  Passing the optional
    *timeout* parameter will set the timeout on the socket instance
    before attempting to connect.  If no *timeout* is supplied, the
    global default timeout setting returned by :func:`getdefaulttimeout`
    is used.  If *source_address* is set it must be a tuple of (host, port)
    for the socket to bind as a source address before making the connection.
    An host of '' or port 0 tells the OS to use the default.
    """

    host, port = address
    if host.startswith('['):
        host = host.strip('[]')
    err = None
    for res in socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM):
        af, socktype, proto, canonname, sa = res
        sock = None
        try:
            sock = socks.socksocket(af, socktype, proto)

            # If provided, set socket level options before connecting.
            # This is the only addition urllib3 makes to this function.
            urllib3.util.connection._set_socket_options(sock, socket_options)

            if timeout is not socket._GLOBAL_DEFAULT_TIMEOUT:
                sock.settimeout(timeout)
            if source_address:
                sock.bind(source_address)
            sock.connect(sa)
            return sock

        except socket.error as e:
            err = e
            if sock is not None:
                sock.close()
                sock = None

    if err is not None:
        raise err

    raise socket.error("getaddrinfo returns an empty list")

# monkeypatch
urllib3.util.connection.create_connection = create_connection


0

Linux에서 할 수 있습니다.

$ pip3 install --user 'requests[socks]'
$ https_proxy=socks5://<hostname or ip>:<port> python3 -c \
> 'import requests;print(requests.get("https://httpbin.org/ip").text)'
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.