Python скачать несколько файлов в цикле - PullRequest
1 голос
/ 28 марта 2012

У меня проблемы с моим кодом.

#!/usr/bin/env python3.1

import urllib.request;

# Disguise as a Mozila browser on a Windows OS
userAgent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)';

URL = "www.example.com/img";
req = urllib.request.Request(URL, headers={'User-Agent' : userAgent});

# Counter for the filename.
i = 0;

while True:
    fname =  str(i).zfill(3) + '.png';
    req.full_url = URL + fname;

    f = open(fname, 'wb');

    try:
        response = urllib.request.urlopen(req);
    except:
        break;
    else:
        f.write(response.read());
        i+=1;
        response.close();
    finally:
        f.close();

Проблема возникает, когда я создаю объект urllib.request.Request (называемый req).Я создаю его с несуществующим URL, но позже я изменяю URL на тот, который должен быть.Я делаю это так, чтобы я мог использовать один и тот же объект urllib.request.Request и не создавать новые на каждой итерации.Вероятно, в python есть механизм, который делает именно это, но я не уверен, что это такое.

EDIT Сообщение об ошибке:

>>> response = urllib.request.urlopen(req);
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.1/urllib/request.py", line 121, in urlopen
    return _opener.open(url, data, timeout)
  File "/usr/lib/python3.1/urllib/request.py", line 356, in open
    response = meth(req, response)
  File "/usr/lib/python3.1/urllib/request.py", line 468, in http_response
    'http', request, response, code, msg, hdrs)
  File "/usr/lib/python3.1/urllib/request.py", line 394, in error
    return self._call_chain(*args)
  File "/usr/lib/python3.1/urllib/request.py", line 328, in _call_chain
    result = func(*args)
  File "/usr/lib/python3.1/urllib/request.py", line 476, in http_error_default
    raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 403: Forbidden

РЕДАКТИРОВАТЬ 2 : Мое решение заключается в следующем.Вероятно, следовало сделать это с самого начала, так как я знал, что это сработает:

import urllib.request;

# Disguise as a Mozila browser on a Windows OS
userAgent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)';

# Counter for the filename.
i = 0;

while True:
    fname =  str(i).zfill(3) + '.png';
    URL = "www.example.com/img" + fname;

    f = open(fname, 'wb');

    try:
        req = urllib.request.Request(URL, headers={'User-Agent' : userAgent});
        response = urllib.request.urlopen(req);
    except:
        break;
    else:
        f.write(response.read());
        i+=1;
        response.close();
    finally:
        f.close();

Ответы [ 3 ]

5 голосов
/ 28 марта 2012

urllib2 подходит для небольших сценариев, которым требуется только одно или два сетевых взаимодействия, но если вы выполняете гораздо больше работы, вы, вероятно, обнаружите, что либо urllib3, либо requests (который не случайно основан на первом), может лучше удовлетворить ваши потребности. Ваш конкретный пример может выглядеть так:

from itertools import count
import requests

HEADERS = {'user-agent': 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'}
URL = "http://www.example.com/img%03d.png"

# with a session, we get keep alive
session = requests.session()

for n in count():
    full_url = URL % n
    ignored, filename = URL.rsplit('/', 1)

    with file(filename, 'wb') as outfile:
        response = session.get(full_url, headers=HEADERS)
        if not response.ok:
            break
        outfile.write(response.content)

Редактировать: Если вы можете использовать обычную HTTP-аутентификацию (для которой настоятельно рекомендуется ответ 403 Forbidden), то вы можете добавить ее к requests.get с параметром auth, например:

response = session.get(full_url, headers=HEADERS, auth=('username','password))
0 голосов
/ 28 марта 2012

Если вы хотите использовать пользовательский агент пользователя с каждым запросом, вы можете создать подкласс FancyURLopener.

. Вот пример: http://wolfprojects.altervista.org/changeua.php

0 голосов
/ 28 марта 2012

Не ломайся, когда получаешь исключение. Изменение

except:
    break

до

except:
    #Probably should log some debug information here.
    pass

Это пропустит все проблемные запросы, так что никто не остановит весь процесс.

...