Skip to content

Instantly share code, notes, and snippets.

@epelc
Forked from cryptix/vineScrape.go
Last active August 29, 2015 14:28
Show Gist options
  • Select an option

  • Save epelc/adf46d31cc77d081035d to your computer and use it in GitHub Desktop.

Select an option

Save epelc/adf46d31cc77d081035d to your computer and use it in GitHub Desktop.

Revisions

  1. @cryptix cryptix created this gist Aug 27, 2014.
    77 changes: 77 additions & 0 deletions vineScrape.go
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,77 @@
    package main

    import (
    "errors"
    "log"
    "os"

    "github.com/PuerkitoBio/goquery"
    "github.com/robertkrimen/otto"
    )

    func getMP4URL(id string) string {
    doc, err := goquery.NewDocument("https://vine.co/v/" + id)
    check(err)

    // we want the first <script> tag from the html
    firstScript := doc.Find("script").First()

    vm := otto.New()

    // otherwise window.POST_DATA will raise an reference error `ReferenceError: 'window' is not defined`
    _, err = vm.Run("var window = {};")
    check(err)

    // eval the javascript inside the <script> tag
    _, err = vm.Run(firstScript.Text())
    check(err)

    // traverse down the object path: window > POST_DATA > <videoID> > videoDashURL
    wVal, err := vm.Get("window")
    check(err)

    pdata, err := getValueFromObject(wVal, "POST_DATA")
    check(err)

    videoData, err := getValueFromObject(*pdata, id)
    check(err)

    videoDashUrl, err := getValueFromObject(*videoData, "videoDashUrl")
    check(err)

    // finally the video url...
    videoUrl, err := videoDashUrl.ToString()
    check(err)

    return videoUrl
    }

    func main() {
    if len(os.Args) != 2 {
    log.Fatalln("Usage: vineUrl <videoID>")
    }

    log.Println("Video URL:", getMP4URL(os.Args[1]))
    }

    // fatal if there is an error
    func check(err error) {
    if err != nil {
    log.Fatal(err)
    }
    }

    func getValueFromObject(val otto.Value, key string) (*otto.Value, error) {
    if !val.IsObject() {
    return nil, errors.New("passed val is not an Object")
    }

    valObj := val.Object()

    obj, err := valObj.Get(key)
    if err != nil {
    return nil, err
    }

    return &obj, nil
    }