Code Golf Image Downloader

20

AVERTISSEMENT: Les réponses peuvent être utiles à certains golfeurs de code.

Dans de nombreux défis de , le message contient des images, qui doivent être enregistrées dans un fichier afin de pouvoir travailler sur le problème. Il s'agit d'une tâche manuelle particulièrement fastidieuse. Nous, les programmeurs, ne devrions pas être soumis à de telles corvées. Votre tâche consiste à télécharger automatiquement toutes les images contenues dans une question Code Golf.SE.

Règles

  • Votre programme peut se connecter à n'importe quelle partie de stackexchange.com, mais ne peut pas se connecter à d'autres domaines, à l'exception des emplacements des images (c'est-à-dire, ne vous embêtez pas avec un raccourcisseur d'URL).
  • Un entier N est donné en entrée, sur la ligne de commande ou stdin.
  • L'URL est garantie d'être un lien valide vers une question Code Golf.http://codegolf.stackexchange.com/questions/N
  • Chaque image affichée dans le corps de la question N doit être enregistrée dans un fichier sur l'ordinateur local. L'un des emplacements suivants est acceptable:
    • Le répertoire courant
    • Un répertoire saisi par l'utilisateur
  • Votre programme ne doit pas enregistrer de fichiers autres que les images dans le corps de la question (par exemple, les avatars des utilisateurs ou les images contenues dans les réponses).
  • Les images doivent être enregistrées avec la même extension de fichier que l'original.

Il s'agit d'un - écrivez le programme le plus court possible.

Critère de validité des réponses

Il existe différents cas de bord possibles avec plusieurs images du même nom, du texte avec le même nom que les éléments HTML, etc. Une réponse ne sera invalidée que s'il peut être démontré qu'elle échoue lors d'une révision d'une question publiée avant le 10 janvier 2015 .

feersum
la source
Si les noms d'images doivent rester les mêmes ou pouvons-nous faire comme 0.png, 1.png etc
stokastic
@stokastic Vous pouvez nommer la partie avant l'extension comme vous voulez (tant que vous n'utilisez pas le même nom deux fois, en écrasant un fichier précédent).
feersum

Réponses:

10

Mathematica, 211 210 octets

i=Import;FileNameTake@#~Export~i@#&/@ImportString["body"/.("items"/.i["http://api.stackexchange.com/2.2/questions/"<>InputString[]<>"?site=codegolf&filter=!*Lgp.gEWHA6BNP.l","JSON"])[[1]],{"HTML","ImageLinks"}]

Non golfé:

i = Import;
FileNameTake@#~Export~i@# & /@ 
 ImportString[
  "body" /. (
    "items" /. 
      i["http://api.stackexchange.com/2.2/questions/" <> 
        InputString[] <> "?site=codegolf&filter=!*Lgp.gEWHA6BNP.l", 
       "JSON"]
  )[[1]], 
  {"HTML", "ImageLinks"}
 ]

C'est assez simple. J'ai mis en place un filtre pour l'API StackExchange, qui ne renvoie que le corps d'une question. Le code récupère les informations de la question avec ce filtre et les analyse comme JSON. Je sélectionne l'élément correct (le corps) et l'utilise ImportStringpour analyser le code HTML et filtrer toutes les URL d'images. FileNameTake@#~Export~Import@#télécharge ensuite chacune des images et la stocke dans le répertoire de travail actuel avec le même nom de fichier que celui de l'URL.

Vous pouvez trouver le répertoire de travail actuel avec Directory[].

En principe, il existe une version beaucoup plus courte, car elle ImportStringpeut en fait télécharger tous les fichiers immédiatement, au lieu de simplement me donner les URL. Mais je perds ensuite des informations sur le type de fichier d'origine (car ils sont convertis en Imageobjets lors du téléchargement), je ne peux donc les enregistrer que sous le même type (PNG, par exemple).

Martin Ender
la source
8

Javascript - 149 161 octets

$.get("http://codegolf.stackexchange.com/q/"+prompt(),function(e){$(".post-text:first img",e).each(function(e,t){$('<a href="'+t.src+'"download>')[0].click()})})

avec un espace

$.get('http://codegolf.stackexchange.com/q/' + prompt(), function(d) {
  $('.post-text:first img',d).each(function(i,e){
   $('<a href="' + e.src + '"download>')[0].click();
  })
})

le script doit être exécuté à partir du site stackexchange pour fonctionner. Va par défaut à la page actuelle si aucun numéro de question n'est spécifié dans l'invite

Professeur Allman
la source
1
Comme @doorknob mentionné ci-dessus, vous pouvez économiser un peu en échangeant q pour question. Et si cela ne vous dérange pas d'obtenir toutes les images dans les messages sur la page, vous pouvez le faire, $('[src*="imgur"]',d)je crois. J'aime que cela puisse être exécuté dans la console - une gratification instantanée.
Josiah
1
questionspeut être raccourci q, mais il doit inclure la codegolf.stackexchange.compartie au lieu de compter sur la présence de cette page. @Josiah, il est possible d'inclure des images d'autres domaines dans les publications.
feersum
1
Le sélecteur #question .post-text imgpeut être raccourci à .post-text:first imgou .post-text:eq(0) img.
cPu1
5

Python 2 - 241 octets

Assez simple, peut probablement être joué plus loin. Je recherche sur le site toutes les occurrences img src=entre la première occurrence de post-textet /divimmédiatement après. Chaque URL d'image est ensuite lue et enregistrée dans le répertoire de travail.

import string,sys,urllib,re;o=string.find;u=urllib.urlopen
r=u("http://codegolf.stackexchange.com/q/"+sys.argv[1]).read()
i=o(r,"post-text")
for p in re.findall(r'img src="([^"]*)',r[i:o(r,"/div",i)]):f=open(p[-9:],"wb");f.write(u(p).read())
stokastic
la source
Les noms de fichiers sont conservés tels [-9:]quels - le nom est considéré comme les 9 derniers octets ( ) de l'URL de l'image, qui doit conserver son nom à 5 caractères et un .pngou .jpgetc. Il coupera les octets du nom de fichier si l'extension dépasse 3 caractères. .
stokastic
Que faire si le nom de fichier est inférieur à 9 octets? Cela n'inclurait-il pas une barre oblique dans le nom du fichier?
Martin Ender
vous pouvez économiser 2 octets en faisant de la forboucle une ligne. for p re.findall(...):f=open(...);f.write(...)
undergroundmonorail
@mar Je ne pense pas que le nom du fichier puisse être inférieur à 9 octets, mais je peux me tromper
undergroundmonorail
@ MartinBüttner Je pense que 9 octets est une hypothèse raisonnable, mais je peux la changer si vous pensez que je devrais. Pour ce que ça vaut - utiliser seulement 6 ou 7 octets est probablement suffisant et garantira toujours à peu près des noms de fichiers distincts.
stokastic
2

Mathematica, 195

x=XMLElement;c=Cases;i=Import;l=Infinity;FileNameTake@#~Export~i@#&/@(((c[#,x["img",{"src"->e_,_},___]:>e,l]&)@*(c[#,x[_,{__,"id"->"question",__},e_]:>e,l]&)@*(i[#,"XMLObject"] &))@InputString[])

Cela exporte les images de la même manière que Martin l'a fait dans sa solution Mathematica, lisez sa réponse pour plus d'informations à ce sujet. Cette approche est très différente de la sienne, au lieu d'analyser le résultat de l'API, j'analyse directement la page HTML. Ou plutôt, j'analyse le XML symbolique que Mathematica peut générer à partir du HTML.


la source
1

Python 2 - 398 342 334 octets

Le programme télécharge la page SE, extrait la partie post (l'élément div post-texte), trouve les URL qui se terminent par une extension d'image et les télécharge. Les images sont enregistrées comme img<n>.<ext>dans le répertoire courant.

import urllib2 as u,re,sys
z=u.urlopen;i=1
p=z('http://codegolf.stackexchange.com/q/'+sys.argv[1]).read()
s=re.search(r'ss="po(.+?)/di',p,16).group(1)
for L in re.findall('"(h.+?://.*?)"',s):
 b=L.rsplit('.',1)
 if len(b)==2 and b[1].lower() in 'jpg jpeg png gif bmp'.split():
  open('img%u.%s'%(i,b[1]),'wb').write(z(L).read());i+=1

Ce programme téléchargera également des images fournies sous forme de lien, pas seulement des images intégrées. En donnant à chaque image un nom de fichier unique, les conflits de noms sont également évités.

Logic Knight
la source
2
Vous pouvez enregistrer 8 caractères en les remplaçant questionspar q(dans l'URL).
Poignée de porte
À la question 43274, je ne vois que 11 images, mais 21 sont téléchargées.
feersum
Mon programme télécharge les 10 images haute résolution ainsi que les 10 miniatures. Je ne suis pas sûr que les autres entrées récupèrent les versions haute résolution.
Logic Knight
@ Doorknob - merci. J'ai manqué ça. J'aurai besoin de beaucoup plus pour attraper les autres gars.
Logic Knight
1
@CarpetPython bien que ce soit sans doute plus utile ... l'intention de la spécification était de télécharger uniquement les images qui sont visibles.
feersum
1

Bash - 86 octets

wget -r -l1 -np -Ajpg,jpeg,png,bmp,gif http://codegolf.stackexchange.com/questions/$1

Rien de tout cela ne va pas arranger. -npempêche wget d'entrer dans les répertoires supérieurs (User Imgs) -Ane prend que les fichiers dont l'extension correspond à la liste présentée. -rest un téléchargement récursif. -lempêche wget d'aller trop profondément. $1est la question à saisir.

HSchmale
la source
1
Y a-t-il quelque chose de spécifique que je dois faire pour que cela fonctionne? Je l'ai essayé sur quelques questions, mais pas bon. Sortie ici .
Geobits
1
Je pense que vous pouvez enregistrer 8 caractères en les remplaçant questionspar qdans l'URL.
Timtech
1

Node.js, 251 247 octets

r=require,g=r('request'),g('http://codegolf.stackexchange.com/q/'+process.argv[2],function(_,_,b){r('cheerio').load(b)('#question .post-text img').each(function(i,a){s=a.attribs.src,g(s).pipe(r('fs').createWriteStream(i+r('path').basename(s)))})})

Permet requestde créer des HTTP GETet cheeriod'analyser le HTML. Les collisions de noms sont résolues en ajoutant l'index de l'image actuelle au nom de base de l'URL du fichier. Les images sont enregistrées dans le même répertoire que le fichier actuel.

cPu1
la source
1

Lua, 200 octets

r=require'socket.http'.request r('http://codegolf.stackexchange.com/questions/'.. ...):gsub('post.text(.-)div',function(p)p:gsub('src="(.-)"',function(i)io.open(i:sub(-9),'wb'):write((r(i)))end)end)

Accepte le nombre comme argument de ligne de commande.

Suppose que tout src=attribut sera pour une imgbalise car ce sont les seules balises avec des srcattributs que l'échange de pile permet (non?).

Notez également le .. .... Je suis particulièrement fier de celui-là.

l'umbumbine
la source