So funktionieren Python-Anfragen über den Socken-Proxy


81

Ich verwende die großartige Requests- Bibliothek in meinem Python-Skript:

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

Ich möchte Socken Proxy verwenden. Requests unterstützt jetzt jedoch nur den HTTP-Proxy.

Wie kann ich das machen?

Antworten:


114

Der moderne Weg:

pip install -U requests[socks]

dann

import requests

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

3
Beachten Sie, dass bei Verwendung eines SOCKS-Proxy-Anforderungssocks HTTP-Anforderungen mit der vollständigen URL (z. B. "GET example.com HTTP / 1.1" anstelle von "GET / HTTP / 1.1") gestellt werden und dieses Verhalten Probleme verursachen kann. Leider scheint es derzeit keine bessere Lösung zu geben.
A3nm

Außerdem habe ich keine Möglichkeit gefunden, Benutzername und Passwort in den Proxy-Einstellungen zu verwenden. Musste auf urllib2 zurückgreifen.
Umfassen

9
Ich benutze zsh und muss es bash -c "pip install -U requests[socks]"stattdessen tun, sonst wird sich zsh beschweren zsh: no matches found: requests[socks].
Bruce Sun

3
Unter Windows benötigen Sie außerdem: pip install win-inet-pton
rstaveley

4
@ BruceSun pip install 'requests[socks]'würde ausreichen
Bakatrouble

53

Ab requestsVersion 2.10.0 , die am 29.04.2016 veröffentlicht wurde, requestswerden SOCKS unterstützt.

Es erfordert PySocks , mit denen installiert werden kann pip install pysocks.

Anwendungsbeispiel:

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

3
pip install -U requests[socks] ist enogh
dvska

8
In meinem Fall funktioniert die Pip-Installation von -U-Anforderungen [Socken] allein nicht. Pip Install Pysocks ist ein Muss.
DenMark

Um dies zu ändern, führen Sie pip: (2.18.4 zum Zeitpunkt des Schreibens) aus, um ein manuelles Upgrade Ihrer Version requestsauf eine Version zu erzwingen , die SOCKS (> 2.10.0) unterstützt. pip install requests==2.18.4Überprüfen Sie jedoch: pypi. python.org/pypi/requests für die neueste Version (diese Seite sollte Ihnen in der oberen Kopfzeile zeigen, was die neueste stabile Version ist).
ntk4

Ich bin mit @DenMark in diesem Fall. Mein Arbeitslaptop ist ein Mac und Anfragen [Socken] lehnten es einfach ab, für mich zu installieren, egal was ich versuchte ... Pysocks reparierten alles auf magische Weise.
Jeremy Logan

In meinem Fall gibt es einen socksKonflikt mit dem qBittorrentModulnamen. Ich muss diesen entfernen / verschieben ~/.local/share/data/qBittorrent/nova3/socks.pyund entfernen socks.pyc, um die Fehlermeldung module 'socks' has no attribute 'create_connection'bzw. zu bad magic number in 'socks':beheben.
Obst

41

Falls jemand all diese älteren Antworten ausprobiert hat und immer noch auf Probleme stößt wie:

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',))

Dies kann daran liegen, dass standardmäßig requestsDNS-Abfragen auf der lokalen Seite der Verbindung aufgelöst werden.

Versuchen Sie, Ihre Proxy-URL von auf socks5://proxyhost:1234zu ändern socks5h://proxyhost:1234. Beachten Sie das Extra h(es steht für Hostnamenauflösung).

Die Standardeinstellung des PySocks-Paketmoduls ist die Remote-Auflösung , und ich bin mir nicht sicher, warum die Integration von Anfragen so dunkel voneinander abweicht , aber hier sind wir.


5
Das war genau mein Problem! Vielen Dank!
Xbeta

3
Das war genau das Problem für mich. Es wurden keine DNS-Abfragen über den Proxy ausgeführt. Sobald ich das h hinzufügte, funktionierte alles richtig.
Jamescampbell

1
Vielen Dank, der socks5hAnsatz ist so viel sauberer als die Problemumgehung beim Affen-Patching, von der ich befürchtet hatte, dass ich sie vorher tun müsste.
Darien

1
Sehr schön. Ich konnte socks5h://nirgendwo eine Python-Dokumentation zu Proxys finden. Muss an den falschen Stellen gesucht haben. Muss ich so lieben.
Ligemer

1
@ Ligemer manchmal ist der Code der einzig richtige Ort, um nachzuschauen. (Aber nachdem Sie sich den Code angesehen haben, aktualisieren Sie StackOverflow, und jetzt gibt es zwei richtige Stellen :))
Mahmoud Hashemi

17

Sie müssen Pysocks installieren , meine Version ist 1.0 und der Code funktioniert für mich:

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)

Toll! Es ist praktisch, wenn ich ein Paket (zB Flickrapi) über Socken 5 Proxy verwenden
möchte

2
Es ist keine gute Möglichkeit, den Socken-Proxy zu verwenden, da er den Standard-Socket ändert und Fehler macht. Wenn Sie ihn also nur testen, ist er in Ordnung, aber nicht für echte Dinge.
lqhcpsgbl

6

Sobald Python requestsmit SOCKS5Pull-Request zusammengeführt wird, ist dies so einfach wie die Verwendung des proxiesWörterbuchs:

#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)

Siehe SOCKS-Proxy-Unterstützung

Eine weitere Option für den Fall, dass Sie nicht warten können, requestbis Sie bereit sind, wenn Sie sie nicht verwenden können requesocks- wie bei GoogleAppEngine aufgrund des Fehlens eines pwdintegrierten Moduls -, ist die Verwendung der oben genannten PySocks :

  1. Holen Sie sich die socks.pyDatei aus dem Repo und legen Sie eine Kopie in Ihrem Stammordner ab.
  2. Hinzufügen import socksundimport socket

Zu diesem Zeitpunkt konfigurieren und binden Sie den Socket vor der Verwendung mit urllib2- im folgenden Beispiel:

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
Funktioniert das in der neuesten Requests-Version so? Ohne requesocks?
Gtx

Dies ist das proxiesWörterbuch für die letzte requestsPull-Anfrage, das zu diesem Zeitpunkt noch nicht zusammengeführt wurde. @see - github.com/kennethreitz/requests/pull/2953
loretoparisi

1

Ich habe pysocks und monkey patched create_connection in urllib3 wie folgt installiert:

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

Ich könnte das unter Linux machen.

$ pip3 install --user 'requests[socks]'
$ https_proxy=socks5://<hostname or ip>:<port> python3 -c \
> 'import requests;print(requests.get("https://httpbin.org/ip").text)'
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.