]>
code.delx.au - monosys/blob - scripts/youtube.cgi
4 from lxml
.html
import document_fromstring
13 class VideoUnavailable(Exception):
16 urllib
.URLopener
.version
= "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0.1) Gecko/20100101 Firefox/4.0.1"
19 (38, ".mp4"), # 4096x3072
20 (37, ".mp4"), # 1920x1080
21 (22, ".mp4"), # 1280x720
22 (45, ".webm"), # 1280x720
23 (43, ".webm"), # 640x360
24 (35, ".flv"), # 854x480
25 (34, ".flv"), # 640x360
26 (18, ".mp4"), # 480x360
27 (5, ".flv"), # 400x240
28 (17, ".3gp"), # 176x144
32 def print_form(url
="", msg
=""):
33 script_url
= "http://%s%s" % (os
.environ
["HTTP_HOST"], os
.environ
["REQUEST_URI"])
34 print "Content-Type: application/xhtml+xml\r\n\r\n"
36 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
37 <html xmlns="http://www.w3.org/1999/xhtml">
39 <title>delx.net.au - YouTube Scraper</title>
40 <link rel="stylesheet" type="text/css" href="/style.css"/>
41 <style type="text/css">
51 <h1>delx.net.au - YouTube Scraper</h1>
53 <form action="" method="get">
54 <p>This page will let you easily download YouTube videos to watch offline. It
55 will automatically grab the highest quality version.</p>
56 <div><input type="text" name="url" value="{1}"/></div>
57 <div><input type="submit" value="Download!"/></div>
59 <p>Tip! Use this bookmarklet: <a href="javascript:(function(){window.location='{2}?url='+escape(location);})()">YouTube Download</a>
60 to easily download videos. Right-click the link and add it to bookmarks,
61 then when you're looking at a YouTube page select that bookmark from your
62 browser's bookmarks menu to download the video straight away.</p>
65 """.replace("{0}", msg
).replace("{1}", url
).replace("{2}", script_url
)
68 f
= urllib
.urlopen(url
)
69 doc
= document_fromstring(f
.read())
73 def get_video_url(doc
):
74 unavailable
= doc
.xpath("//div[@id='unavailable-message']/text()")
76 raise VideoUnavailable(unavailable
[0].strip())
77 embed
= doc
.xpath("//embed")[0]
78 flashvars
= embed
.attrib
["flashvars"]
79 flashvars
= cgi
.parse_qs(flashvars
)
81 for pair
in flashvars
["fmt_url_map"][0].split(","):
82 key
, value
= pair
.split("|")
84 fmt_url_map
[key
] = value
85 for fmt
, extension
in fmt_quality
:
87 video_url
= fmt_url_map
[fmt
]
92 return None, None, None
94 title
= doc
.xpath("/html/head/title/text()")[0]
95 title
= re
.sub("\s+", " ", title
.strip())
96 valid_chars
= frozenset("-_.() abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
97 filename
= "".join(c
for c
in title
.encode("ascii", "ignore") if c
in valid_chars
)
100 return video_url
, filename
107 print_form(url
="http://www.youtube.com/watch?v=FOOBAR")
112 video_url
, filename
= get_video_url(doc
)
113 data
= urllib
.urlopen(video_url
)
114 httpinfo
= data
.info()
115 sys
.stdout
.write("Content-Disposition: attachment; filename=\"%s\"\r\n" % filename
)
116 sys
.stdout
.write("Content-Length: %s\r\n" % httpinfo
.getheader("Content-Length"))
117 sys
.stdout
.write("\r\n")
118 shutil
.copyfileobj(data
, sys
.stdout
)
120 except VideoUnavailable
, e
:
123 msg
="<p class='error'>Sorry, there was an error: %s</p>" % cgi
.escape(e
.message
)
128 msg
="<p class='error'>Sorry, there was an error. Check your URL?</p>"
136 print >>sys
.stderr
, "Usage: %s http://youtube.com/watch?v=FOOBAR" % sys
.argv
[0]
139 video_url
, filename
= get_video_url(doc
)
140 data
= urllib
.urlopen(video_url
)
141 outfile
= open(filename
, "w")
142 shutil
.copyfileobj(data
, outfile
)
147 if __name__
== "__main__":
148 if os
.environ
.has_key("SCRIPT_NAME"):