item 里放一串 file_urls,FilesPipeline 就替你下载文件。它存在哪、文件名怎么来、重复下载怎么避免、失败了怎么办?这篇用一个带 404、重定向、无扩展名下载链接的服务器全跑一遍。
服务器收到的请求:['/', '/f/a.txt', '/f/b.pdf', '/dl?id=3', '/f/missing.txt', '/f/redir']
item["files"] 共 4 个结果(file_urls 有 6 个:a.txt 出现两次得到两条同样的结果但只请求了一次,404 与 302 没有结果):
status=downloadedpath=full/0ba82ee857b25dc90235004d3736f67edf84eb40.txt checksum=94f86a84ec00ce17aeadfdc30912e4ea url=/f/a.txt
status=downloadedpath=full/52ea197978f62ec0cb02c715c46eba47885abeed.pdf checksum=ee4498a36143054208a4c3bb26adca87 url=/f/b.pdf
status=downloadedpath=full/ffb2a4d93b5a93a22cc0e0aa1dc14dab710d3e77 checksum=ee4498a36143054208a4c3bb26adca87 url=/dl?id=3
status=downloadedpath=full/0ba82ee857b25dc90235004d3736f67edf84eb40.txt checksum=94f86a84ec00ce17aeadfdc30912e4ea url=/f/a.txt
磁盘上:full/0ba82ee857b25dc90235004d3736f67edf84eb40.txt(13 字节), full/52ea197978f62ec0cb02c715c46eba47885abeed.pdf(20009 字节), full/ffb2a4d93b5a93a22cc0e0aa1dc14dab710d3e77(20009 字节)
SHA1("http://…/f/a.txt") 对得上文件名:True;stats {'file_count': 3, 'file_status_count/downloaded': 3}
日志:WARNING: File (code: 404): Error downloading file from <GET http://127.0.0.1:9960/f/missing.txt> referred in <None> | WARNING: File (unknown-error): Error downloading file from <GET http://127.0.0.1:9960/f/missing.txt> referred in <None>: | WARNING: File (code: 302): Error downloading file from <GET http://127.0.0.1:9960/f/redir> referred in <None> | WARNING: File (unknown-error): Error downloading file from <GET http://127.0.0.1:9960/f/redir> referred in <None>: downl
a.txt 的 checksum = md5 内容:True文件保存在 FILES_STORE/full/,文件名是 URL 的 SHA1 加扩展名;结果写进 item 的 files 字段,每条有 url、path、checksum、status。
第二次:服务器收到 ['/', '/f/missing.txt', '/f/redir'];files 状态 ['uptodate', 'uptodate', 'uptodate', 'uptodate'];stats {'file_count': 3, 'file_status_count/uptodate': 3}
FILES_EXPIRES=0(任何已有的文件都算过期):服务器收到 ['/', '/f/a.txt', '/f/b.pdf', '/dl?id=3', '/f/missing.txt', '/f/redir'];files 状态 ['downloaded', 'downloaded', 'downloaded', 'downloaded']已存在且没过 FILES_EXPIRES 天的文件状态为 uptodate,不再请求服务器;失败的 URL 不会被记住。
默认(False):files=[];服务器收到 ['/', '/f/redir'];日志 ['WARNING: File (code: 302): Error downloading file from <GET http://127.0.0.1:9960/f/redir> referred ']
MEDIA_ALLOW_REDIRECTS=True:files=[{'path': 'full/df36b499e1bae1cf1a29c3680c05008deff254c0', 'status': 'downloaded'}];服务器收到 ['/', '/f/redir', '/f/a.txt'];日志 []媒体请求默认不跟随 3xx,需要 MEDIA_ALLOW_REDIRECTS = True;保存路径仍按最初的 URL 计算。
磁盘上:by-name/a.txt(13 字节), by-name/b.pdf(20009 字节), by-name/dl-id3(20009 字节)
重写 file_path() 即可用可读的名字,但要自己避免冲突。