显示一个xkcd


36

xkcd是每个人都喜欢的网络漫画,您将编写一个程序,给我们大家带来更多的幽默感。
解决此挑战的目标是编写一个程序,该程序将数字作为输入并显示xkcd及其标题文本(复写文本)。

输入值

您的程序将以一个正整数作为输入(不一定是一个有效的漫画)并显示xkcd:例如,输入1500应该在xkcd.com/1500上显示漫画“ Upside-Down Map”,然后将其标题文本打印到控制台或与图像一起显示。

由于它们靠近海峡,北朝鲜与大不列颠及南爱尔兰联合王国之间一直存在紧张关系。 Due to their proximity across the channel, there's long been tension between North Korea and the United Kingdom of Great Britain and Southern Ireland.

测试案例2,n = 859:

撇开脑子,我想知道有多少写得不好的xkcd.com解析脚本会因该标题而中断(或;;“” {<< ['此鼠标悬停文本。“

Brains aside, I wonder how many poorly-written xkcd.com-parsing scripts will break on this title (or ;;"''{<<[' this mouseover text."

您的程序也应该能够在没有任何输入的情况下运行,并对xkcd.com上的最新xkcd执行相同的任务,并且即使出现新的xkcd,它也应始终显示最新的xkcd。

您不必直接从xkcd.com获取图像,您可以使用其他数据库,只要它是最新的并且在挑战开始之前就已经存在。不允许使用URL缩写,即,没有重定向到其他地方的URL。

您可以通过选择的任何方式显示图像,包括在浏览器中。但是,您可能无法直接在iframe或类似内容中显示另一页的一部分。澄清:您无法打开预先存在的网页,如果您想使用浏览器,则必须创建一个新页面。您还必须实际显示图像-不允许输出图像文件。

您可以以任何希望的合理方式处理特定漫画没有图像的情况(例如,它是交互式的,或者程序被传递的数量大于已发行漫画的数量),包括引发异常,或打印至少一个字符的字符串,只要它能以某种方式向用户表明该输入没有图像。

您只能显示图像并输出其标题文本,或者输出无效漫画的错误消息。不允许其他输出。

这是一个挑战,因此最少的字节获胜。


1
@LukeFarritor您只能显示图像并输出标题文本,或为某种无效的漫画输出某种形式的错误消息。
帕维尔

9
如果您的样本大小为1,则为import antigravityPython;)
Wayne Werner

15
有趣的事实n=404 xkcd.com/404是404页面。
魔术章鱼缸

11
xkcd is everyone's favorite webcomic [需要引用 ]
Sanchises'Oct

11
测试案例:859
betseg

Answers:


13

Perl + curl + feh,86 84 75字节

`curl xkcd.com/$_/`=~/<img src="(.*)" title="(.*?)"/;$_=$2;`feh "http:$1"`

需要-p开关。我已经在字节数中说明了这一点。


@Matt它适用于我尝试过的所有漫画。它仅匹配具有替代文本的图像。
意大利面条

您可能不需要在src属性周围加引号。
科纳·奥布莱恩

我认为您不需要?在第一个比赛组中。您可以使用-p$_=$2而不是print$2,但是仅关闭feh 之后才打印标题文本。不知道这是否有效。
m-chrzan

@ m-chrzan是的,我可以在这里放下不愿使用的量词,谢谢。我曾考虑过使用,-p但不确定OP对它的感觉。
意大利面条

@ ConorO'Brien不幸的是Randall遵循良好的HTML编码惯例...由于反引号在Perl中是如何工作的,因此捕获引号不会引用引数。
意大利面条

9

PowerShell的V3 + 110 99 107 103个字节

iwr($x=((iwr "xkcd.com/$args").images|?{$_.title})).src.Trim("/") -outf x.jpg;if($x){ii x.jpg;$x.title}

感谢Timmy通过使用内联分配帮助节省了一些字节。

如果未传递任何参数,$args则为null,它将仅获取当前漫画。通过将图片与alt文本匹配,将图片下载到脚本当前运行目录中的文件中。然后使用jpg的默认查看器显示它。替代文本随后显示到控制台。iwr是的别名Invoke-WebRequest

如果传递的数字(或与此相关的任何无效输入)不匹配,则该过程将失败,并至少出现404错误。

iwr(                                  # Request the comic image from XKCD
  $x=((iwr "xkcd.com/$args").images|  # Primary search to locate either the current image
                                      # or one matching an argument passed
     ?{$_.title}))                    # Find the image with alt text
        .src.Trim("/")                # Using the images associated link and strip the leading slashes
  -outf x.jpg                         # Output the image to the directory local to where the script was run
if($x){                               # Test if the image acquisition was successful
    ii x.jpg                          # Open the picture in with the default jpg viewer
    $x.title                          # Display alt text to console
}                                     # I'm a closing bracket.

现在才刚刚获得关于此
订阅的

@ConnorLSW答案中的好方法。下次需要考虑的事情。
马特

8

AutoIt,440字节

是的,很长,但是很稳定。

#include<IE.au3>
#include<GDIPlus.au3>
Func _($0='')
_GDIPlus_Startup()
$1=_IECreate('xkcd.com/'&$0)
For $3 In $1.document.images
ExitLoop $3.title<>''
Next
$4=_GDIPlus_BitmapCreateFromMemory(InetRead($3.src),1)
$6=_GDIPlus_ImageGetDimension(_GDIPlus_BitmapCreateFromHBITMAP($4))
GUICreate(ToolTip($3.title),$6[0],$6[1])
GUICtrlSendMsg(GUICtrlCreatePic('',0,0,$6[0],$6[1]),370,0,$4)
_IEQuit($1)
GUISetState()
Do
Until GUIGetMsg()=-3
EndFunc

首先,这不会使用RegEx抓取网站(因为我没有时间在所有漫画上进行测试),而是使用Internet Explorer API遍历DOM的img标签,直到找到带有标题文本的标签为止。

二进制流从图像URL中读取,并使用GDIPlus渲染为位图。然后将其显示在一个不错的,自动调整大小的GUI中,并带有实际的工具提示,以使其行为几乎与网站完全相同。

这是一个测试案例(_(859)):


4
如果将支架重新添加到图像中会更好。
马特

哇,刚刚发现我可以在Ubuntu上的Wine下运行AutoIt。现在,我要做的就是让IE在那上面工作。关于第二个想法... +1的答案
ElPedro '16

2
@ElPedro如果您有现代的CPU,请使用qemu KVM和SeamlessRDP(基本上是Linux的DIY并行)而不是wine。这将Windows应用程序无缝集成到Linux桌面中,并具有100%兼容性+ GPU直通。只是一个小费。
mınxomaτ

谢谢@mınxomaτ。我可以试一试。我整天都在使用Windows,所以更喜欢在工作时不使用Linux(各种口味),但是我一直对实验感兴趣:)感激不尽。
ElPedro

7

Powershell,93字节

93字节版本以使用本地图像查看器。

$n=(iwr xkcd.com/$args).images|?{$_.title};$n.title;iwr ("http:"+$n.src) -OutF x.jpg;ii x.*

通过删除不必要的双引号节省了2个字节,然后通过使用("http:"+$n.src)代替"https://"+$n.src.trim("/")- 节省了很多字节,因为imgsrc //已经附带在其中,并且xkcd不需要https。

$n=(iwr xkcd.com/$args).images|?{$_.title};$n.title;saps ("http:"+$n.src)

$n=(iwr "xkcd.com/$args").images|?{$_.title};$n.title;saps ("https://"+$n.src.trim("/"))

与Matts powershell答案极为相似,(可能应该是评论,但声誉较低)

取而代之的是,这会在默认浏览器中打开一个新的标签页/窗口,并在其他地方保存一些字节。

iwr 是的别名 Invoke-WebRequest

saps是一个别名,Start-Process在默认上下文中为其打开“ it”。


跳过有关打开现有网页的规则的边缘,因为这只是直接在预先存在的.jpg(或任何其他位置)上启动浏览器,但这是一个不错的答案。
AdmBorkBork

@TimmyD可能在这里被误解了-我以为您可以使用xkcd网页本身- 如果您希望在默认本地打开它,则可以更改sapsiwr-OutF x.jpg; ii x。*图像查看器。
colsw

1
OP指定不允许您打开预先存在的网页。我认为可以使用93字节的版本,但这是
一个意大利面条

如果您提供一个有效的数字,然后再输入一个无效的数字,我认为这不会总是一样。它将打开先前运行中存在的图像。
马特

我接受93字节的版本,但您的较短版本违反了拼图的条件。
帕维尔

4

R,358个 328 310 298字节

f=function(x){H="http:";p=paste0;library(XML);a=xpathSApply(htmlParse(p(H,'//xkcd.com/',x)),'//div/img',xmlAttrs)[[1]];download.file(p(H,a[1]),'a');I=`if`(grepl('png',a[1]),png::readPNG,jpeg::readJPEG)('a');d=dim(I)/100;quartz(,d[2],d[1]);par(mar=rep(0,4));frame();rasterImage(I,0,0,1,1);cat(a[2])}

带有新行和注释:

f=function(x){
H="http:"
p=paste0
library(XML) #Needed for xpathSApply, htmlParse and xmlAttrs
# The following line find the first img element and extract its attributes
a=xpathSApply(htmlParse(p(H,'//xkcd.com/',x)),'//div/img',xmlAttrs)[[1]]
download.file(p(H,a[1]),'a') #Download to a file called 'a'
I=`if`(grepl('png',a[1]),png::readPNG,jpeg::readJPEG)('a') #Check if png or jpeg and load the file accordingly
d=dim(I)/100 #convert dimension from pixel to inches (100 ppi).
quartz(,d[2],d[1]) #open a window of the correct dimension
par(mar=rep(0,4)) #Get rid of margins
frame() #Create empty plot
rasterImage(I,0,0,1,1) #Add png/jpeg to the plot
cat(a[2]) #Print title text to stdout
}

测试用例的屏幕截图:

对于x = 1500: 对于x = 1500(png)

对于x空:
对于x =''

图片为jpeg的情况:
对于x = 10(jpeg)

x = 859:
x = 859


我想知道是否有必要以正确的尺寸显示图像。当我玩这个挑战时,我干脆就做plot.new();rasterImage(...)
Billywob

@Billywob好吧,因为情节的默认大小是7x7英寸,所以它会完全失真。这是真的,该任择议定书没有明确地索要图像不会失真,但我更喜欢这种方式:)不过我正在考虑摆脱的xaxs,并yaxs作为结果仍然是相称的。
plannapus


2

Python 2.7版,309个 299 295 274字节

完整程序。绝对更适合打高尔夫,但是已经读了xkcd漫画很长时间了,我不能让它过去(谁知道这在将来对轻松浏览xkcd会有帮助)。

如果未通过任何输入,则获取当前漫画。如果传递了有效的漫画编号作为输入,则获取该漫画。如果传递了无效的输入(不是有效范围内的数字漫画),则会引发错误。

欢迎提供有关减少字节数的任何建议!当我有更多时间时,将重新访问(并添加说明)。

-10个字节,感谢@Dopapp

-21字节感谢@Shebang

import urllib as u,re
from PIL import Image
h='http://';x='xkcd.com/'
o=u.URLopener()
t=u.urlopen(h+x+raw_input()).read()
c=sum([re.findall(r,t)for r in[h+'imgs.'+x+'c.*s/.*\.\w{1,3}','\.\w{1,3}" t.*e="(.*)" a']],[])
Image.open(o.retrieve(c[0],'1.png')[0]).show();print c[1]

1
您可以将try:...和更改except:...try:n=...except:n='',共节省10个字节
Daniel Daniel

1
你为什么还要try发表声明?程序规范说,您将始终得到一个正整数。
卡德,

@Shebang,如果没有输入,它还应该返回最新的漫画。没有输入错误的例外,我无法处理这种情况。
Ioannes

1
@Joannes为什么不使用raw_input()?默认情况下,用户可以按[Enter]并且n仍然包含空字符串。如果删除该try-except块,t=u.urlopen(h+x+n).read() -> t=u.urlopen(h+x+raw_input()).read()您会将其压缩到274个字节。
卡德

这不再起作用,因为xkcd图像URL使用https。但是,它仍然有效,因为它在发布时起作用。要使其现在起作用,请将第3行更改h='https://'为以+1字节开头。
Mego

2

PHP,42字节

<?=@file('http://xkcd.com/'.$_GET[i])[59];

保存到文件并在您选择的Web服务器中启动


1
欢迎来到PPCG!我不知道PHP,但是您的代码中似乎没有一部分正在提取图像的标题文本?
Pavel

1

JavaScript + HTML,124 + 18 = 142个字节

i=>fetch(`//crossorigin.me/http://xkcd.com/${i||""}/info.0.json`).then(r=>r.json()).then(d=>(A.innerHTML=d.alt,B.src=d.img))
<img id=B><p id=A>

跨域解决方案感谢Kaiido在这里的回答

//crossorigin.me/如果可以减去连接到xkcd.com所需的代理,则可以节省17个字节()(有关此内容的meta post)。

测试片段

f=
i=>fetch(`//crossorigin.me/http://xkcd.com/${i||""}/info.0.json`).then(r=>r.json()).then(d=>(A.innerHTML=d.alt,B.src=d.img))
<style>img{width:50%}</style><input id=I> <button onclick="f(I.value)">Run</button><br>
<img id=B><p id=A>


1

蟒3 +请+ PIL,192个 186字节

from requests import*
import PIL.Image as f
from io import*
r=get("https://xkcd.com/%s/info.0.json"%input()).json()
f.open(BytesIO(get(r["img"],stream=1).content)).show()
print(r["alt"])

打开包含漫画的图像查看器(运行它的系统上的默认值),并将标题文本发布到控制台。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.