Настройка прокси-серверов при обходе веб-сайтов с помощью Python

#python #proxy #request #web-crawler

Вопрос:

Я хочу установить прокси-серверы для своего сканера. Я использую модуль запросов и Красивый суп. Я нашел список ссылок API, которые предоставляют бесплатные прокси с 4 типами протоколов.

Все прокси с 3/4 протоколами работают (HTTP, SOCKS4, SOCKS5), кроме одного, и это прокси с протоколом HTTPS. Это мой код:

 from bs4 import BeautifulSoup
import requests
import random
import json

# LIST OF FREE PROXY APIS, THESE PROXIES ARE LAST TIME TESTED 50 MINUTES AGO, PROTOCOLS: HTTP, HTTPS, SOCKS4 AND SOCKS5
list_of_proxy_content = ["https://proxylist.geonode.com/api/proxy-list?limit=150amp;page=1amp;sort_by=lastCheckedamp;sort_type=descamp;filterLastChecked=50amp;country=CHamp;protocols=http,https,socks4,socks5",
                        "https://proxylist.geonode.com/api/proxy-list?limit=150amp;page=1amp;sort_by=lastCheckedamp;sort_type=descamp;filterLastChecked=50amp;country=FRamp;protocols=http,https,socks4,socks5",
                        "https://proxylist.geonode.com/api/proxy-list?limit=150amp;page=1amp;sort_by=lastCheckedamp;sort_type=descamp;filterLastChecked=50amp;country=DEamp;protocols=http,https,socks4,socks5",
                        "https://proxylist.geonode.com/api/proxy-list?limit=1500amp;page=1amp;sort_by=lastCheckedamp;sort_type=descamp;filterLastChecked=50amp;country=ATamp;protocols=http,https,socks4,socks5",
                        "https://proxylist.geonode.com/api/proxy-list?limit=150amp;page=1amp;sort_by=lastCheckedamp;sort_type=descamp;filterLastChecked=50amp;country=ITamp;protocols=http,https,socks4,socks5"]


# EXTRACTING JSON DATA FROM THIS LIST OF PROXIES
full_proxy_list = []
for proxy_url in list_of_proxy_content:
    
    proxy_json = requests.get(proxy_url).text
    proxy_json = json.loads(proxy_json)
    proxy_json = proxy_json["data"]

    full_proxy_list.extend(proxy_json)

# CREATING PROXY DICT
final_proxy_list = []
for proxy in full_proxy_list:

    #print(proxy) # JSON VALUE FOR ALL DATA THAT GOES INTO PROXY

    protocol = proxy['protocols'][0]
    ip_ = proxy['ip']
    port = proxy['port']
        
    proxy = {protocol : protocol   '://'   ip_   ':'   port}

    final_proxy_list.append(proxy)


# TRYING PROXY ON 3 DIFERENT WEBSITES
for proxy in final_proxy_list:

    print(proxy)
    try:
        r0 = requests.get("https://edition.cnn.com/", proxies=proxy, timeout = 15)
        if r0.status_code == 200:
            print("GOOD PROXY")
        else:
            print("BAD PROXY")
    except:
        print("proxy error")
        
    try:        
        r1 = requests.get("https://www.buelach.ch/", proxies=proxy, timeout = 15)
        if r1.status_code == 200:
            print("GOOD PROXY")        
        else:
            print("BAD PROXY")
    except:
        print("proxy error")
        
    try:      
        r2 = requests.get("https://www.blog.police.be.ch/", proxies=proxy, timeout = 15)
        if r2.status_code == 200:
            print("GOOD PROXY")        
        else:
            print("BAD PROXY")
    except:
        print("proxy error")

    print()
 

Мой вопрос в том, почему HTTPS-прокси не работают, что я делаю не так?

Мои прокси выглядят так:

 {'socks4': 'socks4://185.168.173.35:5678'}
{'http': 'http://62.171.177.80:3128'}
{'https': 'http://159.89.28.169:3128'}
 

Я видел, что иногда люди передают прокси таким образом:

 proxies = {"http": "http://10.10.1.10:3128",
           "https": "http://10.10.1.10:1080"}
 

Но у этого диктатора есть 2 протокола, но в ссылках он только http, почему?
Могу ли я передать только один, могу ли я передать 10 разных IP-адресов в этом дикте?

Комментарии:

1. Я работаю за прокси-сервером в офисе (работаю только с протоколами http/https/ftp). (Кстати, я не могу получить доступ к вашим прокси-серверам, они заблокированы здесь). AFAIK, запросы работают, если вы подключаете весь свой набор прокси-серверов (сопоставляя каждый протокол только с одним прокси-сервером) к запросам. Объект сеанса (с использованием session.proxies.update(…)) или в качестве аргумента для запроса.get / запроса.post / … Тот факт, что доступ к прокси-серверу https осуществляется по протоколу http, до сих пор не вызывал у меня никаких проблем.

Ответ №1:

В вашем коде есть несколько ошибок. Сначала я займусь низко висящими фруктами.

Во-первых, ваши прокси-серверы SOCKS тоже не работают. Вот почему. Правильный способ написания прокси-словаря можно найти в документации по запросам.

 # your way
proxy = {'socks4': 'socks4://ip:port'}

# the correct way
proxy = {'https': 'socks4://ip:port'}   # note the s in https

# or another correct way
proxy = {'http': 'socks4://ip:port'}  # Note the http with no s

# best correct way if your urls are mixed http:// https://
proxies = {
  'http': 'socks4://ip:port',
  'https': 'socks4://ip:port',
}

 

« http И https » в этих записях-это не протокол прокси-сервера, а ваш URL-адрес.

Например: https://www.example.com vs http://www.example.com .

Запрос на https:// URL-адрес будет отправлен в https запись, в то время как запрос на http:// URL-адрес будет проходить через http запись. Если вы укажете только одну запись {'http': 'socks4://ip:port'} , а URL-запрос предназначен для https:// URL-адреса, этот запрос не будет перенаправлен, и ваш собственный ip-адрес будет открыт. Поскольку такой вещи socks4://www.example.com , как просмотр, не существует, запросы, которые вы делали, не были проксированы.

При выполнении любой работы через прокси и VPN мне не нравится тестировать код и отправлять запросы на серверы, на которых я буду запускать окончательный код. Мне нравится использовать ipinfo.io. Их ответ json содержит информацию о подключающемся ip-адресе. Таким образом, я могу гарантировать, что соединение проходит через прокси-сервер и не посылает ложных срабатываний.

Примечание.Нередко IP-адрес подключения отличается от IP-адреса прокси-сервера из-за балансировщиков нагрузки. Просто убедитесь, что подключающийся ip-адрес не ваш собственный. Вы можете проверить свой собственный ip-адрес, посетив URL-адрес в приведенном ниже коде, используя свой браузер.

Поскольку вы использовали {'socks4': 'socks4://ip:port'} вместо правильного {'https': 'socks4://ip:port'} , вы все еще получали 200 кодов состояния, и ваш код возвращал ложное срабатывание. Он возвращал 200, потому что вы действительно подключались, но со своим собственным ip-адресом, а не через прокси-сервер.

Поскольку вы не предоставили подробностей о том, что на самом деле происходило, я добавил немного быстрой и грязной обработки ошибок в ваш код, чтобы узнать, что происходит. Некоторые ошибки связаны с конфигурацией на стороне сервера, так как большинству https-прокси потребуется какая-то аутентификация, например сертификат или логин (несмотря на то, что они «бесплатные» и «общедоступные».

Мой несовершенный, но рабочий код приведен ниже. Проверено на Python 3.8.12 . Ниже приведена информация об ошибках подключения к прокси-серверу.

ПОДСКАЗКА: Проверьте свои URL-адреса. country=CH в первом, вероятно, следует сказать country=CN и country=AT , вероятно, следует сказать country=AR . Мой код отражает это.

 from bs4 import BeautifulSoup
import requests
import json
import time

# LIST OF FREE PROXY APIS, THESE PROXIES ARE LAST TIME TESTED 50 MINUTES AGO
# PROTOCOLS: HTTP, HTTPS, SOCKS4 AND SOCKS5
list_of_proxy_content = [
    "https://proxylist.geonode.com/api/proxy-list?limit=150amp;page=1amp;sort_by=lastCheckedamp;sort_type=descamp;filterLastChecked=50amp;country=CNamp;protocols=http,https,socks4,socks5",
    "https://proxylist.geonode.com/api/proxy-list?limit=150amp;page=1amp;sort_by=lastCheckedamp;sort_type=descamp;filterLastChecked=50amp;country=FRamp;protocols=http,https,socks4,socks5",
    "https://proxylist.geonode.com/api/proxy-list?limit=150amp;page=1amp;sort_by=lastCheckedamp;sort_type=descamp;filterLastChecked=50amp;country=DEamp;protocols=http,https,socks4,socks5",
    "https://proxylist.geonode.com/api/proxy-list?limit=1500amp;page=1amp;sort_by=lastCheckedamp;sort_type=descamp;filterLastChecked=50amp;country=ARamp;protocols=http,https,socks4,socks5",
    "https://proxylist.geonode.com/api/proxy-list?limit=150amp;page=1amp;sort_by=lastCheckedamp;sort_type=descamp;filterLastChecked=50amp;country=ITamp;protocols=http,https,socks4,socks5",
]


# EXTRACTING JSON DATA FROM THIS LIST OF PROXIES
full_proxy_list = []
for proxy_url in list_of_proxy_content:

    proxy_json = requests.get(proxy_url).text
    proxy_json = json.loads(proxy_json)
    proxy_json = proxy_json["data"]

    full_proxy_list.extend(proxy_json)

    if not full_proxy_list:
        print("No proxies to check. Exiting...")
        exit
    else:
        print(f"Found {len(full_proxy_list)} proxy servers. Checking...n")

# CREATING PROXY DICT
final_proxy_list = []
for proxy in full_proxy_list:

    # print(proxy)  # JSON VALUE FOR ALL DATA THAT GOES INTO PROXY

    protocol = proxy["protocols"][0]
    ip_ = proxy["ip"]
    port = proxy["port"]

    proxy = {
        "https": protocol   "://"   ip_   ":"   port,
        "http": protocol   "://"   ip_   ":"   port,
    }

    final_proxy_list.append(proxy)

# TRYING PROXY ON 3 DIFERENT WEBSITES
for proxy in final_proxy_list:

    print(proxy)
    try:
        # Use ipinfo.io to test proxy ip
        url = "https://ipinfo.io/json?token=67e01402d14101"
        r0 = requests.get(url, proxies=proxy, timeout=15)

        if r0.status_code == 200:
            # The 3-line block below only works on ipinfo.io
            output = r0.json()
            real_ip = output["ip"]
            print(f"GOOD PROXY [IP = {real_ip}] {proxy}n")

            # Do something with the response
            html_page = r0.text
            soup = BeautifulSoup(r0.text, "html.parser")
            print(soup, "n")

            r0.close()  # close the connection so it can be reused

            # Break out of the proxy loop so we do not send multiple successful
            # requests to the same url. Info needed was already obtained.
            # Comment out to check all possible proxies during testing.
            break
        else:
            # If the response code is something other than 200,
            # it means the proxy worked, but the website did not.
            print(f"BAD URL: [status code: {r0.status_code}]n{r0.headers}n")
            r0.close()

        time.sleep(5)  # Don't overload the server

    except Exception as error:
        print(f"BAD PROXY: Reason: {str(error)}n")
 

Большинство ошибок, которые вы увидите, будут ошибкой тайм-аута, которая должна быть понятна сама по себе.

Другие ошибки-это ошибки на стороне сервера из-за их конфигурации, препятствующей подключению.

Краткий список, не вдаваясь в подробности:

  • Remote end closed connection without response является ли серверная часть просто категорически отказалась отправить ваш запрос, несмотря на подключение к нему.
  • 407 Proxy Authentication Required это одна из тех ошибок, о которых я упоминал выше. Это либо требует, чтобы вы предоставили пользователя/пропуск, либо сертификат.
  • [Errno 111] Connection refused это одна из тех ошибок, о которых я упоминал выше.

ВАЖНО: Если вы видите одну из следующих ошибок check_hostname requires server_hostname EOF occurred in violation of protocol или SSL: WRONG_VERSION_NUMBER после выполнения приведенного выше кода, понизьте рейтинг своей библиотеки urllib3. В некоторых из последних версий есть ошибка прокси-сервера, а также несколько других. Вы можете сделать это с помощью команды pip install -U urllib3==1.25.11 или python3 -m pip install -U urllib3==1.25.11 .

Ответ №2:

Я провел некоторое исследование по этой теме, и теперь я не понимаю, зачем вам нужен прокси для HTTPS.

Хотя понятно, что требуется прокси-сервер для HTTP, (HTTP не зашифрован) HTTPS безопасен.

Возможно ли, что ваш прокси-сервер не подключается, потому что он вам не нужен?

Я не эксперт по доверенности, поэтому приношу извинения, если выкладываю что-то совершенно глупое.


Но я не хочу оставлять тебя совсем с пустыми руками. Если вы ищете полную конфиденциальность, я бы предложил VPN. Как Windscribe, так и RiseUpVPN бесплатны и шифруют все ваши данные на вашем компьютере. (Настольная версия, а не расширение для браузера.)

Хотя это не полностью автоматизированный процесс, он все еще очень эффективен.

Комментарии:

1. Я пробовал это, но ничего не вышло

2. Я отредактировал свой ответ.

Ответ №3:

То, что вы ищете, — это класс для хранения прокси-серверов, которые периодически вращаются после операций в вашем обходчике (зависит от времени или инструкций), чтобы замаскировать вашу личность.

 proxies = {"http": "http://10.10.1.10:3128",
           "https": "http://10.10.1.10:1080"} 
 

Эти типы ip — адресов ссылаются на домен, который внутренне обновляет базовые ip-адреса и перенаправляет вас на один из ip-адресов, расположенных под доменом.

Большинство из них являются платными услугами.

Комментарии:

1. У меня есть список бесплатных прокси, но когда я ставлю https-прокси, он выдает мне ошибку, пожалуйста, запустите код mu, и вы увидите