然后看了很感动,想下载下来收藏。所以点微博视频
进去看了一下,就到了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)}