Code Golf Image Downloader


20

CẢNH BÁO: Câu trả lời có thể hữu ích cho một số người chơi mã.

Trong nhiều thử thách , bài đăng chứa hình ảnh, phải được lưu vào một tệp để có thể xử lý sự cố. Đây là một công việc thủ công đặc biệt tẻ nhạt. Chúng tôi lập trình viên không cần phải chịu sự quyết liệt như vậy. Nhiệm vụ của bạn là tự động tải xuống tất cả các hình ảnh có trong câu hỏi Code Golf.SE.

Quy tắc

  • Chương trình của bạn có thể kết nối với bất kỳ phần nào của stackexchange.com, nhưng có thể không kết nối với bất kỳ tên miền nào khác, ngoại trừ vị trí của hình ảnh (nghĩa là không bận tâm với trình rút ngắn URL).
  • Một số nguyên N được đưa ra làm đầu vào, trên dòng lệnh hoặc stdin.
  • URL được đảm bảo là một liên kết hợp lệ cho câu hỏi Code Golf.http://codegolf.stackexchange.com/questions/N
  • Mỗi hình ảnh được hiển thị trong phần thân của câu hỏi N phải được lưu vào một tệp trên máy tính cục bộ. Một trong những vị trí sau đây được chấp nhận:
    • Thư mục hiện tại
    • Một thư mục đầu vào của người dùng
  • Chương trình của bạn không được lưu các tệp khác ngoài hình ảnh trong thân câu hỏi (ví dụ: hình đại diện của người dùng hoặc hình ảnh có trong câu trả lời).
  • Hình ảnh phải được lưu với phần mở rộng tập tin giống như bản gốc.

Đây là một - viết chương trình ngắn nhất bạn có thể.

Tiêu chí hiệu lực cho câu trả lời

Có nhiều trường hợp cạnh có thể khác nhau với nhiều hình ảnh cùng tên, văn bản có cùng tên với các thành phần HTML, v.v ... Câu trả lời sẽ chỉ bị vô hiệu nếu có thể bị lỗi trong một số sửa đổi của câu hỏi được đăng trước ngày 10 tháng 1 năm 2015 .


Tên hình ảnh nên được giữ nguyên hoặc chúng ta có thể làm như 0.png, 1.png, v.v.
stokastic

@stokastic Bạn có thể đặt tên cho phần trước phần mở rộng thành bất cứ điều gì bạn muốn (miễn là bạn không sử dụng cùng tên hai lần, ghi đè lên một tệp trước đó).
frageum

Câu trả lời:


10

Toán học, 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"}]

Ung dung:

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

Nó khá đơn giản. Tôi đã thiết lập bộ lọc cho API StackExchange, chỉ trả về phần thân của câu hỏi. Mã lấy thông tin câu hỏi với bộ lọc đó và phân tích cú pháp dưới dạng JSON. Tôi chọn phần tử chính xác (phần thân) và sử dụng ImportStringđể phân tích HTML và lọc tất cả các URL hình ảnh.FileNameTake@#~Export~Import@#sau đó tải xuống từng hình ảnh và lưu trữ nó trong thư mục làm việc hiện tại với cùng tên tệp như trong URL.

Bạn có thể tìm ra thư mục làm việc hiện tại với Directory[].

Về nguyên tắc, có một phiên bản ngắn hơn nhiều, vì ImportStringthực sự có thể tải xuống tất cả các tệp ngay lập tức, thay vì chỉ đưa cho tôi các URL. Nhưng sau đó tôi mất thông tin về loại tệp gốc (vì chúng được chuyển đổi thành Imagecác đối tượng khi tải xuống), vì vậy tôi chỉ có thể lưu tất cả chúng dưới dạng cùng loại (PNG, giả sử).


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

với khoảng trắng

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

kịch bản phải được chạy từ trang stackexchange để làm việc. Sẽ mặc định cho trang hiện tại nếu không có số câu hỏi được chỉ định trong lời nhắc


1
Như @doorknob đã đề cập ở trên, bạn có thể tiết kiệm một chút bằng cách hoán đổi q cho câu hỏi. Và nếu bạn không phiền khi nhận được tất cả các hình ảnh trong bài viết trên trang, bạn có thể $('[src*="imgur"]',d)tin tôi. Tôi thích điều này có thể được chạy trong giao diện điều khiển - sự hài lòng ngay lập tức.
Giô

1
questionscó thể rút ngắn lại q, nhưng nó nên bao gồm codegolf.stackexchange.comphần thay vì dựa vào việc ở trang đó. @Josiah có thể bao gồm hình ảnh từ các tên miền khác trong bài viết.
frageum

1
Bộ chọn #question .post-text imgcó thể được rút ngắn thành .post-text:first imghoặc .post-text:eq(0) img.
cPu1

5

Python 2 - 241 byte

Khá đơn giản, có lẽ có thể được chơi golf hơn nữa. Tôi tìm kiếm các trang web cho tất cả các lần xuất hiện img src=giữa lần xuất hiện đầu tiên post-text/divngay sau đó. Mỗi url hình ảnh sau đó được đọc và lưu vào thư mục làm việc.

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

Tên tệp được giữ nguyên - tên được lấy là 9 byte cuối cùng ( [-9:]) của url hình ảnh, sẽ giữ tên 5 ký tự và a .pnghoặc .jpgv.v. Nó sẽ cắt các byte của tên tệp nếu phần mở rộng dài hơn 3 ký tự .
stokastic

Nếu tên tệp ngắn hơn 9 byte thì sao? Điều đó có bao gồm dấu gạch chéo trong tên tệp không?
Martin Ender

bạn có thể lưu 2 byte bằng cách tạo một forvòng lặp. for p re.findall(...):f=open(...);f.write(...)
undergroundmonorail

@mar Tôi không nghĩ rằng tên tập tin có thể được ít hơn 9 byte, nhưng tôi có thể bị nhầm lẫn
undergroundmonorail

@ MartinBüttner Tôi nghĩ rằng 9 byte là một giả định hợp lý, nhưng tôi có thể thay đổi nó nếu bạn nghĩ tôi nên làm. Đối với những gì nó có giá trị - chỉ sử dụng 6 hoặc 7 byte là đủ và vẫn sẽ đảm bảo khá nhiều tên tệp riêng biệt.
stokastic

2

Toán học, 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[])

Điều này xuất hình ảnh theo cách tương tự như Martin đã làm trong giải pháp Mathicala của mình, đọc câu trả lời của anh ấy để biết thêm thông tin về điều đó. Cách tiếp cận này rất khác với cách tiếp cận của anh ấy, thay vì phân tích kết quả từ API tôi phân tích trực tiếp trang HTML. Hay đúng hơn, tôi phân tích cú pháp XML tượng trưng mà Mathicala có thể tạo ra từ HTML.


1

Python 2 - 398 342 334 byte

Chương trình tải xuống trang SE, trích xuất phần bài đăng (phần tử div văn bản), tìm các url kết thúc bằng phần mở rộng hình ảnh và tải chúng xuống. Các hình ảnh được lưu như img<n>.<ext>trong thư mục hiện tại.

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

Chương trình này cũng sẽ tải xuống hình ảnh được cung cấp dưới dạng liên kết, không chỉ hình ảnh được nhúng. Bằng cách cung cấp cho mỗi hình ảnh một tên tệp duy nhất, tránh đụng độ tên.


2
Bạn có thể lưu 8 ký tự bằng cách thay thế questionsbằng q(trong URL).
Doorknob

Trong câu hỏi 43274, tôi chỉ thấy 11 hình ảnh, nhưng 21 hình ảnh được tải xuống.
frageum

Chương trình của tôi tải xuống 10 hình ảnh độ phân giải cao cũng như 10 hình thu nhỏ. Tôi không chắc chắn các mục khác lấy các phiên bản có độ phân giải cao.
Hiệp sĩ logic

@Doorknob - cảm ơn. Tôi bỏ lỡ điều đó. Tôi sẽ cần nhiều hơn nữa để bắt những kẻ khác.
Logic Knight

1
@CarpetPython mặc dù điều đó được cho là hữu ích hơn ... ý định của thông số kỹ thuật là chỉ tải xuống những hình ảnh có thể nhìn thấy.
frageum

1

Bash - 86 byte

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

Không có gì wget sẽ không sửa chữa. -npngăn wget vào các thư mục phía trên (User Imss) -Achỉ lấy các tệp có phần mở rộng khớp với danh sách được trình bày. -rlà một tải về đệ quy. -lngăn wget đi quá sâu. $1là câu hỏi để lấy.


1
Có một cái gì đó cụ thể tôi cần phải làm cho điều này để làm việc? Tôi đã thử nó trên một vài câu hỏi, nhưng không tốt. Đầu ra ở đây .
Geobits

1
Tôi nghĩ ou có thể lưu 8 ký tự bằng cách thay thế questionsbằng qURL.
TimTech

1

Node.js, 251 247 byte

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

Sử dụng requestđể tạo HTTP GETs và cheeriophân tích HTML. Xung đột tên được giải quyết bằng cách thêm chỉ mục của hình ảnh hiện tại vào tên cơ sở của URL của tệp. Hình ảnh được lưu vào cùng thư mục với tập tin hiện tại.


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)

Chấp nhận số này làm đối số dòng lệnh.

Giả sử bất kỳ src=thuộc tính nào sẽ dành cho một imgthẻ vì đây là các thẻ duy nhất có các srcthuộc tính mà trao đổi ngăn xếp cho phép (phải không?).

Cũng lưu ý các .. .... Tôi đặc biệt tự hào về điều đó.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.