Golang Notları 002
GOPATH
“Go” diliyle yeni uğraşmaya başlayanların çok sık karşılaştıkları bir hata – uyarı mesajı vardır: “GOPATH tanımı bulunamadı.”
“GOPATH”, go’nun sürekli kullandığı adreslerden biridir. Çünkü paket yönetim ve kullanım işlemleri bu klasör aracılığıyla yapılıyor.
Ubuntu’da bu klasör genellikle $HOME/go veya $HOME/golang olarak açılır. Ben, ikincisini tercih ettim.
Ubuntu’da bu adresi sisteme aşağıdaki gibi tanıtıyorsunuz:
export GOPATH=$HOME/golang
Bilgisayarınızı yeniden açtığınızda aynı komutu vermek zorunda kalmamak için bu komutu $HOME/.bashrc dosyasının içine ekliyorsunuz.
Kontrol için “go env” komutunu kullanabilirsiniz:
Paket kurma golang için çok kolay bir işlem:
go get golang.org/x/net/html
go get github.com/yhat/scrape
Basit bir Scraper (Kazıyıcı) programı
“html” paketinin kullanıldığı bir de örnek vereyim. Örnekle ilgili açıklamaları https://schier.co/blog/2015/04/26/a-simple-web-scraper-in-go.html adresinde bulabilirsiniz:
//https://schier.co/blog/2015/04/26/a-simple-web-scraper-in-go.html package main import ( "fmt" "golang.org/x/net/html" "net/http" "os" "strings" ) // Helper function to pull the href attribute from a Token func getHref(t html.Token) (ok bool, href string) { // Iterate over all of the Token's attributes until we find an "href" for _, a := range t.Attr { if a.Key == "href" { href = a.Val ok = true } } // "bare" return will return the variables (ok, href) as defined in // the function definition return } // Extract all http** links from a given webpage func crawl(url string, ch chan string, chFinished chan bool) { resp, err := http.Get(url) defer func() { // Notify that we're done after this function chFinished <- true }() if err != nil { fmt.Println("ERROR: Failed to crawl \"" + url + "\"") return } b := resp.Body defer b.close() // close Body when the function returns z := html.NewTokenizer(b) for { tt := z.Next() switch { case tt == html.ErrorToken: // End of the document, we're done return case tt == html.StartTagToken: t := z.Token() // Check if the token is an <a> tag isAnchor := t.Data == "a" if !isAnchor { continue } // Extract the href value, if there is one ok, url := getHref(t) if !ok { continue } // Make sure the url begines in http** hasProto := strings.Index(url, "http") == 0 if hasProto { ch <- url } } } } func main() { foundUrls := make(map[string]bool) seedUrls := os.Args[1:] // Channels chUrls := make(chan string) chFinished := make(chan bool) // Kick off the crawl process (concurrently) for _, url := range seedUrls { go crawl(url, chUrls, chFinished) } // Subscribe to both channels for c := 0; c < len(seedUrls); { select { case url := <-chUrls: foundUrls[url] = true case <-chFinished: c++ } } // We're done! Print the results... fmt.Println("\nFound", len(foundUrls), "unique urls:\n") for url, _ := range foundUrls { fmt.Println(" - " + url) } close(chUrls) }
Kod kolay anlaşılır olduğu için açıklamasını vermeyeceğim. Komut satırına eklediğiniz adresteki tüm tekil linkleri çıktı olarak alıyorsunuz.
İnternet üzerinde çok sayıda “webscraper” örneği var. http://depado.markdownblog.com/2015-08-07-small-example-how-to-use-the-scrape-library-in-go adresindeki örnek kod, Paris’teki bir galeride bulunan eserleri listeliyor.
Ahmet Aksoy
Referanslar: