Проблемы с requests + threading
Хотел написать чекер для прокси, но столкнулся с проблемой при работе с многопоточностью.
Код выглядит так
Класс чекер
import requests as req
class Checker():
def __init__(self, normal_status_code=200, check_address="http://google.com"):
self.check_address = check_address
self.normal_status_code = normal_status_code
def check_proxy(self, proxy_dict):
try:
r = req.get(self.check_address, proxies=proxy_dict)
except req.exceptions.ProxyError:
return False
if r.status_code == self.normal_status_code:
return True
else:
return False
Соответсвенно если для каждого из наборов прокси порт вызвать метод check прокси то мы получим список нормальных проксей. Но это будет работать очень медленно, поэтому я использую библиотеку threading
from Checker import Checker
import threading
def check(proxy):
"""Функция для работы с многопоточностью"""
print(checker.check_proxy(proxy))
threads = 10
checker = Checker()
proxy_filename = "proxy.txt"
proxy_list = []
try:
f = open(proxy_filename, "r")
except FileNotFoundError:
filename = input("Введите название файла прокси ")
f = open(filename, "r")
for line in f:
proxy = "http://" + line
proxy = proxy.replace("\n", "")
proxy_list.append({"http": proxy})
print(proxy_list)
for i, proxy_dict in enumerate(proxy_list):
t = threading.Thread(target=check, name=f"thread {i}", args=proxy_dict)
t.start()
Этот код выдаёт вот такую ошибку:
[{'http': 'http://130.185.122.203:3128'}]
Exception in thread thread 0:
Traceback (most recent call last):
File "C:\Users\Alex\AppData\Local\Programs\Python\Python39\lib\threading.py", line 950, in _bootstrap_inner
self.run()
File "C:\Users\Alex\AppData\Local\Programs\Python\Python39\lib\threading.py", line 888, in run
self._target(*self._args, **self._kwargs)
File "C:\Users\Alex\PycharmProjects\Proxy\main.py", line 7, in check
print(checker.check_proxy(proxy))
File "C:\Users\Alex\PycharmProjects\Proxy\Checker.py", line 21, in check_proxy
r = req.get(self.check_address, proxies=proxy_dict)
File "C:\Users\Alex\PycharmProjects\Proxy\venv\lib\site-packages\requests\api.py", line 76, in get
return request('get', url, params=params, **kwargs)
File "C:\Users\Alex\PycharmProjects\Proxy\venv\lib\site-packages\requests\api.py", line 61, in request
return session.request(method=method, url=url, **kwargs)
File "C:\Users\Alex\PycharmProjects\Proxy\venv\lib\site-packages\requests\sessions.py", line 532, in request
settings = self.merge_environment_settings(
File "C:\Users\Alex\PycharmProjects\Proxy\venv\lib\site-packages\requests\sessions.py", line 710, in merge_environment_settings
no_proxy = proxies.get('no_proxy') if proxies is not None else None
AttributeError: 'str' object has no attribute 'get'
Process finished with exit code 0
Ответы (1 шт):
Автор решения: Roman Konoval
→ Ссылка
Проблема в том, что вы передаете параметры функции потока в конструктор Thread неправильно.
Аргумент args трактуется конструктором Thread как последовательность и, соответственно, аргумент функции, если он единственный, нужно передавать в контейнере, например в кортеже:
t = threading.Thread(target=check, name=f"thread {i}", args=(proxy_dict,))
Этот пример демонстрирует разницу:
def f(*params):
print(params)
# тут каждый элемент последовательности т.е. каждый символ
# будет передан как отдельный параметр в f
# будет напечатано `('a', 'b', 'c')`
t = threading.Thread(target=f, args='abc')
t.start()
t.join()
# тут 'abc' будет передан как один параметр в f
# будет напечатано `('abc')`
t = threading.Thread(target=f, args=('abc',))
t.start()
t.join()