如何使用正确的文件扩展名保存图像?

时间:2014-06-01 14:28:03

标签: python file python-2.7

我有一个解析HTML并将图像保存到磁盘的脚本。 但是,由于某种原因,它错误地输出了文件名。

在Windows中没有使用正确的文件扩展名保存文件。例如,图片应保存为<filename>.jpg<filename>.gif。而是保存图像,没有文件扩展名。

你能帮我看看为什么这个脚本没有在文件名中正确保存扩展名吗?

我正在运行Python 2.7。

""" Tumbrl downloader
This program will download all the images from a Tumblr blog """


from urllib import urlopen, urlretrieve
import os, sys, re


def download_images(images, path):
  for im in images:
    print(im)
    filename = re.findall("([^/]*).(?:jpg|gif|png)",im)[0]
    filename = os.path.join(path,filename)
    try:
      urlretrieve(im, filename.replace("500","1280"))
    except:
      try:
        urlretrieve(im, filename)
      except:
        print("Failed to download "+im)

def main():

  #Check input arguments
  if len(sys.argv) < 2:
    print("usage: ./tumblr_rip.py url [starting page]")
    sys.exit(1)

  url = sys.argv[1]

  if len(sys.argv) == 3:
    pagenum = int(sys.argv[2])
  else:
    pagenum = 1

  if (check_url(url) == ""):
    print("Error: Malformed url")
    sys.exit(1)

  if (url[-1] != "/"):
    url.append("/")

  blog_name = url.replace("http://", "")
  blog_name = re.findall("(?:.[^\.]*)", blog_name)[0]
  current_path = os.getcwd()
  path = os.path.join(current_path, blog_name)
  #Create blog directory
  if not os.path.isdir(path):
    os.mkdir(path)

  html_code_old = ""
  while(True):
    #fetch html from url
    print("\nFetching images from page "+str(pagenum)+"\n")
    f = urlopen(url+"page/"+str(pagenum))
    html_code = f.read()
    html_code = str(html_code)
    if(check_end(html_code, html_code_old, pagenum)):
      break

    images = get_images_page(html_code)
    download_images(images, path)

    html_code_old = html_code
    pagenum += 1


  print("Done downloading all images from " + url)


if __name__ == '__main__':
  main()

1 个答案:

答案 0 :(得分:3)

该行

filename = re.findall("([^/]*).(?:jpg|gif|png)",im)[0]

不按照您的想法行事。首先,点是未转义的,这意味着它将匹配任何角色,而不仅仅是一个时期。

但更大的问题是你搞砸了群体。您将在匹配中获取第一个组的值,这是括号内的第一个部分,仅为您提供没有扩展名的基本文件名。包含扩展名的第二组是一个单独的非捕获组。 (?:...)语法使组无法捕获。

我修复它的方法是在整个比赛中放置一组并使现有的组无法捕获。

re.findall("((?:[^/]*)\.(?:jpg|gif|png))",im)[0]

P.S。另一个问题是模式是贪婪的,因此它可以同时匹配多个文件名。但是,这并不一定无效,因为文件名中允许使用空格和句点。因此,如果您想在此处匹配多个文件名,您必须弄清楚自己要做什么。像"((?:\w+)\.(?:jpg|gif|png))"这样的东西会更直观。