Martin Kroll
Martin Kroll

Reputation: 219

Python: HTTP request using two proxies at the same time in a defined order

Is it possible to send a HTTP request using two (or more) proxies at the same time in Python? The order of proxy servers matters! (Additional info: 1st proxy is Socks5 and requires authentication. 2nd is HTTP, no auth).

client -> Socks5 Proxy Server -> HTTP Proxy Server -> resource

The requests library allows only one proxy at a time:

import requests
from requests.auth import HTTPProxyAuth


url = 'http://example.com'

proxy_1 = {
    'http': 'socks5://host:port',
    'https': 'socks5://host:port'
}
auth = HTTPProxyAuth('user', 'password')

# second proxy is not accepted by requests api
# proxy_2 = {
#     'http': 'http://host:port',
#     'https': 'http://host:port'
# }

requests.get(url, proxies=proxy_1, auth=auth)

I need all this to check if proxy_2 is working while being behind proxy_1. May be there is a better way to do it?

Upvotes: 4

Views: 1378

Answers (2)

Martin Kroll
Martin Kroll

Reputation: 219

Two basic ways to do proxy chaining in python:

1 modified this answer to be used when FIRST proxy requires auth:

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
    # creating connection to 1st proxy
    sock.connect((proxy_host, proxy_port))

    # connecting to 2nd proxy
    # auth creds are for the FIRST proxy while here you connect to the 2nd one
    request = b"CONNECT second_proxy_host:second_proxy_port HTTP/1.0\r\n" \
              b"Proxy-Authorization: Basic b64encoded_auth\r\n" \
              b"Connection: Keep-Alive\r\n" \
              b"Proxy-Connection: Keep-Alive\r\n\r\n"
    sock.send(request)
    print('Response 1:\n' + sock.recv(40).decode())

    # this request will be sent through chain of two proxies
    # auth creds are still for the FIRST proxy
    request2 = b"GET http://www.example.com/ HTTP/1.0\r\n" \
               b"Proxy-Authorization: Basic b64encoded_auth=\r\n" \
               b"Connection: Keep-Alive\r\n" \
               b"Proxy-Connection: Keep-Alive\r\n\r\n"
    sock.send(request2)
    print('Response 2:\n' + sock.recv(4096).decode())

2 Using PySocks:

# pip install pysocks
import socks

with sock.socksocket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.setproxy(proxytype=socks.PROXY_TYPE_SOCKS5,
               addr="proxy1_host",
               port=8080,
               username='user',
               password='password')
    s.connect(("proxy2_host", 8080))

    message = b'GET http://www.example.com/ HTTP/1.0\r\n\r\n'
    s.sendall(message)
    response = s.recv(4069)
    print(response.decode())

Upvotes: 4

Aleks Kuznetsov
Aleks Kuznetsov

Reputation: 570

You could try using proxychains

Something like this

proxychains4 python test.py
#test.py
import requests
r = requests.get("https://ipinfo.io/ip")
print(r.content)

Or check out this and this questions

Also, you could try using selenium instead of requests and play with web driver settings

Upvotes: 3

Related Questions