2017-09-05 35 views
0

良い日、私はPythonで非同期のものをマスターしようとしていて、簡単に解決できるはずの状況に陥っていますが、私はまだ何が間違っているのですか?私はプロキシのリストを持っていると私はサーバーが起動し、実行しているかどうかを確認したいと思うと私は非同期的な方法でそれをやってほしいと思っています残念ながら同期機能との比較は、Python非同期プロキシステータスチェック

ので、コードに:非同期checkProxiesの実行の

import requests 
import os 
import asyncio 

from lxml import html 


class GetUkProxy: 
    url = "https://free-proxy-list.net/uk-proxy.html" 

    def __init__(self): 
     self.getProxyList(self.url) 

    def getProxyList(self, url): 
     self.proxies = [] 
     data = requests.get(url) 
     response = html.fromstring(data.text) 
     for item in response.xpath('//table[@id="proxylisttable"]/tbody/tr'): 
      ip, port = item.getchildren()[:2] 
      self.proxies.append({'IP': ip.text, 'Port': port.text, 'Status': 'unknown'}) 

    def printProxies(self): 
     try: 
      for proxy in self.proxies: 
       print(proxy['IP'] + ':' + proxy['Port'], proxy['Status']) 
     except: 
      print("Proxy list is empty") 

    def checkProxies(self): 
     loop = asyncio.get_event_loop() 
     data = loop.run_until_complete(self.checkProxyList()) 
     loop.close() 


    async def checkProxyList(self): 
     try: 
      tasks = [] 
      for proxy in self.proxies[:10]: 
       task = asyncio.ensure_future(self.checkProxy(proxy)) 
       tasks.append(task) 
      await asyncio.gather(*tasks) 
     except: 
      print('Proxy list is empty') 

    async def checkProxy(self, proxy=None): 
     try: 
      check = os.system('ping -n 4 -w 2 ' + proxy['IP']) 
      if not check: 
       proxy['Status'] = 'Dead' 
      else: 
       proxy['Status'] = 'Alive' 
     except Exception as exp: 
      print(exp) 

    def syncCheck(self): 
     for item in self.proxies[:10]: 
      check = os.system('ping -n 4 -w 2 ' + item['IP']) 

時間同期同期検査の実行時間に等しいので、任意のアイデアは間違いの根本何であり、それはある解決方法ようこそ。

答えて

1

os.systemは、イベントループをブロックする同期関数です。

asyncio.create_subprocess_execを使用してシステムコマンドを非同期で実行し、イベントループをブロックしないようにすることができます。

async def checkProxy(self, proxy=None): 
    try: 
     check = await asyncio.create_subprocess_exec(
      'ping', '-c', '4', '-W', '2', proxy['IP'], stdout=asyncio.subprocess.PIPE) 
     out, error = await check.communicate() 

     proxy['Status'] = 'Alive' 

     if error: 
      proxy['Status'] = 'Dead' 
    except Exception as exp: 
     print(exp) 

編集:checkProxies方法では、一緒に実行するための先物のリストを作ります。

def checkProxies(self): 
    loop = asyncio.get_event_loop() 
    proxies = self.proxies[:10] 
    tasks = [self.checkProxy(proxy) for proxy in proxies] 


    loop.run_until_complete(
     asyncio.gather(
      *tasks 
     ) 
    ) 

    loop.close() 

uk = GetUkProxy() 
uk.checkProxies() 
print(uk.proxies) 
+0

ありがとうございました。 Offtop:あなたの答えに示されているようなasyncioのものを勉強するための本/記事/チュートリアルをお勧めしますか? –

+0

うーん、問題がある - それは速く実行しているが、実行後のプロキシのステータスは不明のままで、外に出てエラーとなり、決して満たされないようだ。コードをもう一度見てください。 –

+0

これは 'self.proxies [:10]'をスライスするときに 'self.proxies'のコピーを使用しているからです。参考までに、「vanheemスライド」(https://github.com/vangheem/asyncio-presentation/tree/master)と「ProgrammerCreekの例」(https://www.programcreek.com/python)を参照してください。/index/5526/asyncio) –

関連する問題