然后看了很感动,想下载下来收藏。所以点微博视频
进去看了一下,就到了http://video.weibo.com/show?fid=1034:0e906d53094c5d231bf09028af8ba9b1
这个链接,打开网页源代码看了一下:
<!doctype html><html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><meta id="viewport" name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,minimal-ui"><link class="style" rel="stylesheet" href="http://img.t.sinajs.cn/t4/appstyle/photo/css/pages/miaopai.css?v2"><title>视频</title></head><body><div style="margin:0 auto;text-align:center"><embed type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" wmode="transparent" quality="high" pluginspage="http://get.adobe.com/cn/flashplayer/" height="480" width="480" src="http://js.t.sinajs.cn/t5/album/static/swf/video/player.swf?_v122326477820508684050" flashvars="list=http%3A%2F%2Fus.sinaimg.cn%2F003BqToKjx06PK8lOidW0104010000220k01.m3u8%3FKID%3Dunistore%2Cvideo%26Expires%3D1423376348%26ssig%3Dvuz2N%252FMVtm" /></div></body></html>
发现播放的是flashvars="list=http%3A%2F%2Fus.sinaimg.cn%2F003BqToKjx06PK8lOidW0104010000220k01.m3u8%3FKID%3Dunistore%2Cvideo%26Expires%3D1423376348%26ssig%3Dvuz2N%252FMVtm"
这样一个m3u8文件,不说了,先把m3u8
列表下载下来看看,不看不知道,一看吓一跳,原来是个完整的mp4文件。注意上面的链接需要urldecode
一下,得到:http://us.sinaimg.cn/003BqToKjx06PK8lOidW0104010000220k01.m3u8?KID=unistore,video&Expires=1423376348&ssig=vuz2N%2FMVtm
#EXTM3U#EXT-X-VERSION:3#EXT-X-TARGETDURATION:207#EXTINF:206.640000,000KDKzUjx06PK8lMcpx01040100JzGp0k01.mp4#EXT-X-ENDLIST
那就好办了,直接下载http://us.sinaimg.cn/000KDKzUjx06PK8lMcpx01040100JzGp0k01.mp4
就好了。
为了方便下载同类型的视频,小写了一个代码。https://gist.github.com/jemygraw/412a4fd557d875fd3037
package main //Usage: vsina http://video.weibo.com/show?fid=1034:0e906d53094c5d231bf09028af8ba9b1import ( "bufio" "fmt" "github.com/astaxie/beego/httplib" "io" "io/ioutil" "net/url" "os" "regexp" "strings" "time") func help() { fmt.Println("Usage: vsina <VideoUrl>")} func fetch(videoUrl string) { req := httplib.Get(videoUrl) resp, err := req.Response() if err != nil { fmt.Println("fetch video url error,", err) return } defer resp.Body.Close() respData, err := ioutil.ReadAll(resp.Body) if err != nil { fmt.Println("read video url content error,", err) return } pattern := `flashvars="list=.*"` regx := regexp.MustCompile(pattern) flashVars := regx.FindString(string(respData)) if flashVars != "" { size := len(flashVars) m3u8Url, err := url.QueryUnescape(flashVars[16 : size-1]) if err != nil { fmt.Println(err) } else { fetchMovie(m3u8Url) } } else { fmt.Println("m3u8 playlist not found") }} func fetchMovie(m3u8Url string) { req := httplib.Get(m3u8Url) resp, respErr := req.Response() if respErr != nil { fmt.Println("fetch m3u8 playlist error,", respErr) return } defer resp.Body.Close() respData, readErr := ioutil.ReadAll(resp.Body) if readErr != nil { fmt.Println("read m3u8 playlist content error,", readErr) return } videoFolder := fmt.Sprintf("video_%d", time.Now().Unix()) mkdErr := os.Mkdir(videoFolder, 0775) if mkdErr != nil { fmt.Println("mkdir for m3u8 playlist failed,", mkdErr) return } m3u8Uri, _ := url.Parse(m3u8Url) sReader := strings.NewReader(string(respData)) bReader := bufio.NewScanner(sReader) bReader.Split(bufio.ScanLines) for bReader.Scan() { line := bReader.Text() if !strings.HasPrefix(line, "#") { tsFileName := line tsLocalFileName := fmt.Sprintf("%s/%s", videoFolder, line) tsFileUrl := fmt.Sprintf("%s://%s/%s", m3u8Uri.Scheme, m3u8Uri.Host, tsFileName) downloadTS(tsFileUrl, tsLocalFileName) } } fmt.Println() fmt.Println("Result:", videoFolder)} func downloadTS(tsFileUrl string, tsLocalFileName string) { fmt.Println("downloading", tsFileUrl) req := httplib.Get(tsFileUrl) resp, respErr := req.Response() if respErr != nil { fmt.Println("download ts ", tsFileUrl, "failed,", respErr) return } defer resp.Body.Close() tsFp, openErr := os.OpenFile(tsLocalFileName, os.O_CREATE|os.O_WRONLY, 0775) if openErr != nil { fmt.Println("open local file", tsLocalFileName, "failed,", openErr) return } defer tsFp.Close() _, copyErr := io.Copy(tsFp, resp.Body) if copyErr != nil { fmt.Println("download ts", tsFileUrl, " failed,", copyErr) }} func main() { argv := os.Args argc := len(argv) if argc != 2 { help() return } videoUrl := argv[1] fetch(videoUrl)}