Code Golf Image Downloader

20

ВНИМАНИЕ: Ответы могут быть полезны для некоторых игроков в гольф кода.

Во многих задачах изображений пост содержит изображения, которые должны быть сохранены в файл, чтобы иметь возможность работать над проблемой. Это особенно утомительное ручное задание. Мы, программисты, не должны подвергаться такой тяжелой работе. Ваша задача - автоматически загрузить все изображения, содержащиеся в вопросе Code Golf.SE.

правила

  • Ваша программа может подключаться к любой части stackexchange.com, но не может подключаться к каким-либо другим доменам, за исключением расположения изображений (т. Е. Не беспокоиться об укорачивателе URL).
  • Целое число N задается в качестве входных данных в командной строке или в stdin.
  • URL гарантированно является действительной ссылкой на вопрос Code Golf.http://codegolf.stackexchange.com/questions/N
  • Каждое изображение, отображаемое в теле вопроса N, должно быть сохранено в файл на локальном компьютере. Любое из следующих мест является приемлемым:
    • Текущий каталог
    • Ввод каталога пользователем
  • Ваша программа не должна сохранять файлы, кроме изображений в теле вопроса (например, аватары пользователей или изображения, содержащиеся в ответах).
  • Изображения должны быть сохранены с тем же расширением файла, что и оригинал.

Это - напишите самую короткую программу, какую только сможете.

Критерий достоверности ответов

Существуют различные возможные крайние случаи с несколькими изображениями с одинаковым именем, текстом с тем же именем, что и у элементов HTML, и т. Д. Ответ будет признан недействительным только в том случае, если может быть показано, что он не выполнен, при некоторой ревизии вопроса, опубликованного до 10 января 2015 г. ,

feersum
источник
Должны ли имена изображений быть одинаковыми или мы можем сделать как 0.png, 1.png и т. Д.
stokastic
@stokastic Вы можете назвать часть перед расширением по своему желанию (если вы не используете одно и то же имя дважды, перезаписывая предыдущий файл).
feersum

Ответы:

10

Mathematica, 211 210 байт

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

Это довольно просто. Я установил фильтр для API StackExchange, который возвращает только тело вопроса. Код извлекает информацию о вопросе с помощью этого фильтра и анализирует ее как JSON. Я выбираю правильный элемент (тело) и использую его ImportStringдля анализа HTML и отфильтровывания всех URL-адресов изображений. FileNameTake@#~Export~Import@#затем загружает каждое из изображений и сохраняет его в текущем рабочем каталоге с тем же именем файла, что и в URL.

Вы можете узнать текущий рабочий каталог с помощью Directory[].

В принципе, есть гораздо более короткая версия, потому что на ImportStringсамом деле можно скачать все файлы сразу, а не просто дать мне URL-адреса. Но затем я теряю информацию об исходном типе файла (поскольку Imageпри загрузке они преобразуются в объекты), поэтому я могу сохранить их все как один и тот же тип (скажем, PNG).

Мартин Эндер
источник
8

Javascript - 149 161 байт

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

с пробелами

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

скрипт должен быть запущен с сайта stackexchange для работы. По умолчанию будет отображаться текущая страница, если в приглашении не указан номер вопроса.

Профессор аллман
источник
1
Как упоминалось выше, @doorknob, вы можете немного сэкономить, поменяв q на вопрос. И если вы не против получить все изображения в постах на странице, вы можете, $('[src*="imgur"]',d)я верю. Мне нравится, что это можно запустить в консоли - мгновенное удовлетворение.
Иосия
1
questionsможет быть сокращен до q, но он должен включать codegolf.stackexchange.comчасть, а не полагаться на то, чтобы быть на этой странице. @Josiah можно включать изображения из других доменов в сообщениях.
feersum
1
Селектор #question .post-text imgможет быть сокращен до .post-text:first imgили .post-text:eq(0) img.
1
5

Python 2 - 241 байт

Довольно просто, возможно, дальше можно играть в гольф. Я ищу на сайте все вхождения img src=между первым появлением post-textи /divсразу после этого. Каждый URL-адрес изображения затем читается и сохраняется в рабочем каталоге.

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
источник
Имена файлов сохраняются как есть - имя берется как последние 9 байтов ( [-9:]) URL-адреса изображения, в котором должно быть 5-символьное имя и a .pngили .jpgт. Д. Оно будет отрезать байты имени файла, если расширение длиннее 3 символов. ,
Stokastic
Что если имя файла короче 9 байтов? Разве это не включает косую черту в имени файла?
Мартин Эндер
Вы можете сохранить 2 байта, сделав forцикл одной строкой. for p re.findall(...):f=open(...);f.write(...)
подземный
@mar Не думаю, что имя файла может быть меньше 9 байт, но я могу ошибаться
подземный
@ MartinBüttner Я думаю, что 9 байтов - разумное предположение, но я могу изменить его, если вы считаете, что я должен. Для чего бы это ни стоило - вероятно, достаточно использовать только 6 или 7 байтов, и все же в значительной степени гарантирует отличные имена файлов.
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[])

Это экспортирует изображения таким же образом, как это делал Мартин в своем решении Mathematica, прочитайте его ответ для получения дополнительной информации об этом. Этот подход очень отличается от его, вместо того, чтобы анализировать результат API, я анализирую HTML-страницу напрямую. Вернее, я анализирую символический XML, который Mathematica может генерировать из HTML.


источник
1

Python 2 - 398 342 334 байта

Программа загружает страницу SE, извлекает часть записи (элемент div текста после записи), находит URL-адреса, заканчивающиеся расширением изображения, и загружает их. Изображения сохраняются как img<n>.<ext>в текущем каталоге.

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

Эта программа также будет загружать изображения, которые поставляются в виде ссылки, а не только встроенные изображения. Придавая каждому изображению уникальное имя файла, также избегаются конфликты имен.

Логика Найт
источник
2
Вы можете сохранить 8 символов путем замены questionsс q(в URL).
Дверная ручка
В вопросе 43274 я вижу только 11 изображений, но загружено 21.
feersum
Моя программа загружает 10 изображений с высоким разрешением, а также 10 миниатюр. Я не уверен, что другие записи получают версии с высоким разрешением.
Логика Найт
@ Doorknob - спасибо. Я пропустил это. Мне нужно гораздо больше, чтобы поймать других парней.
Логика Найт
1
@CarpetPython, хотя это, пожалуй, более полезно ... намерение спецификации заключалось в том, чтобы загружать только изображения, которые видны.
feersum
1

Баш - 86 байт

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

Ничто не может исправить. -npне позволяет wget входить в верхние каталоги (User Imgs) -Aтолько захватывает файлы с расширением, соответствующим представленному списку. -rэто рекурсивная загрузка. -lпредотвращает слишком глубокое проникновение wget $1это вопрос, чтобы схватить.

HSchmale
источник
1
Есть ли что-то конкретное, что мне нужно сделать, чтобы это работало? Я попробовал это на паре вопросов, но ничего хорошего. Вывод здесь .
Geobits
1
Я думаю , что ожно сохранить 8 символов путем замены questionsс qв URL.
Timtech
1

Node.js, 251 247 байт

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

Используется requestдля создания HTTP GETи cheerioанализа HTML. Конфликты имен разрешаются путем добавления индекса текущего изображения к базовому имени URL файла. Изображения сохраняются в том же каталоге, что и текущий файл.

CPU1
источник
1

Lua, 200 байт

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)

Принимает число в качестве аргумента командной строки.

Предполагается, что любой src=атрибут будет для imgтега, поскольку это единственные теги с srcатрибутами, которые допускает обмен стека (верно?).

Также обратите внимание .. .... Я особенно горжусь этим.

thenumbernine
источник