Загрузчик Python - PullRequest
       19

Загрузчик Python

2 голосов
/ 04 ноября 2010

Итак, я пытаюсь написать скрипт для загрузки файла изображения с помощью python, и я нашел это определение с помощью Google, но каждая картинка, которую я загружаю, получается "поврежденной".Любые идеи ...

def download(url):
 """Copy the contents of a file from a given URL
 to a local file.
 """
 import urllib
 webFile = urllib.urlopen(url)
 localFile = open(url.split('/')[-1], 'w')
 localFile.write(webFile.read())
 webFile.close()
 localFile.close()

Редактировать: тег кода не очень хорошо сохранил отступы, но я могу заверить вас, что они есть, это не моя проблема.

Ответы [ 5 ]

6 голосов
/ 04 ноября 2010

Вы можете просто сделать

urllib.urlretrieve(url, filename)

и избавь себя от неприятностей.

5 голосов
/ 04 ноября 2010

Вам нужно открыть локальный файл в двоичном режиме:

localFile = open(url.split('/')[-1], 'wb')

В противном случае символы CR / LF в двоичном потоке будут искажены, что приведет к повреждению файла.

3 голосов
/ 04 ноября 2010

Вы должны включить флаг 'b', если намереваетесь записать двоичный файл. Строка 7 становится:

localFile = open(url.split('/')[-1], 'wb')

Код не обязательно должен работать, но в будущем вы можете подумать:

  • Импорт за пределы ваших функций.
  • Использование os.path.basename вместо анализа строки для получения компонента имени пути.
  • Использование оператора with для управления файлами, а не их ручное закрытие. Это делает ваш код чище, и гарантирует, что они правильно закрыты, если ваш код вызывает исключение.

Я бы переписал ваш код как:

import urllib
import os.path

def download(url):
 """Copy the contents of a file from a given URL
 to a local file in the current directory.
 """
 with urllib.urlopen(url) as webFile:
  with open(os.path.basename(url), 'wb') as localFile:
   localFile.write(webFile.read())
2 голосов
/ 19 октября 2012

Он выходит из строя, потому что функция, которую вы используете, записывает байты в файл, как если бы это был простой текст. Однако вам нужно записать байты в двоичном режиме (wb). Вот идея того, что вы должны делать:

import urllib

def Download(url, filename):
  Data = urllib.urlopen(url).read()
  File = open(filename, 'wb')
  File.Write(Data)
  #Neatly close off the file...
  File.flush()
  File.close()
  #Cleanup, for you neat-freaks.
  del Data, File
0 голосов
/ 04 ноября 2010
import subprocess
outfile = "foo.txt"
url = "http://some/web/site/foo.txt"
cmd = "curl.exe -f -o %(outfile)s %(url)s" % locals()
subprocess.check_call(cmd)

Выделение может показаться не элегантным, но когда вы начинаете сталкиваться с проблемами на более сложных сайтах, но curl обладает богатой логикой для обработки вас через барьеры, представленные веб-серверами (куки, аутентификация, сеансы и т. д.)

wget является еще одной альтернативой.

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