J'ai regardé une vidéo et j'ai essayé d'appliquer le code suivant
# pip install html5lib import requests from bs4 import BeautifulSoup from random import choice def get_proxy(): url = "https://www.sslproxies.org/" r = requests.get(url) soup = BeautifulSoup(r.content, 'html5lib') return {'https': 'https://' + choice(list(map(lambda x:x[0]+':'+x[1], list(zip(map(lambda x:x.text, soup.findAll('td')[::8]), map(lambda x:x.text, soup.findAll('td')[1::8]))))))} def proxy_request(request_type, url, **kwargs): proxy = get_proxy() req = requests.request(request_type, url, proxies=proxy, timeout=5, **kwargs) return req for __ in range(10): try: r = proxy_request('get', "https://api.ipify.org") except (TimeoutError, OSError) as e: print("Exception:", e) continue print(r.status_code) print(r.content) break
J'ai eu l'erreur de traceback suivante et je n'ai aucune idée
Traceback (most recent call last): File "C:\Users\Future\Desktop\Spyder\Demo.py", line 16, in proxy_request req = requests.request(request_type, url, proxies=proxy, timeout=5, **kwargs) File "C:\Users\Future\AppData\Local\Programs\Python\Python39\lib\site-packages\requests\api.py", line 61, in request return session.request(method=method, url=url, **kwargs) File "C:\Users\Future\AppData\Local\Programs\Python\Python39\lib\site-packages\requests\sessions.py", line 530, in request resp = self.send(prep, **send_kwargs) File "C:\Users\Future\AppData\Local\Programs\Python\Python39\lib\site-packages\requests\sessions.py", line 643, in send r = adapter.send(request, **kwargs) File "C:\Users\Future\AppData\Local\Programs\Python\Python39\lib\site-packages\requests\adapters.py", line 412, in send conn = self.get_connection(request.url, proxies) File "C:\Users\Future\AppData\Local\Programs\Python\Python39\lib\site-packages\requests\adapters.py", line 309, in get_connection proxy_manager = self.proxy_manager_for(proxy) File "C:\Users\Future\AppData\Local\Programs\Python\Python39\lib\site-packages\requests\adapters.py", line 193, in proxy_manager_for manager = self.proxy_manager[proxy] = proxy_from_url( File "C:\Users\Future\AppData\Local\Programs\Python\Python39\lib\site-packages\urllib3\poolmanager.py", line 492, in proxy_from_url return ProxyManager(proxy_url=url, **kw) File "C:\Users\Future\AppData\Local\Programs\Python\Python39\lib\site-packages\urllib3\poolmanager.py", line 429, in __init__ raise ProxySchemeUnknown(proxy.scheme) urllib3.exceptions.ProxySchemeUnknown: Not supported proxy scheme None During handling of the above exception, another exception occurred: Traceback (most recent call last): File "C:\Users\Future\Desktop\Spyder\Demo.py", line 22, in <module> r = proxy_request('get', "https://youtube.com") File "C:\Users\Future\Desktop\Spyder\Demo.py", line 20, in proxy_request return req UnboundLocalError: local variable 'req' referenced before assignment [Finished in 1.4s]
Le code final.
# pip install html5lib import requests from bs4 import BeautifulSoup from random import choice def get_proxy(): url = "https://www.sslproxies.org/" r = requests.get(url) soup = BeautifulSoup(r.content, 'html5lib') return {'https': choice(list(map(lambda x:x[0]+':'+x[1], list(zip(map(lambda x:x.text, soup.findAll('td')[::8]), map(lambda x:x.text, soup.findAll('td')[1::8]))))))} def proxy_request(request_type, url, **kwargs): while 1: try: proxy = get_proxy() req = requests.request(request_type, url, proxies=proxy, timeout=5, **kwargs) break except: pass return req r = proxy_request('get', "https://youtube.com") print(r)
5 Réponses :
Il semble que votre paramètre proxy soit égal à None. De cette façon, lorsque vous essayez de créer une demande, il y a une erreur et l'objet de demande n'est pas affecté.
Si vous voulez résoudre ce problème, vous pouvez faire 2 choses différentes:
proxy = get_proxy()
vous pouvez vérifier si ce n'est pas None et si c'est le cas, vous pouvez configurer vous-même un proxy par défaut.J'espère que cela a aidé!
Dans votre fonction proxy_request()
, définissez req
avant d' try
... except
, par exemple:
def proxy_request(request_type, url, **kwargs): req = None # <------------------------------- Here while 1: try: proxy = get_proxy() req = requests.request(request_type, url, proxies=proxy, timeout=5, **kwargs) break except: pass return req
L'explication:
Vous try
branche a échoué avant l' req = requests.request(...)
commande a été atteinte, de sorte que la branche , except
a été réalisée et son return req
commande voulait retour inconnue req
.
Merci beaucoup. Il n'y a plus d'erreurs maintenant. Mais j'ai essayé le code plusieurs fois et tout ce que j'ai est None. Y aura-t-il une chance d'obtenir une réponse?
@Yasser, ce n'était qu'un correctif. Maintenant je suis occupé, mais si personne ne le résout, je vais essayer de vous aider.
@Yasser, votre problème est maintenant résolu, voyez mon autre réponse .
try: proxy = get_proxy() req = requests.request(request_type, url, proxies=proxy, timeout=5, **kwargs) break except: pass return req The return req statement is inside the exception handler, which means it's executed only if an exception is raised during the call to get_proxy or requests.request. Either way, these will lead to req never being bound, hence UnboundLocalError.I expect you wanted to put the return req outside the while loop, though I would just replace the break with it, doing so leads to more straightforward and resilient behaviour.Also: A bare except is a very bad idea as it's going to catch things like keyboard interruption (Ctrl-C), meaning you'll have to go through the task manager when (not if!) your program fucks up. When an exception is raised, you just busy loop without even notifying the user of what's happening, without the UnboundLocalError it could just keep looping around calling sslproxies as fast as it can, that's a good way to get banned for abuse, especially when sslproxies clearly advertises that its proxy list is updated every 10 minutes. Picking a random proxy in the list is fine, but why are you not storing the list of proxies to pick from? See point above, the list is updated at most every 10 minutes and you're not doing any sort of pagination, you're going to get the same list every time. Just fetch the proxies list once outside the loop, then randomly pick a proxy to try from within.
Merci beaucoup monsieur. Je suis tellement novice en python. Pouvez-vous m'aider à saisir les procurations sous forme de liste, puis m'apprendre à tester cette liste?
Si vous souhaitez utiliser un proxy, je peux vous recommander d'utiliser une approche un peu différente et peut-être d'essayer d'utiliser un package python qui essaie de faire ce dont vous avez besoin.
Installez simplement les requêtes proxy et lisez la documentation pour plus d'aide
Installez-le en faisant -> pip install proxy-requests
et envoyer une demande de proxy par
r = ProxyRequests('https://api.ipify.org') r.get()
bien sûr, il existe un moyen d'envoyer une demande de publication et même de modifier les en-têtes de la demande comme vous le souhaitez
Merci beaucoup. J'ai essayé from proxy_requests import ProxyRequests
et from proxy_requests import ProxyRequests
essayé les lignes et je from proxy_requests import ProxyRequests
rien obtenu du tout. Est-ce que tu l'as essayé?
Je viens de regarder sa documentation de code et cela a fonctionné pour moi. github.com/rootVIII/proxy_requests En bas de page, vous verrez un exemple qu'il a fait et que j'ai trouvé très utile! C'est une bonne chose car vous pouvez jouer avec les en-têtes et envoyer une demande de publication et voir également le proxy qui était utilisé (peut être pratique parfois)
Pouvez-vous poster un exemple qui a fonctionné avec vous pour essayer de mon côté ??
Vous pouvez essayer ceci par exemple: à partir de proxy_requests import ProxyRequests h = {'User-Agent': 'NCSA Mosaic / 3.0 (Windows 95)'} r = ProxyRequests (' postman-echo.com/headers' ) r.set_headers (h ) r.get_with_headers () print (r.get_proxy_used ())
Merci beaucoup. J'ai exécuté le code et attendu environ deux minutes sans aucune réponse. C'est ce dont je parle.
Mon code n'a pas non plus renvoyé de sortie? parce que cela a fonctionné pour moi ...
Je veux dire que la ligne d'impression ne fonctionnait pas du tout. Cela signifie pour moi que cela n'a pas fonctionné. Ou que voulez-vous dire exactement?
Votre code ne fonctionne pas en raison d'un schéma manquant ( https://
) dans votre proxy renvoyé par votre fonction get_proxy()
- par exemple, il renvoie
for __ in range(10): try: r = proxy_request('get', "https://youtube.com") except (TimeoutError, OSError) as e: print("Exception:", e) continue print(r.status_code) print(r.content) break
au lieu du correct
r = proxy_request('get', "https://youtube.com") print(r)
Veuillez donc corriger votre déclaration de return
dans cette fonction - au lieu de votre
def proxy_request(request_type, url, **kwargs): proxy = get_proxy() req = requests.request(request_type, url, proxies=proxy, timeout=5, **kwargs) return req
utilisation
return {'https': 'https://' + choice(...)}
Note 1:
Vous pouvez simplifier votre autre fonction en déplaçant votre boucle et try
... except
bloc dans le niveau module (voir Note 2
):
return {'https': choice(...)}
(Vous pouvez inclure print(proxy)
et print(req.status_code)
à des fins de test.)
Note 2:
Vous pouvez déplacer votre boucle et try
... except
bloquer de cette fonction dans le niveau du module, c'est-à-dire lorsque vous appelez cette fonction - au lieu de votre
{'https': 'https://183.89.96.57:8080'}
utiliser par exemple
{'https': '183.89.96.57:8080'}
Note 3:
Je l'ai testé et ça marche - parfois timeout, parfois refus de connexion, mais parfois OK.
(Dans tous les cas, le problème était dans le serveur distant ou dans ma connexion lente.)
Merci beaucoup. J'ai mis à jour le code pendant que vous m'avez guidé. Veuillez jeter un œil à l'article principal. Maintenant, j'ai essayé le code trois fois sans succès pour obtenir un proxy fonctionnel. Est-il impossible d'obtenir un proxy fonctionnel gratuit?
@Yasser, avez-vous essayé d'augmenter le délai d'attente? Il est possible d'obtenir un proxy fonctionnel gratuit, j'ai eu une telle chance (mais pas très souvent avec ma connexion lente).
@Yasser, par exemple, ce proxy a fonctionné pour moi: 183.89.96.57:8080
J'ai augmenté le délai à 20 et pareil ... Je n'ai pas eu de chance d'obtenir des procurations gratuites.
@Yasser, j'ai utilisé timeout = 150 ;-)
Quelle valeur attendez-vous pour
req
si une exception est levée dans le bloc try?