2

Trying to save image files in batches. Works nicely, but the list of names for each file sometimes includes apostrophes, and everything stops.

The offending script is:

    pic.save(r"C:\Python34\Scripts\{!s}.jpg".format(name))

The apostrophes in the names aren't a problem when I embed them in a url with selenium

    browser.get("https://website.com/{!s}".format(name))

or when I print the destination file name, e.g.

    print(r"C:\Python34\Scripts\{!s}.jpg".format(name))

Which is fine to turn out like

C:\Python34\Scripts['It's fine'].jpg

so I assume this kind of problem has something to do with the save function.

The trace back calls the pic.save line of code in PIL\Image.py and says the OSError: [Errno 22] is an Invalid argument in the save destination.

Using Windows 7 if that matters.

Probably super-novice error, but I've been reading threads and can't figure this out--workaround would be cleaning the list of apostrophes before using it, which would be annoying but acceptable.

Any help appreciated.

---edited to fix double quotes as single, just mistyped when writing this post...doh.

  • The `"` symbol in this text `C:\Python34\Scripts["It's fine"].jpg` is not an apostrophe, it's a double quote, which is not allowed in a Windows filename. – Sam Jul 08 '15 at 20:01
  • Sorry!!! Good catch, @Sam but that was a problem with my writeup here but not with the actual code on my computer, which has used single quotes consistently Like C:\Python34\Scripts['It's fine'].jpg Blunder upon blunder, sorry for the confusion. – JussAssKinn Jul 09 '15 at 18:42
  • Nevermind @Sam, got this solved by adding [0] so that it's pic.save(r"C:\Python34\Scripts\{!s}.jpg".format(name[0])) Thanks again for the help! – JussAssKinn Jul 09 '15 at 19:53

1 Answers1

2

It's not a Python problem, but Windows, or rather the file system, file naming rules. From the MSDN:

Use any character in the current code page for a name, including Unicode characters and characters in the extended character set (128–255), except for the following:

The following reserved characters

< (less than)

> (greater than)

: (colon)

" (double quote)

/ (forward slash)

\ (backslash)

| (vertical bar or pipe)

? (question mark)

* (asterisk)

On UNIX type systems, all except the / would be valid (although most would be a bad idea). A further "character", binary zero 0x00, is invalid on most file systems.

Rules for URLs are different again.

So you are going to have to write a sanitiser for filenames avoiding these characters. A regular expression would probably be the easiest, but you will have to choose replacement characters that don't occur naturally.

Edit: I was assuming that Error 22 was reporting an invalid filename, but I was wrong, it actually means "The device does not recognise the command".

See https://stackoverflow.com/questions/19870570/pil-giving-oserror-errno-22-when-opening-gif. The accepted reply is rather weird though.

I Google'd "python PIL OSError Errno 22", you might like to try the same and see if any of the conditions apply to you, but clearly you are not alone, if that's any consolation.

Sorry I can't do more.

Community
  • 1
  • 1
cdarke
  • 42,728
  • 8
  • 80
  • 84
  • Thanks for the help, but unfortunately for me you found a problem with the way I wrote this up and not with the actual code on my computer, where I have been having problems with single quotes and only put in doubles by accident in a blind typo when writing this into the help request. Not helpful on my part I know. If you can think of why a set of three single quotes in the file name is a problem or how to get around that, please let me know. Thanks. – JussAssKinn Jul 09 '15 at 18:44
  • @JussAssKinn: that's difficult without seeing your code, in theory that shouldn't be an issue but I can't say I have every tried it. I'll wind-up my Windows machine to try it myself. – cdarke Jul 09 '15 at 19:06
  • @JussAssKinn: to confirm, single quotes work fine as Windows filenames. However, I don't have PIL to try it, and when I looked, PIL appears to be deprecated in favour of `Pillow`. HOWEVER, see my edit – cdarke Jul 09 '15 at 19:33
  • Hi cdarke, thanks much for your help. With another person's help, it's now working by adding [0], as in pic.save(r"C:\Python34\Scripts\{!s}.jpg".format(name[0])) – JussAssKinn Jul 09 '15 at 20:03
  • @JussAssKinn: I'm glad you got it fixed. I would never have considered that. I see you mentioned a list of names, but your variable was called `name`. If you post here again you might wish to consider your variable names, so using the plural `names` would have been a clue, rather than the singular `name`. Good illustration of why variable names are so important (and why I shouldn't assume anything). – cdarke Jul 10 '15 at 08:39