Загрузка и обработка ошибок - PullRequest
0 голосов
/ 14 октября 2018

Я использовал функцию, которую я взял из книги Райана Митчелла «Зачистка с помощью Python» от O'Really:

import  sys
import  os.path
import  socket
import  random
import  urllib2
import  contextlib
import  diskCache
import  logging as logger
from bs4 import BeautifulSoup

DEFAULT_AGENT = 'Mozilla/5.0 Firefox/56.0'
DEFAULT_DELAY = 3
DEFAULT_RETRIES = 10
DEFAULT_TIMEOUT = 60
socket.setdefaulttimeout (DEFAULT_TIMEOUT)

def  download (url, delay=DEFAULT_DELAY, user_agent=DEFAULT_AGENT, proxies=None, \
        cache=None, num_retries=DEFAULT_RETRIES, timeout=DEFAULT_TIMEOUT, data=None):
    result = None
    if  cache:
        try:
            result = cache[url]
        except  KeyError:
            # url is not available in cache
            pass
        if  result is not  None  and  result['code'] is not None \
                and  num_retries > 0  and  500 <= result['code'] < 600:
            # server error so ignore result from cache and re-download
            result = None
    if result is None:
        proxy = random.choice(proxies) if proxies else None
        headers = {'User-agent': user_agent}
        result = call (url, headers, proxy=proxy, num_retries=num_retries, cache=cache)
        if  cache:
            # save result to cache
            cache[url] = result

    return  result['html']

def  call (url, headers, proxy, num_retries, cache=None, data=None):
    request = urllib2.Request(url, data, headers or {})
    with  contextlib.closing (urllib2.urlopen(request))  as  connection:
        try:
            logger.info ('Downloading: %s', url)
            html = connection.read ()
            code = connection.getcode ()
        except  Exception as e:
            logger.exception ('Download error:', str(e))
            if  cache:
                del  cache['url']
            html = None
            if  hasattr (e, 'code'):
                code = e.code
                if  num_retries > 0  and  500 <= code < 600:
                    return  download (url, headers, num_retries-1, data) # retry server errors
            else:
                code = None
    return {'html': html, 'code':code}

Я хотел бы знать, существует ли более простой способ обработкиошибки при загрузке URL.Я видел, что библиотека requests - это библиотека более высокого уровня и более простая, и, возможно, она могла бы упростить это.По крайней мере, как этот код будет для python3?

Это будет что-то вроде

"""Functions used by the fetch module"""

# Standard library imports
import time
import socket
import logging as logger
from typing import Dict, Optional

# Third party imports
import requests
from requests.exceptions import HTTPError, Timeout
from bs4 import BeautifulSoup

# Constants
DEFAULT_AGENT = 'Mozilla/5.0 Firefox/56.0'
DEFAULT_DELAY = 3
DEFAULT_RETRIES = 10
DEFAULT_TIMEOUT = 60
socket.setdefaulttimeout(DEFAULT_TIMEOUT)

def fetch(url: str, retries: Optional[int] = DEFAULT_RETRIES) -> Dict:
    """Download an url"""
    code = None
    try:
        logger.info('Downloading: %s', url)
        resp = requests.get(url)
        resp.raise_for_status()
        code = resp.status_code
    except (HTTPError, Timeout) as ex:
        logger.exception("Couldn't download %s", ex)
        return None
    if code is not None and retries > 0 and \
            500 <= code < 600: # Server error
        logger.info('Retrying download')
        time.sleep(DEFAULT_DELAY)
        return fetch(url, retries-1)

    return {'html': resp, 'code': code}

1 Ответ

0 голосов
/ 14 октября 2018

Как вы сказали, это намного проще с requests

resp = requests.get(url, headers=headers, timeout=timeout)
print(resp.status_code)
print(resp.text)
# for an API use resp.json()

По умолчанию исключений не возникает.Вы можете позвонить resp.raise_for_status(), если хотите вызвать исключение.

Подробнее см. http://docs.python -requests.org / en / master / user / quickstart /

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...