[Question]
  [
## Challenge
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`.
## Rules
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`](https://xkcd.com/404) does not exist and [`859`](https://xkcd.com/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.
## Examples
```
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.
```
## Bounty
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.
## Winning
Shortest code in bytes wins.
  
[Answer]
# [Python 2.7](https://docs.python.org/2) + [xkcd](https://pypi.python.org/pypi/xkcd), 55 bytes
[xkcd](https://pypi.python.org/pypi/xkcd) is a third-party Python package. In Python, there is a [package for everything](https://xkcd.com/353/)!
```
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`
> 
> 
> 
[Answer]
# [Python 2](https://docs.python.org/2) + [Requests](https://docs.python-requests.org/en/master/), ~~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*
```
Obligatory:
```
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']
```
[Answer]
# 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
[Answer]
# [Wolfram Language](http://reference.wolfram.com/language)/Mathematica, ~~118~~ 117 bytes
*saved a byte thanks to numbermanic*
```
If[ImportString[#,"HTML"]===#,#,$Failed]&@Import[StringTemplate["http://xkcd.com/``/info.0.json"]@#,"RawJSON"]@"alt"&
```
Explanation:
Use `StringTemplate`to form the URL from the input. 
`Import[..., "RawJSON"]` imports the JSON object and parses it into an [`Assocation`](http://reference.wolfram.com/language/ref/Association.html). 
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 
```
ImportString[
 "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 
```
If[
 ImportString[$Failed["alt"], "HTML"] === $Failed["alt"], 
 $Failed["alt"],
 $Failed]
```
results in `$Failed`.
[Answer]
## 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...
### Explanation:
* `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.
[Answer]
# [Python](https://docs.python.org/) + [xkcd](https://pypi.python.org/pypi/xkcd), 54 bytes
```
import xkcd
lambda n:xkcd.getComic(*{n}-{859}).altText
```
### Verification
```
>>> 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)
```
[Answer]
# 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`
[Answer]
# PHP, ~~89~~ ~~86~~ 85 bytes
```
<?=($a=$argv[1])==859?_:@json_decode(file("http://xkcd.com/$a/info.0.json")[0])->alt;
```
Returns null for 404 and 859
Save as xkcd.php and run with the comic number...
```
$ php xkcd.php 386
```
[Answer]
# 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');
```
[Answer]
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:
### 404
```
$ printf "$(curl -s https://xkcd.com/404/info.0.json | sed 's/.*alt": "\([^"]\+\).*/\1/')\n"
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
</html>
```
### 859
```
$ 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.
[Answer]
# [Python 2](https://docs.python.org/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
```
[Answer]
# 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...!
[Answer]
# 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);
```
[Answer]
# [APL (Dyalog Unicode)](https://github.com/abrudz/dyalog-apl-extended), ~~110~~ 73 bytes
```
{'('‚àä‚éï‚Üê‚çµ.safe_title:-‚çµ‚ãÑ‚çµ.alt}‚éïJSON‚àä‚éïSH‚àä'curl -L xkcd.com/'‚çû'/info.0.json'
```
-37 bytes from Ad√°m.
## Explanation
```
‚éï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)
```
[Answer]
# 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.
[Answer]
# 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!
[Answer]
# Javascript (ES6), ~~118~~ ~~96~~ 94 bytes
```
f=n=>fetch(`//xkcd.com/${n}/info.0.json`).then(x=>x.json()).then(y=>eval(`alert('${y.alt}')`))
```
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.*
]