Mikubill / pixivpy-async

Pure Python 3 Async Pixiv API
The Unlicense
148 stars 18 forks source link

download方法使用后缀自动匹配位于判断文件是否存在之后,此时可能存在重复下载的问题 #7

Closed ethpch closed 3 years ago

ethpch commented 4 years ago

如下代码,初始化 name 变量时仅使用 url 最后的字符串, https://github.com/Mikubill/pixivpy-async/blob/4e110edd9000ade3584a30b904a1a0fc18d50226/pixivpy_async/bapi.py#L137-L138 而在如下代码中,初始化 img_path 变量时使用了 name 变量,在之后的判断里,直接使用 img_path 变量来判断文件是否存在, https://github.com/Mikubill/pixivpy-async/blob/4e110edd9000ade3584a30b904a1a0fc18d50226/pixivpy_async/bapi.py#L142-L144 其后又使用后缀自动匹配方法修改了 img_path 的后缀并且作为文件名写入图片文件, https://github.com/Mikubill/pixivpy-async/blob/4e110edd9000ade3584a30b904a1a0fc18d50226/pixivpy_async/bapi.py#L145-L154 此时即存在标题所描述的问题:例如下载 webp 格式的文件,下载后得到了 image.webp 文件,若使用 url 初始化得到的 name 以及 img_path 后缀名并不是 webp (例如 jpg 格式),此时判断了 image.jpg 文件不存在,因而重复下载文件并重新改名为 image.webp
将后缀自动匹配的代码提前到 142行与143行之间应该能修复此问题

ethpch commented 4 years ago

不好意思唐突了 -- type 在调用down方法后才获取,所提修复方式行不通

Mikubill commented 4 years ago

将replace判断移到写入文件前应该就没问题了,但是这样会始终完成下载操作再判断写入=

ethpch commented 4 years ago

是的,这样性能损耗太大了。我目前使用的是AppPixivAPI类下载小图,从 illust.image_urls['large'] 获取链接,得到的是webp格式的图像。观察了一下,获取到的 illust.image_urls['large'] = 'https://i.pximg.net/c/600x1200_90_webp/img-master/img/2020/04/16/23/41/25/80839841_p0_master1200.jpg',其链接中明确有着 'webp'字符串。而 illust.image_urls['medium'] = 'https://i.pximg.net/c/540x540_70/img-master/img/2020/04/16/23/41/25/80839841_p0_master1200.jpg',它的格式是jpeg的。webp格式能从url里判明,不知道png和gif能不能从url里得到,如果可以的话从url里判断格式应该也是可行的方法。

ethpch commented 4 years ago

上p站看了下,png格式能明确标识在链接里 https://i.pximg.net/img-original/img/2019/02/15/17/00/00/73198415_p0.png,再去找找gif

Mikubill commented 4 years ago

嗯...虽然文件格式可能发生变化,但是貌似没有发现同一文件名存在多个格式的情况。感觉也可以考虑直接忽略扩展名(即<name>\.\w+$的形式),匹配所有后缀

ethpch commented 4 years ago

测试了下几种图,针对AppPixivAPI,一般 illust.image_urls['large']illust.image_urls['square_medium'] 的链接是含有webp字符串的webp格式图像,链接后缀为.jpg; illust.image_urls['medium'] 的链接是不含webp字符串的jpeg格式图像,链接后缀为.jpg; illust.meta_single_page.original_image_url的链接则是原图,后缀由图像种类决定,可为jpg也可为png;而gif格式的图像无法从url里解析出来,其 largemediumsquare_medium链接特征依次为webpjpgwebporiginal_image_url获取到的是jpg

ethpch commented 4 years ago

嗯...虽然文件格式可能发生变化,但是貌似没有发现同一文件名存在多个格式的情况。感觉也可以考虑直接忽略扩展名(即<name>\.\w+$的形式),匹配所有后缀

illust.image_urls['large']illust.image_urls['square_medium']里获取到的图像,使用pillow打开之后其 format 字段为webp,即如果用如上两种链接获取的图像的确是webp格式;而从illust.image_urls['medium']illust.meta_single_page.original_image_url获取的图像是jpg格式,使用pillow打开的其 format 字段为jpeg,也就是该id获取的图像存在两种格式。gif暂未测试

ethpch commented 4 years ago

嗯...gif的话使用illust_detail方法获取的large medium square_medium original链接下载的文件分别为webp jpeg webp jpeg,与大图为 jpg 的图像所获取的链接特征完全相同,使用pillow打开后也为如上格式,并不是动图。使用 ugoira_metadata 方法获取的 ugoira_metadata.zip_urls.medium链接下载的包与图像无关。
随便挑选测试了几十张图,对于AppPixivAPI获取图像链接的初步结论是:从illust.image_urls['large']illust.image_urls['square_medium'] 获取的链接明确带有webp字段,下载的图片是webp格式,url后缀为.jpg;而从illust.image_urls['medium']illust.meta_single_page.original_image_url获取的链接无webp字段,medium后缀为.jpg,格式为jpegoriginal由原图决定,后缀为jpg则格式为jpeg,为png则格式为png
PixivAPI相关功能尚未测试,太懒了(逃