Code Golf Image Downloader

20

WARNUNG: Antworten können für einige Code-Golfer nützlich sein.

Bei vielen enthält der Beitrag Bilder, die in einer Datei gespeichert werden müssen, damit das Problem behoben werden kann. Dies ist eine besonders mühsame manuelle Aufgabe. Wir Programmierer sollten uns keiner solchen Plackerei unterziehen müssen. Ihre Aufgabe ist es, alle in einer Code Golf.SE-Frage enthaltenen Bilder automatisch herunterzuladen.

Regeln

  • Ihr Programm stellt möglicherweise eine Verbindung zu einem beliebigen Teil von stackexchange.com, aber möglicherweise nicht zu anderen Domänen her, mit Ausnahme der Speicherorte der Bilder (z. B. ohne URL-Kürzung).
  • Eine Ganzzahl N wird als Eingabe in der Befehlszeile oder in stdin angegeben.
  • Die URL ist garantiert ein gültiger Link zu einer Code Golf-Frage.http://codegolf.stackexchange.com/questions/N
  • Jedes Bild, das im Hauptteil der Frage angezeigt wird N muss in einer Datei auf dem lokalen Computer gespeichert werden. Einer der folgenden Standorte ist akzeptabel:
    • Das aktuelle Verzeichnis
    • Ein vom Benutzer eingegebenes Verzeichnis
  • Ihr Programm darf keine anderen Dateien als die Bilder im Fragenkörper speichern (z. B. Benutzeravatare oder in Antworten enthaltene Bilder).
  • Bilder müssen mit derselben Dateierweiterung wie das Original gespeichert werden.

Dies ist ein - schreiben Sie das kürzeste Programm, das Sie können.

Gültigkeitskriterium für Antworten

Es gibt verschiedene mögliche Randfälle mit mehreren Bildern mit demselben Namen, Text mit demselben Namen wie HTML-Elemente usw. Eine Antwort wird nur ungültig, wenn bei einer Überarbeitung einer Frage, die vor dem 10. Januar 2015 veröffentlicht wurde, gezeigt werden kann, dass sie fehlschlägt .

Feersum
quelle
Sollten die Bildnamen gleich bleiben oder können wir 0.png, 1.png usw. tun
stokastic
@stokastic Sie können dem Teil vor der Erweiterung einen beliebigen Namen geben (solange Sie nicht zweimal denselben Namen verwenden und eine vorherige Datei überschreiben).
Feersum

Antworten:

10

Mathematica, 211 210 Bytes

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"}]

Ungolfed:

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"}
 ]

Es ist ziemlich einfach. Ich habe einen Filter für die StackExchange-API eingerichtet, der nur den Hauptteil einer Frage zurückgibt. Der Code ruft die Frageninformationen mit diesem Filter ab und analysiert sie als JSON. Ich wähle das richtige Element (den Body) aus und ImportStringanalysiere den HTML-Code und filtere alle Bild-URLs heraus.FileNameTake@#~Export~Import@#Lädt dann jedes der Bilder herunter und speichert es im aktuellen Arbeitsverzeichnis mit demselben Dateinamen wie dem in der URL.

Mit können Sie das aktuelle Arbeitsverzeichnis herausfinden Directory[] .

Im Prinzip gibt es eine viel kürzere Version, da ImportStringalle Dateien sofort heruntergeladen werden können, anstatt mir nur die URLs zu geben. Aber dann verliere ich Informationen über den ursprünglichen Dateityp (da diese Imagebeim Herunterladen in Objekte konvertiert werden), sodass ich sie nur als denselben Typ speichern kann (z. B. PNG).

Martin Ender
quelle
8

Javascript - 149 161 Bytes

$.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()})})

mit Leerzeichen

$.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();
  })
})

Das Skript muss von der StackExchange-Site ausgeführt werden, um zu funktionieren. Wird standardmäßig auf die aktuelle Seite gesetzt, wenn in der Eingabeaufforderung keine Fragennummer angegeben ist

Professor Allman
quelle
1
Wie oben bei @doorknob erwähnt, können Sie ein wenig sparen, indem Sie q gegen eine Frage tauschen. Und wenn es Ihnen nichts ausmacht, alle Bilder in den Beiträgen auf der Seite zu finden, können Sie das, glaube $('[src*="imgur"]',d)ich, tun . Ich mag, dass dies in der Konsole ausgeführt werden kann - sofortige Befriedigung.
Josiah
1
questionskann auf gekürzt werden, qsollte aber den codegolf.stackexchange.comTeil enthalten, anstatt sich auf diese Seite zu verlassen. @Josiah Es ist möglich, Bilder von anderen Domains in Posts aufzunehmen.
Feersum
1
Der Selektor #question .post-text imgkann auf .post-text:first imgoder gekürzt werden .post-text:eq(0) img.
cPu1,
5

Python 2 - 241 Bytes

Ziemlich unkompliziert, kann wohl weiter golfen werden. Ich suche auf der Website nach allen Vorkommen img src=zwischen dem ersten Vorkommen post-textund dem /divunmittelbar darauf folgenden. Jede Bild-URL wird dann gelesen und im Arbeitsverzeichnis gespeichert.

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())
stokastisch
quelle
Dateinamen bleiben wie sie sind - der Name wird als die letzten 9 Bytes ( [-9:]) der Bild-URL genommen, die ihren 5-stelligen Namen und ein .pngoder .jpgusw. behalten soll. Wenn die Erweiterung länger als 3 Zeichen ist, werden Bytes des Dateinamens abgeschnitten .
Stokastic
Was ist, wenn der Dateiname kürzer als 9 Byte ist? Wäre das nicht ein Schrägstrich im Dateinamen?
Martin Ender
Sie können 2 Bytes sparen, indem Sie die forSchleife zu einer Zeile machen. for p re.findall(...):f=open(...);f.write(...)
bahnmonorail
@mar Ich glaube nicht, dass der Dateiname kleiner als 9 Byte sein kann, aber ich könnte mich irren
undergroundmonorail
@ MartinBüttner Ich halte 9 Bytes für eine vernünftige Annahme, aber ich kann es ändern, wenn du denkst, dass ich sollte. Für das, was es wert ist - die Verwendung von nur 6 oder 7 Bytes reicht wahrscheinlich aus und garantiert dennoch ziemlich genau eindeutige Dateinamen.
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[])

Dadurch werden Bilder auf die gleiche Weise exportiert, wie dies Martin in seiner Mathematica-Lösung getan hat. Weitere Informationen hierzu finden Sie in seiner Antwort. Dieser Ansatz unterscheidet sich stark von seinem, anstatt das Ergebnis über die API zu analysieren, analysiere ich die HTML-Seite direkt. Oder besser gesagt, ich analysiere das symbolische XML, das Mathematica aus HTML generieren kann.


quelle
1

Python 2 - 398 342 334 Bytes

Das Programm lädt die SE-Seite herunter, extrahiert den Beitragsteil (das Post-Text-Div-Element), findet URLs, die in einer Bilderweiterung enden, und lädt sie herunter. Die Bilder werden gespeichert alsimg<n>.<ext> im aktuellen Verzeichnis .

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

Dieses Programm lädt auch Bilder herunter, die als Link bereitgestellt werden, nicht nur eingebettete Bilder. Wenn Sie jedem Bild einen eindeutigen Dateinamen zuweisen, werden auch Namenskonflikte vermieden.

Logik-Ritter
quelle
2
Sie können 8 Zeichen speichern durch Ersetzen questionsmit q(in der URL).
Türklinke
In Frage 43274 sehe ich nur 11 Bilder, aber 21 werden heruntergeladen.
Feersum
Mein Programm lädt die 10 hochauflösenden Bilder sowie die 10 Thumbnails herunter. Ich bin nicht sicher, ob die anderen Einträge die hochauflösenden Versionen abrufen.
Logic Knight
@Doorknob - danke. Das habe ich vermisst. Ich werde aber noch viel mehr brauchen, um die anderen zu erwischen.
Logic Knight
1
@CarpetPython obwohl das wohl nützlicher ist ... die Absicht der Spezifikation war es, nur Bilder herunterzuladen, die sichtbar sind.
Feersum
1

Bash - 86 Bytes

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

Nichts Wget wird nicht behoben. -npverhindert, dass wget in die oberen Verzeichnisse (User Imgs) gelangt und -Anur Dateien mit der Erweiterung aufruft, die der angezeigten Liste entspricht. -rist ein rekursiver Download. -lverhindert, dass Wget zu tief geht. $1ist die Frage zu greifen.

HSchmale
quelle
1
Muss ich etwas spezielles tun, damit dies funktioniert? Ich habe es bei ein paar Fragen versucht, aber nichts Gutes. Ausgabe hier .
Geobits
1
Ich denke , ou 8 Zeichen speichern kann durch den Austausch questionsmit qin der URL.
Timtech
1

Node.js, 251 247 Bytes

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)))})})

Verwendet request, um HTTP GETs cheeriozu erstellen und den HTML-Code zu analysieren. Namenskollisionen werden behoben, indem der Index des aktuellen Bildes dem Basisnamen der Datei-URL vorangestellt wird. Bilder werden im selben Verzeichnis wie die aktuelle Datei gespeichert.

cPu1
quelle
1

Lua, 200 Bytes

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)

Akzeptiert die Nummer als Befehlszeilenargument.

Angenommen, ein src=Attribut bezieht sich auf ein imgTag, da dies die einzigen Tags mit sindsrc Attributen sind, die der Stapelaustausch zulässt (richtig?).

Beachten Sie auch die .. .... Darauf bin ich besonders stolz.

thenumbernine
quelle