Ara 062016
 
6.169 views

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:

Golang Notları 002

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.

Golang Notları 002

İ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: