3

Ich habe einen Scraper (basierend auf Python 3.4.2 und asyncio/aiohttp libs) und Bündel von Links (> 10K), um einige kleine Datenmenge zu retrollen. Teil Schaber Code:Zukünftige Ausnahme wurde nie abgerufen

@asyncio.coroutine 
def prepare(self, links): 
    semaphore = asyncio.Semaphore(self.limit_concurrent) 
    tasks = [] 
    result = [] 

    tasks = [self.request_data(link, semaphore) for link in links] 

    for task in asyncio.as_completed(tasks): 
     response = yield from task 
     if response: 
      result.append(response) 
     task.close() 
    return result 

@asyncio.coroutine 
def request_data(self, link, semaphore): 

    ... 

    with (yield from semaphore): 
     while True: 
      counter += 1 
      if counter >= self.retry: 
       break 
      with aiohttp.Timeout(self.timeout): 
       try: 
        response = yield from self.session.get(url, headers=self.headers) 
        body = yield from response.read() 
        break 
       except asyncio.TimeoutError as err: 
        logging.warning('Timeout error getting {0}'.format(url)) 
        return None 
       except Exception: 
        return None 
    ... 

Whan es versucht, Anfragen ungültiger URL zu machen, ich Meldungen wie diese:

Future exception was never retrieved 
future: <Future finished exception=gaierror(11004, 'getaddrinfo failed')> 
Traceback (most recent call last): 
    File "H:\Python_3_4_2\lib\concurrent\futures\thread.py", line 54, in run 
    result = self.fn(*self.args, **self.kwargs) 
    File "H:\Python_3_4_2\lib\socket.py", line 530, in getaddrinfo 
    for res in _socket.getaddrinfo(host, port, family, type, proto, flags): 
socket.gaierror: [Errno 11004] getaddrinfo failed 

Der Fehler occures wenn sie versuchen, Antwort von session.get zu ergeben. Wie ich verstehe, wurde die Ausnahme nie von asyncio konsumiert und so war es nicht "babble up".

Erste tryed ich einfach Anfrage von Versuch wickeln/außer:

try: 
    response = yield from self.session.get(url, headers=self.headers) 
except Exception: 
    return None 

Dies funktioniert nicht.

Dann ich read here über Verkettung Koroutinen, Ausnahme zu fangen, aber das hat auch nicht für mich arbeiten. Ich bekomme diese Nachrichten und Skripts immer noch nach einer gewissen Zeit abstürzen.

Also meine Frage - wie kann ich mit dieser Ausnahme richtig umgehen?

Antwort

1

keine Antwort auf Ihre Frage, aber vielleicht eine Lösung für Ihr Problem, je nachdem, ob Sie nur wollen, dass der Code funktioniert oder nicht.

Ich würde die URLs validieren, bevor ich sie anfordere. Ich hatte viele Kopfschmerzen mit dieser Art von Dingen, die versuchten, einige Daten zu sammeln, also entschied ich, sie im Voraus zu beheben und fehlerhafte URLs in einem Protokoll zu melden.

Sie können djangos regex oder anderen Code verwenden, um dies zu tun, wie es öffentlich verfügbar ist.

In dieser Frage gibt eine Person die Validierung Regex für Django. Python - How to validate a url in python ? (Malformed or not)

+0

Ja, ich schaute in diese Richtung, aber es gibt andere Probleme. Kleine Untersuchungen zeigen, dass nicht alle Links dazu führen, dass dieser Fehler fehlerhaft ist. Einige von ihnen haben nur Weiterleitungen oder WebSocket-Server anstelle von http (s). Ich denke, in diesem Fall ist es besser, eine Ausnahme zu bekommen. – Charnel

+1

vielleicht können Sie eine Debug-Traceback über die Methoden, die hier diskutiert werden: https://docs.python.org/3/library/asyncio-dev.html#detect-exceptions-never-consumed vielleicht gibt es weitere Informationen auf Was genau löst es aus? Wie auch immer, viel Glück, Schaber kann ein Albtraum sein, um aufrechtzuerhalten und weiterzumachen ^^ – user7296055

Verwandte Themen