首页 文章

从未检索到未来的异常

提问于
浏览
3

我有一个刮刀(基于Python 3.4.2和asyncio / aiohttp库)和一堆链接(> 10K)来检索一些少量数据 . 刮刀代码的一部分:

@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
    ...

它试图向格式错误的URL发出请求,我收到这样的消息:

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

尝试从session.get生成响应时发生错误 . 据我所知,异常从未被asyncio消耗,所以它不是“喋喋不休” .

首先,我尝试通过try / except简单地包装请求:

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

这不起作用 .

然后我read here关于链接协程以捕获异常,但这对我也不起作用 . 经过一段时间后,我仍然会收到这些消息和脚本崩溃 .

所以我的问题 - 如何以正确的方式处理此异常?

1 回答

  • 2

    不是你的问题的答案,但也许是你的问题的解决方案,取决于你是否只是想让代码工作 .

    我会在请求之前验证URL . 我有很多令人头疼的尝试收集一些数据的东西,所以我决定提前修复它们,并将错误的网址报告给日志 .

    您可以使用django的正则表达式或其他代码来执行此操作,因为它是公开可用的 .

    在这个问题中,一个人为django提供了验证正则表达式 . Python - How to validate a url in python ? (Malformed or not)

相关问题