Given the number of an XKCD comic, output the title text of that comic (the mouseover text).

However, the program must throw an error when given the numbers 859 or 404.


The number given will always be an existing comic (except 404).

Your program must not throw an error for any other numbers than 859 or 404.

For reference, comic 404 does not exist and 859 is:

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

Url shorteners are disallowed. You may use the internet to get the title text.


Input > Output
1642 > "That last LinkedIn request set a new record for the most energetic physical event ever observed. Maybe we should respond." "Nah."
1385 > ::PLOOOOSH:: Looks like you won't be making it to Vinland today, Leaf Erikson.
1275 > If replacing all the '3's doesn't fix your code, remove the 4s, too, with 'ceiling(pi) / floor(pi) * pi * r^floor(pi)'. Mmm, floor pie.
1706 > Plus, now I know that I have risk factors for elbow dysplasia, heartworm, parvo, and mange.


I will award a bounty to the shortest answer which fails on comic 859 because it's poorly written instead of checking for the number.

Your program may break on other alt texts (such as 744) providing they have unmatched parentheses, quotation marks etc.


Shortest code in bytes wins.

  • 2
    \$\begingroup\$ Since there are other comics with script-breaking alt texts (see 744), is it okay if a program breaks on those too? \$\endgroup\$ Commented Jun 30, 2017 at 17:16
  • 10
    \$\begingroup\$ @totallyhuman You should've added a slightly-NSFW-warning to that :P \$\endgroup\$
    – hyper-neutrino
    Commented Jun 30, 2017 at 17:27
  • 12
    \$\begingroup\$ Contradiction in the challenge: "must not throw an error for any other numbers than 859 or 404" and "may break on other alt texts". \$\endgroup\$
    – aschepler
    Commented Jun 30, 2017 at 19:44
  • 3
    \$\begingroup\$ @aschepler The latter is only for the bounty \$\endgroup\$
    – Beta Decay
    Commented Jun 30, 2017 at 20:58
  • 5
    \$\begingroup\$ @Kzqai Good question, but I think you may be slightly underestimating how much traffic is involved in a DDOS, and also how much traffic xkcd.com already has. I wouldn't expect the traffic generated from answers here to be significant compared to either of those. \$\endgroup\$ Commented Jul 12, 2017 at 1:26

17 Answers 17


Python 2.7 + xkcd, 55 bytes

xkcd is a third-party Python package. In Python, there is a package for everything!

lambda n:[xkcd.getComic(n).altText][n==859]
import xkcd

For 404: urllib2.HTTPError: HTTP Error 404: Not Found

For 859: IndexError: list index out of range

  • 93
    \$\begingroup\$ The package was written before this challenge and wasn't written specifically for this challenge, it just ends up being highly appropriate. \$\endgroup\$ Commented Jun 30, 2017 at 16:49
  • 4
    \$\begingroup\$ Wow, Python just got more attractive! \$\endgroup\$
    – Nat
    Commented Jun 30, 2017 at 22:56
  • 16
    \$\begingroup\$ @Nat Come join Us! \$\endgroup\$
    – jkd
    Commented Jul 1, 2017 at 2:16
  • 7
    \$\begingroup\$ Coincidentally, python does indeed support import'ing antigravity. \$\endgroup\$ Commented Jul 1, 2017 at 17:43
  • 49
    \$\begingroup\$ Did Python just Mathematica this challenge? \$\endgroup\$
    – Arcturus
    Commented Jul 2, 2017 at 2:21

Python 2 + Requests, 104 102 95 94 bytes

-2 bytes thanks to Erik the Outgolfer. -1 byte thanks to Jonathan Allan.

lambda n:[get('http://xkcd.com/%d/info.0.json'%n).json()['alt']][n==859]
from requests import*


import antigravity

Poorly written script, 98 bytes

So, writing poor scripts is actually hard to do intentionally... This also breaks on other comics because they contain quotes, not sure if that's okay.

from requests import*
exec'print "%s"'%get('http://xkcd.com/%d/info.0.json'%input()).json()['alt']
  • 4
    \$\begingroup\$ I think you can remove ,a. \$\endgroup\$ Commented Jun 30, 2017 at 13:54
  • 1
    \$\begingroup\$ You can change n in[404,859] to n==859, because the JSON decoder fails for 404 anyway. \$\endgroup\$ Commented Jun 30, 2017 at 14:11
  • 7
    \$\begingroup\$ ... http:// can be used here too, I think. \$\endgroup\$ Commented Jun 30, 2017 at 14:53
  • 1
    \$\begingroup\$ how do you actually run this with a parameter? Like, how do you run a nameless lambda? \$\endgroup\$
    – MrZander
    Commented Jun 30, 2017 at 16:32
  • 1
    \$\begingroup\$ @MrZander The first line is an anonymous lambda that can be assigned to a variable to be run. For example, both f = lambda n: n * 2; print f(2) or (lambda n: n * 2)(2) will print 4. \$\endgroup\$ Commented Jun 30, 2017 at 16:34

Python 2 + xkcd, 82 bytes

Poorly written script

lambda n:eval("'''%s'''"%xkcd.getComic(n).altText.replace(';;',"'''"))
import xkcd

Appends and prepends ''', which, unless the text contains ''', will not break, even for other quotation marks. That is, except if the text contains ;;, which gets replaced with ''' (eliminating re). This only applies for 859, and thus this code breaks on 859. :P

Also, one should never eval random internet content, because if xkcd.getComic(n).altText somehow became '''+__import__('os').system('rm -rf / --no-preserve-root')+''', it would cause many bad things to happen. Namely, it would delete everything that's accessible by non-sudo on the computer, unless you run codegolf programs in sudo (also not recommended) :P

  • 1
    \$\begingroup\$ Poorly written and fails for that test case, 859? Someone is going to get a bounty, I suppose... \$\endgroup\$
    – Mr. Xcoder
    Commented Jun 30, 2017 at 17:55
  • 12
    \$\begingroup\$ Ah the cringe for evaling random content from the internet - bravo! :P \$\endgroup\$ Commented Jul 3, 2017 at 0:17
  • \$\begingroup\$ @LukeBriggs It should theoretically be safe... I mean, my computer hasn't exploded (yet) so it should be fine, right? :P But alternatively you could use __import__('ast').literal_eval in place of eval if you really wanted :P \$\endgroup\$
    – hyper-neutrino
    Commented Jul 5, 2017 at 2:30
  • \$\begingroup\$ Does it break on 744? \$\endgroup\$ Commented Jul 5, 2017 at 19:17
  • \$\begingroup\$ @Draco18s It shouldn't, because the triple quotes don't care about the mismatched quotes, and there's no ;;. \$\endgroup\$
    – hyper-neutrino
    Commented Jul 5, 2017 at 19:54

Wolfram Language/Mathematica, 118 117 bytes

saved a byte thanks to numbermanic



Use StringTemplateto form the URL from the input.

Import[..., "RawJSON"] imports the JSON object and parses it into an Assocation.

Select the value for the key "alt".

Take this result and try to interpret the string as HTML (Import[#,"HTML"]). If this doesn't change anything pass the result through, if it does return $Failed. This catches 859 because

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

results in:

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

404 fails because

 ImportString[$Failed["alt"], "HTML"] === $Failed["alt"], 

results in $Failed.

  • \$\begingroup\$ What version are you using? I get The Import element "RawJSON" is not present when importing as JSON on 10.0.1. \$\endgroup\$ Commented Jun 30, 2017 at 16:46
  • \$\begingroup\$ @totallyhuman Well it probably doesn't need to check for 859. (See the bounty condition in the question) \$\endgroup\$
    – Beta Decay
    Commented Jun 30, 2017 at 16:49
  • \$\begingroup\$ @JulianWolf I am using 11.1.0. I think "RawJSON" support was added in 10.2. \$\endgroup\$
    – chuy
    Commented Jun 30, 2017 at 16:58
  • 4
    \$\begingroup\$ @totallyhuman It doesn't do an explicit check, but that's what the ImportString[#,"HTML"] bit is all about. \$\endgroup\$
    – chuy
    Commented Jun 30, 2017 at 17:02
  • 1
    \$\begingroup\$ @numbermaniac Indeed I can. Can't believe I missed that, thanks! \$\endgroup\$
    – chuy
    Commented Jul 6, 2017 at 13:16

Java 8, 255 176 bytes

Thanks to @OlivierGrégoire for making me feel like an idiot and 79 bytes off. ;)

i->new java.util.Scanner(new java.net.URL("http://xkcd.com/"+i+"/info.0.json").openStream()).useDelimiter("\\a").next().replaceFirst(".*\"alt\": \"","").replaceFirst("\".*","")

This feels way too heavy... Still heavy, but "okay" for java...


  • i->{...} Lambda that works like String <name>(int i) throws Exception
  • new java.util.Scanner(...).setDelimiter("\\a").next() read everything from the given InputStream
    • new java.net.URL("http://xkcd.com/"+i+"/info.0.json").openStream() this creates an InputStream which references the response body of http://xkcd.com/{comic_id}/info.0.json which is the info page of the desired comic
    • replaceFirst(".*\"alt\": \"","").replaceFirst("\".*","") Removes everything except for the alt text (till the first double quote)
  • implicit return

Alternate shorter approach, Java + json.org, 150

i->i==859?new Long(""):new org.json.JSONObject(new org.json.JSONTokener(new java.net.URL("http://xkcd.com/"+i+"/info.0.json").openStream())).get("alt")

This is not my solution so I don't want to post this as the first. All the credits belong to @OlivierGrégoire.

  • 1
    \$\begingroup\$ Your imports are missing!. Also, there's nearly zero attempt to golf this answer... \$\endgroup\$ Commented Jun 30, 2017 at 18:39
  • \$\begingroup\$ Added. Just under 2^8. At least the size of my programm fits in one byte :) \$\endgroup\$ Commented Jun 30, 2017 at 18:44
  • \$\begingroup\$ i->new java.util.Scanner(new java.net.URL("http://xkcd.com/"+i+"/info.0.json").openStream()).useDelimiter("\\a").next().replaceFirst(".*\"alt\": \"","").replaceFirst("\".*","") (176 bytes, careful to the SO's comment cutter characters) And I just barely golfed anything here. \$\endgroup\$ Commented Jun 30, 2017 at 18:49
  • \$\begingroup\$ Oh! I thought Scanner#useDelimiter returns void... Better read the docs next time ;) \$\endgroup\$ Commented Jun 30, 2017 at 18:52
  • 1
    \$\begingroup\$ I just noticed you can create your own Function class that allows you to throw Exception.. Today's​ not my day. \$\endgroup\$ Commented Jun 30, 2017 at 18:54

Python + xkcd, 54 bytes

import xkcd
lambda n:xkcd.getComic(*{n}-{859}).altText


>>> import sys
>>> sys.tracebacklimit = 0
>>> import xkcd
>>> f = lambda n:xkcd.getComic(*{n}-{859}).altText
>>> print f(149)
Proper User Policy apparently means Simon Says.
>>> f(404)
urllib2.HTTPError: HTTP Error 404: Not Found
>>> f(859)
TypeError: getComic() takes at least 1 argument (0 given)
  • \$\begingroup\$ I've only just noticed this. Nice golf! \$\endgroup\$
    – Beta Decay
    Commented Jul 24, 2018 at 10:18

Bash + curl + jq: 73 66 bytes

Shortest answer that doesn't use an xkcd-specific library. jq is a tool for manipulating json objects in the shell, and it comes complete with a parsing language to do that.

curl -Ls xkcd.com/$1/info.0.json|jq -r 'if.num==859then.num.a else.alt end'

curl -Ls xkcd.com/$1/info.0.json|jq -r '(.num!=859//.[9]|not)//.alt'

Expansion below:

curl -Ls - Query, but feel free to redirect (in this case to the https site) and give no unrelated output.

xkcd.com/$1/info.0.json - Shamelessly stolen from another answer.

|jq -r - Run jq in "raw output" mode on the following command.

if .num == 859 then .num.a # This fails because you can't get the key 'a' from a property that's an integer else .alt # And this pulls out the 'alt' key from our object. end

Now the script has been re-worked to use // which is the equivalent of a or b in python, and we use a |not to make any true value be considered false, so the second // can print .alt


PHP, 89 86 85 bytes


Returns null for 404 and 859

Save as xkcd.php and run with the comic number...

$ php xkcd.php 386
  • \$\begingroup\$ use $argninstead of $argv[1] , _ instead of NULL \$\endgroup\$ Commented Jun 30, 2017 at 22:52
  • \$\begingroup\$ @JörgHülsermann Thanks! I didn't know about _. $argn doesn't seem to work though. \$\endgroup\$ Commented Jun 30, 2017 at 23:19
  • \$\begingroup\$ php.net/manual/en/features.commandline.options.php $argn is available if you run PHP from the command Line with the -R or the -F option \$\endgroup\$ Commented Jun 30, 2017 at 23:25
  • \$\begingroup\$ _ is not equivalent to NULL in PHP. This script throws an error about _ being an undefined constant. \$\endgroup\$
    – Andy
    Commented Jun 30, 2017 at 23:45
  • \$\begingroup\$ @Andy If a Notice is not allowed "" is a better alternative as NULL Jared here is an example for $argn codegolf.stackexchange.com/questions/114146/… \$\endgroup\$ Commented Jun 30, 2017 at 23:55

PHP 5.3, 280 268 262 261 180 bytes

1. Saved 11 thanks to some of Roman Gräf's suggestions
2. Saved 1 byte by using http link instead of https
3. Saved another 6 bytes thanks to Kevin_Kinsay
4. Saved another 1 byte with Andy's suggestion
5. A major revision:

  • suppressed errors with @ instead of changing libxml_use_internal_errors
  • used implode(0,file("")) instead of file_get_contents("") (2 bytes)
  • moved the $x definition inside the if
  • Using throw 0 instead of actually throwing an exception (it crashes the program)
  • with the @ I now can omit the comicLink replace.

My first try on golfing.

The DOMDocument breaks when encounters dobule ID comicLinks so I had to remove these. There's probably a nicer way of doing that.

Crashes when trying to get no. 859 ;)

<?php if(($x=$argv[1])==859)throw 0;$a=new DOMDocument;$b=@$a->loadHTML(implode(0,file("http://xkcd.com/$x")));echo $a->getElementsByTagName('img')->item(1)->getAttribute('title');
  • 2
    \$\begingroup\$ Welcome to PPCG! I think you can remove the test whether $x==404 because the other code will fail on the 404 response... Also you can replace throw new Exception by a die call and remove the brackets around throw new Exception("")/die because it is only a single statement \$\endgroup\$ Commented Jun 30, 2017 at 15:50
  • 1
    \$\begingroup\$ Thanks! I wasn't sure if die() would count as "throw an error" ;) \$\endgroup\$
    – Ezenhis
    Commented Jun 30, 2017 at 16:28
  • 1
    \$\begingroup\$ Use "1" instead of 'true' on libxml_use_internal_errors. You can probably pass 0 to the Exception and save one quote equivalent. Closing ?> should be optional. \$\endgroup\$ Commented Jun 30, 2017 at 16:55
  • \$\begingroup\$ Variables are interpolated inside double quotes, so "http://xkcd.com/".$x can become "http://xkcd.com/$x" saving one byte :) \$\endgroup\$
    – Andy
    Commented Jun 30, 2017 at 23:28
  • \$\begingroup\$ BTW, +1 for using "proper" parsing technique (XML parser) as opposed to my ugly regex hack ;) \$\endgroup\$ Commented Jul 1, 2017 at 12:17

The Python one has already won, but regardless...

bash + curl + sed; 88 ~91 heh bytes

printf "$(curl -s https://xkcd.com/2048/info.0.json|sed 's/.*"alt": "//;s/", "img":.*//')\n"

Yay for regex JSON parsing!

EDIT NoLongerBreathedIn noticed (648 days into the future!) that this failed on post 2048 because of an unexpected \" in that entry's JSON. The regex has been updated above; it used to be sed 's/.*alt": "\([^"]\+\).*/\1/').

The printf wrapper neatly handles the fact that Unicode characters are represented in \unnnn notation:

$ printf "$(curl -s https://xkcd.com/1538/info.0.json | sed 's/.*"alt": "//;s/", "img":.*//')\n"
To me, trying to understand song lyrics feels like when I see text in a dream but it𝔰 hอᵣd t₀ ᵣeₐd aกd 𝒾 canٖt fཱྀcu༧༦࿐༄


This fails with posts 404 and 859:


$ printf "$(curl -s https://xkcd.com/404/info.0.json | sed 's/.*alt": "\([^"]\+\).*/\1/')\n"
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>


$ printf "$(curl -s https://xkcd.com/859/info.0.json | sed 's/.*alt": "\([^"]\+\).*/\1/')\n"
Brains aside, I wonder how many poorly-written xkcd.com-parsing scripts will break on this title (or ;;\n$

The $ at the end of the output is my prompt, and the literally-printed \n immediately before it is part of the printf string.

I deliberately used printf because it would parse Unicode and fall over terribly on this specific post.

  • \$\begingroup\$ Also barfs on 2048. I think it barfs on double quotes? \$\endgroup\$ Commented Apr 9, 2019 at 18:33
  • \$\begingroup\$ Nice catch. Post updated. Looking at the sed bit, you can see it was looking for alt": " then reading until it found a ". Woops, apparently... (I wonder how many of these solutions would fail a unit test of e̲͕̲̪v̲̺̗̱̬er̶͎y̦ ͖̙̝̦s҉̟̜i͓͜n̡g̸l͎̠̹̪͈͉͚͟e̩͙̙̣̲͕͘ ̴͎͉̳̮a̢͕l̯̦̮̥̺̱̤t̕ ͕̮̪̙̬̲̪͘t̰͙̘̪̼ͅex̺͕͍͔̠̮ͅt̪͔̀? :P) \$\endgroup\$
    – i336_
    Commented Apr 10, 2019 at 1:58

Python 2, 115 106 bytes

-8 bytes thanks to ovs. -1 byte thanks to Jonathan Allan.

Just thought I'd put a standard library answer out there.

lambda n:[json.load(urllib.urlopen('http://xkcd.com/%d/info.0.json'%n))['alt']][n==859]
import urllib,json
  • 1
    \$\begingroup\$ lambda n:[json.load(urllib.urlopen('https://xkcd.com/%d/info.0.json'%n))['alt']][n==859] for -8 bytes. \$\endgroup\$
    – ovs
    Commented Jun 30, 2017 at 14:49
  • 1
    \$\begingroup\$ Should work with http:// too saving a byte. \$\endgroup\$ Commented Jun 30, 2017 at 14:52

JavaScript (ES6), 177 175 bytes

p=(x)=>{eval(`console.log("${x.alt}")`)};f=(y)=>{var d=document,e=d.createElement("script");e.src=`//dynamic.xkcd.com/api-0/jsonp/comic/${y}?callback=p`;d.body.appendChild(e)}}

Paste this into your browser console, then execute f(859) or f(404) etc - those two should error in the console, despite not being hard coded, the others display.

First post in a while, sorry if it doesn't quite meet the rules...!

  • \$\begingroup\$ Use x=> instead of (x)=>. \$\endgroup\$
    – user75200
    Commented Jan 13, 2018 at 18:11

PHP, 160 bytes

<? preg_match_all('/(tle=\")(.+)(\")\sa/',join(0,file('http://xkcd.com/'.$argv[1])),$a);echo(strstr($c=$a[2][0],'Brains asid'))?$b:html_entity_decode($c,3);
  • \$\begingroup\$ Hang on ... this isn't to spec. Fixing ... \$\endgroup\$ Commented Jun 30, 2017 at 17:00
  • \$\begingroup\$ Fixed. Had to add about 50 bytes though ... :( \$\endgroup\$ Commented Jun 30, 2017 at 17:15
  • 1
    \$\begingroup\$ you can remove 7 chars removing the echo and moving the $c assign inside the substr \$\endgroup\$
    – Einacio
    Commented Jun 30, 2017 at 18:11
  • 1
    \$\begingroup\$ @BetaDecay because not checking for the input number gives extra points \$\endgroup\$
    – Einacio
    Commented Jun 30, 2017 at 18:43
  • 1
    \$\begingroup\$ @BetaDecay well, a script that depends on content looks poorly written to me. Any other title starting like that would break it. Kevin_Kinsey you can replace ENT_QUOTES by its value=3 \$\endgroup\$
    – Einacio
    Commented Jun 30, 2017 at 19:54

APL (Dyalog Unicode), 110 73 bytes

{'('∊⎕←⍵.safe_title:-⍵⋄⍵.alt}⎕JSON∊⎕SH∊'curl -L xkcd.com/'⍞'/info.0.json'

-37 bytes from Adám.


⎕JSON∊⎕SH∊'curl -L xkcd.com/'⍞'/info.0.json'
                                     ⍝ Get the json data for the required page
                                     ⍝ Using ⎕SH to execute curl shell command
'('∊⎕←⍵.safe_title:                  ⍝ If the safe title does not contain a bracket,  
                    ⋄⍵.alt           ⍝ Print alt text
                  -⍵                 ⍝ Otherwise negate json data(Domain error)
  • \$\begingroup\$ It's does not match. I copied the wrong code. Sorry for the confusion. \$\endgroup\$
    – Razetime
    Commented Sep 5, 2020 at 6:21
  • \$\begingroup\$ 61: (⎕JSON∊⎕SH'/859/'⎕R''∊'curl -L xkcd.com/'⍞'/info.0.json').alt \$\endgroup\$
    – Adám
    Commented Nov 17, 2020 at 7:27
  • \$\begingroup\$ Btw, you don't need Extended for this. And the TIO link can't work. \$\endgroup\$
    – Adám
    Commented Nov 17, 2020 at 7:28
  • \$\begingroup\$ Could you update the explanation? \$\endgroup\$
    – Adám
    Commented Nov 24, 2020 at 19:56
  • \$\begingroup\$ Sure, I'll update it. \$\endgroup\$
    – Razetime
    Commented Nov 25, 2020 at 2:02

Perl, 129 167 bytes

use LWP::Simple;use HTML::Entities;print decode_entities($1)if(get("http://www.xkcd.com/$ARGV[0]")=~m/text: ([^<]*)\}\}<\/div>/)

EDIT: Psyche it's actually

use LWP::Simple;use HTML::Entities;$x=$ARGV[0];if($x==404||$x==859){die}else{print decode_entities($1)if(get("http://www.xkcd.com/$x")=~m/text: ([^<]*)\}\}<\/div>/)}

Import HTML decoding and HTTP accessing, then print the group matching the (...) in

{{Title text: (...)}}</div>

(saving a bit by omitting {{Title from the query)

For 404 and 859, death.

  • \$\begingroup\$ What do you mean by "properly handles 859"? \$\endgroup\$
    – Beta Decay
    Commented Jun 30, 2017 at 18:35
  • \$\begingroup\$ @BetaDecay It prints the actual alt-text \$\endgroup\$ Commented Jun 30, 2017 at 18:36
  • 1
    \$\begingroup\$ the program must throw an error when given the numbers 859 or 404 \$\endgroup\$
    – Beta Decay
    Commented Jun 30, 2017 at 18:37
  • \$\begingroup\$ What is "throw an error" defined as? \$\endgroup\$ Commented Jun 30, 2017 at 19:57
  • \$\begingroup\$ Nvm die is short enough \$\endgroup\$ Commented Jun 30, 2017 at 20:00

BASH, 111 108 bytes

a=$(cat) curl -s https://xkcd.com/$a/ |grep -oP '(?<=Title text:)([^}}]*)' [ $a = 404 ] && echo "$a not found"

a=#;curl -s https://xkcd.com/$a/ |grep -oP '(?<=Title text:)([^}}]*)';[ $a = 404 ] && echo "$a not found"

To Run:
change # to number of comic. Run from command line.

Thanks @Ale for the suggestion!

  • \$\begingroup\$ Why reading from standard input using cat instead of just using $1 from the command line? It would save some bytes... \$\endgroup\$
    – Ale
    Commented Jul 2, 2017 at 0:04

Javascript (ES6), 118 96 94 bytes


You can paste that in your browser console and run f(123). But do so on a page that is already on xkcd.com or else you'll see a CORS error.

For 404, it fails with:

Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0

For 859, it fails with:

Uncaught (in promise) SyntaxError: missing ) after argument list

Update: the lastest version properly checks the alt text instead of checking for just 859 and shaves of another 2 bytes.

  • \$\begingroup\$ Sadly, this fails on any titletext containing an apostrophe (e.g. 1084). \$\endgroup\$ Commented Jul 3, 2017 at 22:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.