Colly Framework ile Go dilinde Web Scraping nasıl yapılır?
Published: 2021-11-21 16:32:22

Öncelikle go resmi dökümantasyonunda olduğu gibi bir proje oluşturuyoruz.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2ryap216p9z7ufbeb8ct.png)
 
favori kod editörümüzü açıyoruz ve main.go dosyamızı oluşturuyoruz.İster VS Code terminalinde istersek işletim sisteminin terminalinde projenin olduğu dizinde 
go get -u github.com/gocolly/colly/...
komutu ile colly framework yüklemesini başlatıyoruz.Kurulum esnasında sorun yaşarsanız,
http://go-colly.org/ ve https://github.com/gocolly/colly adreslerini inceleyebilirsiniz.

Bizim yapacağımız uygulamada tek bir amacımız var bu da TFF sitesinden Süper Lig puan durumunu çekmek.Bunu yapmak için temel düzeyde olsa html taglarını tanıyor olmanızı bekliyoruz.Eğer daha önce css kullanırken selector yazdıysanız bu iş size çocuk oyuncağı gelecektir.
Öyleyse kodlarımızı yazmaya başlayalım.

c := colly.NewCollector(
		colly.AllowedDomains(),
	)
komutu ile yeni bir Collector oluşturalım.Bu uygulamada bize bir adet collector yettiği için ekstra ekleme yapmayacağım fakat size kendi projenizde lazım olursa, herhangi bir struct tipinden örnek oluşturur gibi c2,c3,c4 şeklinde collector oluşturabilirsiniz.

Colly Framework kullanırken mutlaka Callback'ler ile karşılaşacaksınız.Android lifecycle konusuna benzettiğim bu yapıyı en iyi anlatan kısım ise yine kendi resmi dökümantasyonu

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gz892reryesuwsuov732.png)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yr51rqrh0no43wugtops.png)
  
Callbackler konusuna şimdilik, yazıyı kısa ve anlaşılır tutmak için detaylı şekilde girmiyorum.Hevesimizi kaçırmadan hemen Tff resmi sitesinde puan durumu ve fikstür bilgisi yer alan sayfaya gidelim(Bu yazı yazılırken link: https://www.tff.org/default.aspx?pageID=198). Sayfayı açtıktan sonra geliştirici seçeneklerini açalım.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g0v56vkutyoolmzugw34.png)
En sol üstte bulunan işarete tıklayıp sayfa üzerinde puan durumunun olduğu kısma tıklarsanız, ihtiyacımız olan alanın bir table yapısı içinde olduğu kolaylıkla anlaşılıyor.
Selector yazıp verileri alma işlemini table ın hemen üzerinde bulunan div i kullanıp yapacağız.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t8kvan0m28d4pi5ej8fv.png)
Burada div in id sini hemen kopyalayıp, örneğini oluşturduğumuz collector'ü kullanmaya başlıyoruz.
c.OnHTML Callback ' içine aşağıdaki kodları yazıyoruz.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3rzt6fzuem1woadvwebe.png)
 
Aşağıdaki kısma dikkat ediniz.
c.OnHTML("#ctl00_MPane_m_198_10561_ctnr_m_198_10561_Panel1>table>tbody>tr".... Normalde burayı tek bir td olsaydı tr>td>a şeklinde uzatabilirdim fakat, her tr nin içinde birçok td olduğu için bütün td leri teker teker gezmemiz gerekiyor.Bunun için selektörü "...>tr" de bitiririp, tr den sonra gelen td ler için ayrı bir forEach dönerek table da bulunan istatistikleri de yazmayı amaçladık.

Son olarak 
c.Visit("https://www.tff.org/default.aspx?pageID=198")
kodunu ekleyerek uygulamamızın istediğimiz linki ziyaret edip verileri çekmesini bekliyoruz.
Çıktı :
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iub4xz8eecmhkuo0qn9i.png)

Eğer isterseniz console a yazdırdığımız bu verileri .csv dosyasına da kaydedebiliriz. Bu kodları tam bütün halinde paylaşıyorum.
Esen kalın... 
package main

import (
	"encoding/csv"
	"fmt"
	"github.com/gocolly/colly"
	"log"
	"os"
)

func main() {

	fName:="data.csv"
	file,err:=os.Create(fName)
	if err!=nil {
		log.Fatalf("Failed to c reate file: %q",err)
		return
	}

	defer file.Close()
	writer:=csv.NewWriter(file)
	defer writer.Flush()


	// Instantiate default collector
	c := colly.NewCollector(
		
		colly.AllowedDomains(),
	)

	// On every a element which has href attribute call callback
	c.OnHTML("#ctl00_MPane_m_198_10561_ctnr_m_198_10561_Panel1>table>tbody>tr", func(e *colly.HTMLElement) {
		var liste_stats []string
		var takim string
		var statistics string
		e.ForEach("td", func(_ int, elem *colly.HTMLElement) {
			takim = elem.ChildText("a")
			statistics= elem.ChildText("span")
			liste_stats=append(liste_stats,takim )
			liste_stats=append(liste_stats, statistics)
		})
			fmt.Println(liste_stats)
			writer.Write(liste_stats)
			c.Visit(e.Request.AbsoluteURL(takim))
	})

	
	// Before making a request print "Visiting ..."
	c.OnRequest(func(r *colly.Request) {
			fmt.Println("Visiting", r.URL.String())
	})

	
	c.Visit("https://www.tff.org/default.aspx?pageID=198")
}