Pengunduh Gambar Kode Golf

20

PERINGATAN: Jawaban mungkin berguna untuk beberapa pegolf kode.

Dalam banyak tantangan , kiriman berisi gambar, yang harus disimpan ke file agar dapat mengatasi masalah tersebut. Ini adalah tugas manual yang sangat membosankan. Kami para programmer tidak harus mengalami kerepotan seperti itu. Tugas Anda adalah mengunduh secara otomatis semua gambar yang ada dalam pertanyaan Code Golf.SE.

Aturan

  • Program Anda dapat terhubung ke bagian mana pun dari stackexchange.com, tetapi mungkin tidak terhubung ke domain lain, kecuali lokasi gambar (yaitu, jangan repot-repot dengan penyingkat URL).
  • Integer N diberikan sebagai input, pada baris perintah atau stdin.
  • URL dijamin menjadi tautan yang valid ke pertanyaan Code Golf.http://codegolf.stackexchange.com/questions/N
  • Setiap gambar yang ditampilkan di badan pertanyaan N harus disimpan ke file di komputer lokal. Salah satu dari lokasi berikut ini dapat diterima:
    • Direktori saat ini
    • Input direktori oleh pengguna
  • Program Anda tidak boleh menyimpan file selain gambar di badan pertanyaan (mis. Avatar pengguna, atau gambar yang ada dalam jawaban).
  • Gambar harus disimpan dengan ekstensi file yang sama dengan aslinya.

Ini adalah - tulislah program sesingkat mungkin.

Kriteria validitas untuk jawaban

Ada berbagai kemungkinan tepi kasus dengan beberapa gambar dengan nama yang sama, teks dengan nama yang sama dengan elemen HTML, dll. Jawaban hanya akan dibatalkan jika terbukti gagal pada beberapa revisi pertanyaan yang diposting sebelum 10 Januari 2015 .

feersum
sumber
Haruskah nama gambar dijaga tetap sama atau bisa kita lakukan seperti 0.png, 1.png dll
stokastic
@stokastic Anda dapat memberi nama bagian sebelum ekstensi ke apa pun yang Anda inginkan (selama Anda tidak menggunakan nama yang sama dua kali, menimpa file sebelumnya).
feersum

Jawaban:

10

Mathematica, 211 210 byte

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

Tidak Terkumpul:

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

Cukup mudah. Saya telah menyiapkan filter untuk StackExchange API, yang hanya mengembalikan isi pertanyaan. Kode mengambil informasi pertanyaan dengan filter itu dan mem-parsingnya sebagai JSON. Saya memilih elemen yang benar (badan), dan gunakan ImportStringuntuk mem-parsing HTML dan memfilter semua URL gambar. FileNameTake@#~Export~Import@#kemudian unduh masing-masing gambar dan simpan di direktori kerja saat ini dengan nama file yang sama dengan yang ada di URL.

Anda dapat mengetahui direktori kerja saat ini dengan Directory[].

Pada prinsipnya, ada versi yang jauh lebih pendek, karena ImportStringsebenarnya dapat langsung mengunduh semua file, bukan hanya memberi saya URL. Tapi kemudian saya kehilangan informasi tentang jenis file asli (karena mereka dikonversi menjadi Imageobjek saat diunduh), jadi saya hanya dapat menyimpan semuanya sebagai jenis yang sama (PNG, katakanlah).

Martin Ender
sumber
8

Javascript - 149 161 byte

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

dengan spasi putih

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

skrip harus dijalankan dari situs stackexchange agar berfungsi. Akan default ke halaman saat ini jika tidak ada nomor pertanyaan yang ditentukan dalam prompt

Profesor Allman
sumber
1
Seperti @doorknob yang disebutkan di atas, Anda dapat menghemat sedikit dengan menukar q untuk pertanyaan. Dan jika Anda tidak keberatan mendapatkan semua gambar di pos di halaman, Anda bisa $('[src*="imgur"]',d)percaya. Saya suka ini dapat dijalankan di konsol - kepuasan instan.
Josiah
1
questionsdapat disingkat menjadi q, tetapi harus mencakup codegolf.stackexchange.combagian daripada mengandalkan berada di halaman itu. @ Yosia dimungkinkan untuk memasukkan gambar dari domain lain dalam posting.
feersum
1
Pemilih #question .post-text imgdapat disingkat menjadi .post-text:first imgatau .post-text:eq(0) img.
cPu1
5

Python 2 - 241 byte

Cukup mudah, mungkin bisa bermain golf lebih lanjut. Saya mencari situs untuk semua kejadian img src=antara kejadian pertama post-textdan /divsegera setelah itu. Setiap url gambar kemudian dibaca dan disimpan ke direktori kerja.

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())
stokastik
sumber
Nama file dijaga apa adanya - nama tersebut diambil sebagai 9 byte terakhir ( [-9:]) dari url gambar, yang seharusnya menjaga 5 karakter nama dan a .pngdan .jpglain - lain. Itu akan memotong byte nama file jika ekstensi lebih panjang dari 3 karakter .
stokastik
Bagaimana jika nama file lebih pendek dari 9 byte? Bukankah itu termasuk garis miring pada nama file?
Martin Ender
Anda dapat menyimpan 2 byte dengan membuat forsatu baris loop. for p re.findall(...):f=open(...);f.write(...)
undergroundmonorail
@mar Saya tidak berpikir nama file bisa kurang dari 9 byte, tapi saya mungkin salah
undergroundmonorail
@ MartinBüttner Saya pikir 9 byte adalah asumsi yang masuk akal, tapi saya bisa mengubahnya jika Anda pikir saya harus. Untuk apa nilainya - menggunakan hanya 6 atau 7 byte mungkin cukup dan masih akan cukup menjamin nama file yang berbeda.
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[])

Ini mengekspor gambar dengan cara yang sama yang Martin lakukan dalam solusi Mathematica-nya, baca jawabannya untuk informasi lebih lanjut tentang itu. Pendekatan ini sangat berbeda dari pendekatannya, daripada mem-parsing hasil dari API saya langsung mem-parsing halaman HTML. Atau lebih tepatnya, saya menguraikan XML simbolis yang dapat dihasilkan Mathematica dari HTML.


sumber
1

Python 2 - 398 342 334 byte

Program mengunduh halaman SE, mengekstrak bagian posting (elemen pos-teks), menemukan url yang berakhir dengan ekstensi gambar dan mengunduhnya. Gambar disimpan seperti img<n>.<ext>dalam direktori saat ini.

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

Program ini juga akan mengunduh gambar yang disediakan sebagai tautan, tidak hanya gambar yang disematkan. Dengan memberi setiap gambar nama file unik, bentrokan nama juga dihindari.

Ksatria Logika
sumber
2
Anda dapat menyimpan 8 karakter dengan mengganti questionsdengan q(dalam URL).
Gagang Pintu
Dalam pertanyaan 43274, saya hanya melihat 11 gambar, tetapi 21 diunduh.
feersum
Program saya mengunduh 10 gambar beresolusi tinggi serta 10 thumbnail. Saya tidak yakin entri lain mengambil versi resolusi tinggi.
Logic Knight
@ Doorknob - terima kasih. Saya melewatkan itu. Saya akan membutuhkan lebih banyak lagi untuk menangkap orang lain.
Logic Knight
1
@CarpetPython meskipun itu bisa dibilang lebih bermanfaat ... maksud dari spec adalah untuk mengunduh hanya gambar yang terlihat.
feersum
1

Bash - 86 byte

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

Tidak ada yang wget tidak akan memperbaiki. -npmencegah wget dari memasukkan direktori atas (Gambar Pengguna) -Ahanya mengambil file dengan ekstensi yang cocok dengan daftar yang disajikan. -radalah unduhan berulang. -lmencegah wget dari terlalu dalam. $1adalah pertanyaan yang harus diambil.

HSchmale
sumber
1
Apakah ada sesuatu yang spesifik yang perlu saya lakukan agar ini berfungsi? Saya mencobanya pada beberapa pertanyaan, tetapi tidak baik. Keluaran di sini .
Geobits
1
Saya pikir Anda dapat menyimpan 8 karakter dengan mengganti questionsdengan qdi 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)))})})

Menggunakan requestuntuk membuat HTTP GETdan cheeriomem-parsing HTML. Tabrakan nama diselesaikan dengan menambahkan indeks gambar saat ini ke nama file URL file. Gambar disimpan ke direktori yang sama dengan file saat ini.

cPu1
sumber
1

Lua, 200 byte

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)

Menerima nomor sebagai argumen baris perintah.

Asumsikan src=atribut apa pun akan untuk suatu imgtag karena ini adalah satu-satunya tag dengan srcatribut yang memungkinkan pertukaran tumpuk (kan?).

Perhatikan juga .. .... Saya sangat bangga dengan yang itu.

lalunomor
sumber