Socks5Proxy

Tetapan Proxy Python requests, Menyambungkan SOCKS5 dan HTTP Proxy

Panduan langkah demi langkah untuk menyambung HTTP dan SOCKS5 proxy Socks5Proxy ke pustaka Python requests, pengesahan username/password, serta kod putaran senarai dan percubaan semula.

Apa yang perlu disediakan?

Anda memerlukan Python 3.8 ke atas dan pustaka requests. Untuk menggunakan SOCKS5, anda perlu memasang pakej sokongan SOCKS. Memasang requests[socks] akan memasang PySocks dan membolehkan anda menggunakan alamat socks5 dan socks5h.

Maklumat proksi boleh dilihat di skrin proksi saya di dashboard. Contoh ini menggunakan IP 198.51.100.23, port HTTP 8000, port SOCKS5 1080, nama pengguna spx_user, kata laluan spx_pass. Gantikan dengan nilai sebenar anda.

pip install "requests[socks]"

Bagaimana cara menghubungkan HTTP proxy?

requests menghantar permintaan melalui proksi apabila alamat ditambah dalam kamus proxies. Penting untuk menambah alamat proksi HTTP yang sama untuk kedua-dua kunci http dan https. Tanpa kunci https, permintaan ke alamat HTTPS akan keluar tanpa melalui proksi.

Permintaan situs HTTPS melewati proxy dengan metode CONNECT, sehingga konten dikirimkan terenkripsi dari awal hingga akhir. Kode di bawah ini adalah contoh meminta alamat pemeriksaan IP dan memeriksa apakah respons menunjukkan IP proxy.

import requests

proxy = "http://spx_user:spx_pass@198.51.100.23:8000"
proxies = {"http": proxy, "https": proxy}

r = requests.get("https://api.ipify.org?format=json", proxies=proxies, timeout=20)
print(r.status_code, r.json())  # the "ip" field should show the proxy IP

Bagaimana untuk menyambung ke proksi SOCKS5?

Disarankan untuk menggunakan socks5h di hadapan alamat. socks5h membolehkan pengesahan nama domain dilakukan oleh proxy, supaya permintaan DNS dari pelayan anda tidak terdedah dan diselesaikan berdasarkan negara proxy. Jika menggunakan socks5, nama domain akan diselesaikan oleh pelayan anda sebelum IP dihantar ke proxy.

Anda perlu menggunakan port SOCKS5. Jika anda memasukkan alamat SOCKS5 ke port HTTP, sambungan tidak akan berjaya, jadi sila bezakan dua port pada setiap baris.

import requests

proxy = "socks5h://spx_user:spx_pass@198.51.100.23:1080"
proxies = {"http": proxy, "https": proxy}

r = requests.get("https://api.ipify.org?format=json", proxies=proxies, timeout=20)
print(r.json())

Bagaimana untuk mengitar pelbagai proksi untuk menghantar permintaan?

Apabila mengumpul banyak halaman, kaedah asas adalah menerima senarai dan menggunakan proksi seterusnya untuk setiap permintaan. Kod di bawah menerima senarai SOCKS5 melalui API dan menggunakannya secara bergilir, menghantar semula permintaan yang gagal ke proksi lain sehingga 3 kali. Ia juga memasukkan masa rehat untuk mengelakkan permintaan terlalu cepat ke domain yang sama.

Lebih baik membiarkan proksi yang gagal berehat sebentar sebelum menggunakannya semula daripada membuangnya terus. Selalunya, ralat sementara disebabkan oleh keadaan laman sasaran.

import itertools
import time
import requests

API = "https://socks5proxy.io/api/v1"
KEY = "YOUR_API_KEY"

lines = requests.get(
    API + "/proxies/download",
    params={"format": "user:pass@ip:port", "protocol": "socks5"},
    headers={"Authorization": "Bearer " + KEY},
    timeout=30,
).text.split()
pool = itertools.cycle(lines)

def fetch(url, tries=3):
    for _ in range(tries):
        p = "socks5h://" + next(pool)
        try:
            r = requests.get(url, proxies={"http": p, "https": p}, timeout=20)
            if r.status_code == 200:
                return r.text
        except requests.RequestException:
            pass
        time.sleep(1)
    return None

for page in range(1, 6):
    html = fetch("https://example.com/list?page=" + str(page))
    print(page, "ok" if html else "failed")
    time.sleep(0.5)

Bagaimana untuk mengekalkan sesi dan kuki?

Untuk aliran yang memerlukan kesinambungan kuki seperti log masuk atau menukar halaman, gunakan satu proxy tetap untuk satu requests.Session. Masukkan alamat ke atribut proxies objek sesi, dan semua permintaan dari sesi tersebut akan keluar melalui IP yang sama. Tutup sesi apabila aliran selesai dan buat sesi baru dengan proxy seterusnya.

Jika anda juga menetapkan header User-Agent dan Accept-Language untuk setiap sesi, paparan di laman web sasaran akan menjadi konsisten.

import requests

s = requests.Session()
s.proxies = {
    "http": "http://spx_user:spx_pass@198.51.100.23:8000",
    "https": "http://spx_user:spx_pass@198.51.100.23:8000",
}
s.headers.update({"User-Agent": "Mozilla/5.0", "Accept-Language": "en-US,en;q=0.9"})

s.get("https://example.com/", timeout=20)          # cookies are stored in the session
r = s.get("https://example.com/account", timeout=20)  # same IP, same cookies
print(r.status_code)
s.close()

Bagaimana cara menggunakannya dengan pengesahan IP?

Daftarkan IPv4 pelayan yang menjalankan kod ini di papan pemuka, kemudian anda boleh menggunakan alamat tanpa nama pengguna dan kata laluan. Ini memudahkan penyebaran kod yang sama ke pelbagai pelayan tanpa menyimpan kata laluan dalam kod atau fail konfigurasi. Anda juga boleh memilih format ip:port semasa memuat turun senarai.

import requests

proxy = "http://198.51.100.23:8000"  # no user or password, server IP is authorized in the dashboard
r = requests.get("https://api.ipify.org", proxies={"http": proxy, "https": proxy}, timeout=20)
print(r.text)

Bagaimana untuk menghantar pelbagai permintaan dengan cepat secara serentak?

requests menunggu sehingga satu permintaan selesai, jadi untuk memuat turun banyak halaman dengan cepat, anda perlu menjalankan beberapa tugas serentak. Cara termudah adalah dengan ThreadPoolExecutor dari concurrent.futures. Dengan mengekalkan bilangan tugas di bawah bilangan proksi, permintaan tidak akan tertumpu pada satu IP.

Kod di bawah membahagikan senarai alamat kepada 20 pekerja, setiap tugas memilih proksi seterusnya dari senarai. itertools.cycle boleh digunakan bersama dalam pelbagai thread tanpa masalah, tetapi jika urutan tepat diperlukan, gunakan kunci bersama.

import itertools
from concurrent.futures import ThreadPoolExecutor
import requests

lines = open("proxies.txt").read().split()  # user:pass@ip:port per line
pool = itertools.cycle(lines)

def get(url):
    p = "http://" + next(pool)
    try:
        return url, requests.get(url, proxies={"http": p, "https": p}, timeout=20).status_code
    except requests.RequestException as e:
        return url, type(e).__name__

urls = ["https://example.com/item/" + str(i) for i in range(200)]
with ThreadPoolExecutor(max_workers=20) as ex:
    for url, result in ex.map(get, urls):
        print(url, result)

Bolehkah saya menggunakan pustaka asinkron seperti httpx atau aiohttp?

Ya. httpx memungkinkan Anda menambahkan alamat proxy saat membuat klien, dan SOCKS5 dapat digunakan dengan menginstal httpx[socks]. Klien asinkron AsyncClient juga menerima argumen yang sama.

aiohttp memerlukan alamat proksi HTTP dalam argumen proxy untuk setiap permintaan, dan proxy_auth dengan aiohttp.BasicAuth. aiohttp tidak menyokong SOCKS secara lalai, jadi untuk SOCKS5 anda perlu menggunakan penyambung dari pakej aiohttp-socks.

Kaedah asinkron boleh memproses beribu-ribu permintaan dengan sumber yang sedikit secara serentak, tetapi jika bilangan permintaan serentak tidak dihadkan, ia boleh membanjiri laman web sasaran dan proksi sekaligus. Tetapkan bilangan permintaan yang boleh dijalankan serentak menggunakan asyncio.Semaphore.

import httpx

with httpx.Client(proxy="http://spx_user:spx_pass@198.51.100.23:8000", timeout=20) as client:
    print(client.get("https://api.ipify.org").text)

Bagaimana cara menyelesaikan kesalahan yang sering terjadi?

Ralat 'Missing dependencies for SOCKS support' bermaksud requests[socks] belum dipasang. Sila pasang semula dalam persekitaran maya yang sama.

407 Proxy Authentication Required berlaku apabila nama pengguna atau kata laluan salah, atau apabila pengesahan IP digunakan tetapi IP pelayan tidak didaftarkan. Jika kata laluan mengandungi aksara khas, anda perlu menggantikannya dengan urllib.parse.quote.

Masa tamat sambungan selalunya disebabkan oleh port yang tidak sepadan. Pastikan anda menggunakan port HTTP untuk alamat HTTP dan port SOCKS5 untuk alamat socks5h. Memasukkan nilai timeout pasti dapat menghalang permintaan tanpa respons daripada menghentikan keseluruhan tugas.

  • Ralat SOCKS: pip install "requests[socks]"
  • 407: Semula nama pengguna·kata laluan atau IP yang didaftarkan
  • Masa tamat: Bezakan antara port HTTP dan SOCKS5
  • Tambahkan timeout pada semua permintaan
Tetapan Proxy Python requests, Menyambungkan SOCKS5·HTTP | Socks5Proxy