Do request support added. Updated docs.
This commit is contained in:
		@@ -1,5 +1,8 @@
 | 
				
			|||||||
# Geziyor
 | 
					# Geziyor
 | 
				
			||||||
Scraper and crawler framework for Golang. Geziyor uses go *channels* over *callbacks*   
 | 
					Geziyor is a fast web crawling and web scraping framework, used to crawl websites and extract structured data from their pages. It can be used for a wide range of purposes, from data mining to monitoring and automated testing.   
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[](https://godoc.org/github.com/geziyor/geziyor)
 | 
				
			||||||
 | 
					[](http://goreportcard.com/report/geziyor/geziyor)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Features
 | 
					## Features
 | 
				
			||||||
- 1.000+ Requests/Sec
 | 
					- 1.000+ Requests/Sec
 | 
				
			||||||
@@ -36,3 +39,5 @@ geziyor.Start()
 | 
				
			|||||||
## Installation
 | 
					## Installation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    go get github.com/geziyor/geziyor
 | 
					    go get github.com/geziyor/geziyor
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					We highly recommend you to use go modules. As this project is in **development stage** right now.
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										44
									
								
								geziyor.go
									
									
									
									
									
								
							
							
						
						
									
										44
									
								
								geziyor.go
									
									
									
									
									
								
							@@ -14,6 +14,7 @@ import (
 | 
				
			|||||||
	"time"
 | 
						"time"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Geziyor is our main scraper type
 | 
				
			||||||
type Geziyor struct {
 | 
					type Geziyor struct {
 | 
				
			||||||
	client *http.Client
 | 
						client *http.Client
 | 
				
			||||||
	wg     sync.WaitGroup
 | 
						wg     sync.WaitGroup
 | 
				
			||||||
@@ -22,6 +23,7 @@ type Geziyor struct {
 | 
				
			|||||||
	visitedURLS []string
 | 
						visitedURLS []string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Opt is custom options type for Geziyor
 | 
				
			||||||
type Opt struct {
 | 
					type Opt struct {
 | 
				
			||||||
	AllowedDomains []string
 | 
						AllowedDomains []string
 | 
				
			||||||
	StartURLs      []string
 | 
						StartURLs      []string
 | 
				
			||||||
@@ -33,6 +35,8 @@ func init() {
 | 
				
			|||||||
	log.SetOutput(os.Stdout)
 | 
						log.SetOutput(os.Stdout)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NewGeziyor creates new Geziyor with default values.
 | 
				
			||||||
 | 
					// If options provided, options
 | 
				
			||||||
func NewGeziyor(opt Opt) *Geziyor {
 | 
					func NewGeziyor(opt Opt) *Geziyor {
 | 
				
			||||||
	geziyor := &Geziyor{
 | 
						geziyor := &Geziyor{
 | 
				
			||||||
		client: &http.Client{
 | 
							client: &http.Client{
 | 
				
			||||||
@@ -48,6 +52,7 @@ func NewGeziyor(opt Opt) *Geziyor {
 | 
				
			|||||||
	return geziyor
 | 
						return geziyor
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Start starts scraping
 | 
				
			||||||
func (g *Geziyor) Start() {
 | 
					func (g *Geziyor) Start() {
 | 
				
			||||||
	for _, startURL := range g.opt.StartURLs {
 | 
						for _, startURL := range g.opt.StartURLs {
 | 
				
			||||||
		go g.Get(startURL)
 | 
							go g.Get(startURL)
 | 
				
			||||||
@@ -57,19 +62,30 @@ func (g *Geziyor) Start() {
 | 
				
			|||||||
	g.wg.Wait()
 | 
						g.wg.Wait()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (g *Geziyor) Get(rawURL string) {
 | 
					// Get issues a GET to the specified URL.
 | 
				
			||||||
 | 
					func (g *Geziyor) Get(url string) {
 | 
				
			||||||
 | 
						req, err := http.NewRequest("GET", url, nil)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Printf("Request creating error %v\n", err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						g.Do(req)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Do sends an HTTP request
 | 
				
			||||||
 | 
					func (g *Geziyor) Do(req *http.Request) {
 | 
				
			||||||
	g.wg.Add(1)
 | 
						g.wg.Add(1)
 | 
				
			||||||
	defer g.wg.Done()
 | 
						defer g.wg.Done()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if !checkURL(rawURL, g) {
 | 
						if !checkURL(req.URL, g) {
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Log
 | 
						// Log
 | 
				
			||||||
	log.Println("Fetching: ", rawURL)
 | 
						log.Println("Fetching: ", req.URL.String())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Get request
 | 
						// Do request
 | 
				
			||||||
	resp, err := g.client.Get(rawURL)
 | 
						resp, err := g.client.Do(req)
 | 
				
			||||||
	if resp != nil {
 | 
						if resp != nil {
 | 
				
			||||||
		defer resp.Body.Close()
 | 
							defer resp.Body.Close()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -104,23 +120,17 @@ func (g *Geziyor) Get(rawURL string) {
 | 
				
			|||||||
	time.Sleep(time.Millisecond)
 | 
						time.Sleep(time.Millisecond)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func checkURL(rawURL string, g *Geziyor) bool {
 | 
					func checkURL(parsedURL *url.URL, g *Geziyor) bool {
 | 
				
			||||||
 | 
						rawURL := parsedURL.String()
 | 
				
			||||||
	// Parse URL
 | 
					 | 
				
			||||||
	parsedURL, err := url.Parse(rawURL)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		fmt.Fprintf(os.Stderr, "url parsing error: %v\n", err)
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Check for allowed domains
 | 
						// Check for allowed domains
 | 
				
			||||||
	if len(g.opt.AllowedDomains) != 0 && !Contains(g.opt.AllowedDomains, parsedURL.Host) {
 | 
						if len(g.opt.AllowedDomains) != 0 && !contains(g.opt.AllowedDomains, parsedURL.Host) {
 | 
				
			||||||
		log.Printf("Domain not allowed: %s\n", parsedURL.Host)
 | 
							log.Printf("Domain not allowed: %s\n", parsedURL.Host)
 | 
				
			||||||
		return false
 | 
							return false
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Check for duplicate requests
 | 
						// Check for duplicate requests
 | 
				
			||||||
	if Contains(g.visitedURLS, rawURL) {
 | 
						if contains(g.visitedURLS, rawURL) {
 | 
				
			||||||
		log.Printf("URL already visited %s\n", rawURL)
 | 
							log.Printf("URL already visited %s\n", rawURL)
 | 
				
			||||||
		return false
 | 
							return false
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -129,8 +139,8 @@ func checkURL(rawURL string, g *Geziyor) bool {
 | 
				
			|||||||
	return true
 | 
						return true
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Contains checks whether []string contains string
 | 
					// contains checks whether []string contains string
 | 
				
			||||||
func Contains(s []string, e string) bool {
 | 
					func contains(s []string, e string) bool {
 | 
				
			||||||
	for _, a := range s {
 | 
						for _, a := range s {
 | 
				
			||||||
		if a == e {
 | 
							if a == e {
 | 
				
			||||||
			return true
 | 
								return true
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,16 @@ import (
 | 
				
			|||||||
	"testing"
 | 
						"testing"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestGeziyor_StartURLs_Simple(t *testing.T) {
 | 
					func TestGeziyor_Simple(t *testing.T) {
 | 
				
			||||||
 | 
						NewGeziyor(Opt{
 | 
				
			||||||
 | 
							StartURLs: []string{"http://api.ipify.org"},
 | 
				
			||||||
 | 
							ParseFunc: func(r *Response) {
 | 
				
			||||||
 | 
								fmt.Println(string(r.Body))
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}).Start()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestGeziyor_IP(t *testing.T) {
 | 
				
			||||||
	geziyor := NewGeziyor(Opt{
 | 
						geziyor := NewGeziyor(Opt{
 | 
				
			||||||
		StartURLs: []string{"http://api.ipify.org"},
 | 
							StartURLs: []string{"http://api.ipify.org"},
 | 
				
			||||||
		Cache:     httpcache.NewMemoryCache(),
 | 
							Cache:     httpcache.NewMemoryCache(),
 | 
				
			||||||
@@ -19,7 +28,7 @@ func TestGeziyor_StartURLs_Simple(t *testing.T) {
 | 
				
			|||||||
	geziyor.Start()
 | 
						geziyor.Start()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestGeziyor_StartURLs_HTML(t *testing.T) {
 | 
					func TestGeziyor_HTML(t *testing.T) {
 | 
				
			||||||
	geziyor := NewGeziyor(Opt{
 | 
						geziyor := NewGeziyor(Opt{
 | 
				
			||||||
		StartURLs: []string{"http://quotes.toscrape.com/"},
 | 
							StartURLs: []string{"http://quotes.toscrape.com/"},
 | 
				
			||||||
		ParseFunc: func(r *Response) {
 | 
							ParseFunc: func(r *Response) {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user