http package renamed to client to reduce cunfusion

This commit is contained in:
Musab Gültekin 2019-06-29 14:18:31 +03:00
parent 1e109c555d
commit bd6466a5f2
8 changed files with 73 additions and 73 deletions

View File

@ -27,7 +27,7 @@ Simple usage
```go
geziyor.NewGeziyor(&geziyor.Options{
StartURLs: []string{"http://api.ipify.org"},
ParseFunc: func(g *geziyor.Geziyor, r *http.Response) {
ParseFunc: func(g *geziyor.Geziyor, r *client.Response) {
fmt.Println(string(r.Body))
},
}).Start()
@ -44,7 +44,7 @@ func main() {
}).Start()
}
func quotesParse(g *geziyor.Geziyor, r *http.Response) {
func quotesParse(g *geziyor.Geziyor, r *client.Response) {
r.HTMLDoc.Find("div.quote").Each(func(i int, s *goquery.Selection) {
g.Exports <- map[string]interface{}{
"text": s.Find("span.text").Text(),
@ -78,7 +78,7 @@ After reading response, ```ParseFunc func(g *Geziyor, r *Response)``` called.
```go
geziyor.NewGeziyor(&geziyor.Options{
StartURLs: []string{"http://api.ipify.org"},
ParseFunc: func(g *geziyor.Geziyor, r *http.Response) {
ParseFunc: func(g *geziyor.Geziyor, r *client.Response) {
fmt.Println(string(r.Body))
},
}).Start()
@ -95,7 +95,7 @@ geziyor.NewGeziyor(&geziyor.Options{
g.GetRendered("https://httpbin.org/anything", g.Opt.ParseFunc)
g.Head("https://httpbin.org/anything", g.Opt.ParseFunc)
},
ParseFunc: func(g *geziyor.Geziyor, r *http.Response) {
ParseFunc: func(g *geziyor.Geziyor, r *client.Response) {
fmt.Println(string(r.Body))
},
}).Start()
@ -130,7 +130,7 @@ If response isn't HTML, ```response.HTMLDoc``` would be ```nil```.
```go
geziyor.NewGeziyor(&geziyor.Options{
StartURLs: []string{"http://quotes.toscrape.com/"},
ParseFunc: func(g *geziyor.Geziyor, r *http.Response) {
ParseFunc: func(g *geziyor.Geziyor, r *client.Response) {
r.HTMLDoc.Find("div.quote").Each(func(_ int, s *goquery.Selection) {
log.Println(s.Find("span.text").Text(), s.Find("small.author").Text())
})
@ -146,7 +146,7 @@ You can export data automatically using exporters. Just send data to ```Geziyor.
```go
geziyor.NewGeziyor(&geziyor.Options{
StartURLs: []string{"http://quotes.toscrape.com/"},
ParseFunc: func(g *geziyor.Geziyor, r *http.Response) {
ParseFunc: func(g *geziyor.Geziyor, r *client.Response) {
r.HTMLDoc.Find("div.quote").Each(func(_ int, s *goquery.Selection) {
g.Exports <- map[string]interface{}{
"text": s.Find("span.text").Text(),

View File

@ -1,4 +1,4 @@
package http
package client
import (
"errors"

View File

@ -1,4 +1,4 @@
package http
package client
import (
"io"

View File

@ -1,4 +1,4 @@
package http
package client
import (
"github.com/PuerkitoBio/goquery"

View File

@ -7,7 +7,7 @@ import (
"github.com/chromedp/cdproto/network"
"github.com/chromedp/chromedp"
"github.com/fpfeng/httpcache"
"github.com/geziyor/geziyor/http"
"github.com/geziyor/geziyor/client"
"github.com/geziyor/geziyor/metrics"
"github.com/pkg/errors"
"github.com/prometheus/client_golang/prometheus/promhttp"
@ -15,7 +15,7 @@ import (
"io"
"io/ioutil"
"log"
stdhttp "net/http"
"net/http"
"net/http/cookiejar"
"net/url"
"sync"
@ -36,7 +36,7 @@ type Exporter interface {
// Geziyor is our main scraper type
type Geziyor struct {
Opt *Options
Client *http.Client
Client *client.Client
Exports chan interface{}
metrics *metrics.Metrics
@ -55,7 +55,7 @@ type Geziyor struct {
// If options provided, options
func NewGeziyor(opt *Options) *Geziyor {
geziyor := &Geziyor{
Client: http.NewClient(),
Client: client.NewClient(),
Opt: opt,
Exports: make(chan interface{}),
requestMiddlewares: []RequestMiddleware{
@ -114,10 +114,10 @@ func (g *Geziyor) Start() {
// Metrics
if g.Opt.MetricsType == metrics.Prometheus {
metricsServer := &stdhttp.Server{Addr: ":2112"}
metricsServer := &http.Server{Addr: ":2112"}
defer metricsServer.Close()
go func() {
stdhttp.Handle("/metrics", promhttp.Handler())
http.Handle("/metrics", promhttp.Handler())
metricsServer.ListenAndServe()
}()
}
@ -149,39 +149,39 @@ func (g *Geziyor) Start() {
}
// Get issues a GET to the specified URL.
func (g *Geziyor) Get(url string, callback func(g *Geziyor, r *http.Response)) {
req, err := stdhttp.NewRequest("GET", url, nil)
func (g *Geziyor) Get(url string, callback func(g *Geziyor, r *client.Response)) {
req, err := http.NewRequest("GET", url, nil)
if err != nil {
log.Printf("Request creating error %v\n", err)
return
}
g.Do(&http.Request{Request: req}, callback)
g.Do(&client.Request{Request: req}, callback)
}
// GetRendered issues GET request using headless browser
// Opens up a new Chrome instance, makes request, waits for 1 second to render HTML DOM and closed.
// Rendered requests only supported for GET requests.
func (g *Geziyor) GetRendered(url string, callback func(g *Geziyor, r *http.Response)) {
req, err := stdhttp.NewRequest("GET", url, nil)
func (g *Geziyor) GetRendered(url string, callback func(g *Geziyor, r *client.Response)) {
req, err := http.NewRequest("GET", url, nil)
if err != nil {
log.Printf("Request creating error %v\n", err)
return
}
g.Do(&http.Request{Request: req, Rendered: true}, callback)
g.Do(&client.Request{Request: req, Rendered: true}, callback)
}
// Head issues a HEAD to the specified URL
func (g *Geziyor) Head(url string, callback func(g *Geziyor, r *http.Response)) {
req, err := stdhttp.NewRequest("HEAD", url, nil)
func (g *Geziyor) Head(url string, callback func(g *Geziyor, r *client.Response)) {
req, err := http.NewRequest("HEAD", url, nil)
if err != nil {
log.Printf("Request creating error %v\n", err)
return
}
g.Do(&http.Request{Request: req}, callback)
g.Do(&client.Request{Request: req}, callback)
}
// Do sends an HTTP request
func (g *Geziyor) Do(req *http.Request, callback func(g *Geziyor, r *http.Response)) {
func (g *Geziyor) Do(req *client.Request, callback func(g *Geziyor, r *client.Response)) {
if req.Synchronized {
g.do(req, callback)
} else {
@ -191,7 +191,7 @@ func (g *Geziyor) Do(req *http.Request, callback func(g *Geziyor, r *http.Respon
}
// Do sends an HTTP request
func (g *Geziyor) do(req *http.Request, callback func(g *Geziyor, r *http.Response)) {
func (g *Geziyor) do(req *client.Request, callback func(g *Geziyor, r *client.Response)) {
g.acquireSem(req)
defer g.releaseSem(req)
if !req.Synchronized {
@ -207,7 +207,7 @@ func (g *Geziyor) do(req *http.Request, callback func(g *Geziyor, r *http.Respon
}
// Do request normal or Chrome and read response
var response *http.Response
var response *client.Response
var err error
if !req.Rendered {
response, err = g.doRequestClient(req)
@ -233,7 +233,7 @@ func (g *Geziyor) do(req *http.Request, callback func(g *Geziyor, r *http.Respon
}
}
func (g *Geziyor) doRequestClient(req *http.Request) (*http.Response, error) {
func (g *Geziyor) doRequestClient(req *client.Request) (*client.Response, error) {
// Do request
resp, err := g.Client.Do(req.Request)
@ -260,7 +260,7 @@ func (g *Geziyor) doRequestClient(req *http.Request) (*http.Response, error) {
return nil, errors.Wrap(err, "Reading body error")
}
response := http.Response{
response := client.Response{
Response: resp,
Body: body,
Meta: req.Meta,
@ -270,7 +270,7 @@ func (g *Geziyor) doRequestClient(req *http.Request) (*http.Response, error) {
return &response, nil
}
func (g *Geziyor) doRequestChrome(req *http.Request) (*http.Response, error) {
func (g *Geziyor) doRequestChrome(req *client.Request) (*client.Response, error) {
var body string
var reqID network.RequestID
var res *network.Response
@ -280,7 +280,7 @@ func (g *Geziyor) doRequestChrome(req *http.Request) (*http.Response, error) {
if err := chromedp.Run(ctx,
network.Enable(),
network.SetExtraHTTPHeaders(network.Headers(http.ConvertHeaderToMap(req.Header))),
network.SetExtraHTTPHeaders(network.Headers(client.ConvertHeaderToMap(req.Header))),
chromedp.ActionFunc(func(ctx context.Context) error {
chromedp.ListenTarget(ctx, func(ev interface{}) {
switch ev.(type) {
@ -317,11 +317,11 @@ func (g *Geziyor) doRequestChrome(req *http.Request) (*http.Response, error) {
// Set new URL in case of redirection
req.URL, _ = url.Parse(res.URL)
response := http.Response{
Response: &stdhttp.Response{
response := client.Response{
Response: &http.Response{
Request: req.Request,
StatusCode: int(res.Status),
Header: http.ConvertMapToHeader(res.Headers),
Header: client.ConvertMapToHeader(res.Headers),
},
Body: []byte(body),
Meta: req.Meta,
@ -331,7 +331,7 @@ func (g *Geziyor) doRequestChrome(req *http.Request) (*http.Response, error) {
return &response, nil
}
func (g *Geziyor) acquireSem(req *http.Request) {
func (g *Geziyor) acquireSem(req *client.Request) {
if g.Opt.ConcurrentRequests != 0 {
g.semGlobal <- struct{}{}
}
@ -349,7 +349,7 @@ func (g *Geziyor) acquireSem(req *http.Request) {
}
}
func (g *Geziyor) releaseSem(req *http.Request) {
func (g *Geziyor) releaseSem(req *client.Request) {
if g.Opt.ConcurrentRequests != 0 {
<-g.semGlobal
}

View File

@ -6,11 +6,11 @@ import (
"github.com/fortytw2/leaktest"
"github.com/fpfeng/httpcache"
"github.com/geziyor/geziyor"
"github.com/geziyor/geziyor/client"
"github.com/geziyor/geziyor/exporter"
"github.com/geziyor/geziyor/extractor"
"github.com/geziyor/geziyor/http"
"github.com/geziyor/geziyor/metrics"
httpstd "net/http"
"net/http"
"net/http/httptest"
"testing"
"unicode/utf8"
@ -20,7 +20,7 @@ func TestSimple(t *testing.T) {
defer leaktest.Check(t)()
geziyor.NewGeziyor(&geziyor.Options{
StartURLs: []string{"http://api.ipify.org"},
ParseFunc: func(g *geziyor.Geziyor, r *http.Response) {
ParseFunc: func(g *geziyor.Geziyor, r *client.Response) {
fmt.Println(string(r.Body))
},
}).Start()
@ -31,7 +31,7 @@ func TestSimpleCache(t *testing.T) {
geziyor.NewGeziyor(&geziyor.Options{
StartURLs: []string{"http://api.ipify.org"},
Cache: httpcache.NewMemoryCache(),
ParseFunc: func(g *geziyor.Geziyor, r *http.Response) {
ParseFunc: func(g *geziyor.Geziyor, r *client.Response) {
fmt.Println(string(r.Body))
g.Exports <- string(r.Body)
g.Get("http://api.ipify.org", nil)
@ -48,7 +48,7 @@ func TestQuotes(t *testing.T) {
}).Start()
}
func quotesParse(g *geziyor.Geziyor, r *http.Response) {
func quotesParse(g *geziyor.Geziyor, r *client.Response) {
r.HTMLDoc.Find("div.quote").Each(func(i int, s *goquery.Selection) {
// Export Data
g.Exports <- map[string]interface{}{
@ -73,7 +73,7 @@ func TestAllLinks(t *testing.T) {
geziyor.NewGeziyor(&geziyor.Options{
AllowedDomains: []string{"books.toscrape.com"},
StartURLs: []string{"http://books.toscrape.com/"},
ParseFunc: func(g *geziyor.Geziyor, r *http.Response) {
ParseFunc: func(g *geziyor.Geziyor, r *client.Response) {
g.Exports <- []string{r.Request.URL.String()}
r.HTMLDoc.Find("a").Each(func(i int, s *goquery.Selection) {
if href, ok := s.Attr("href"); ok {
@ -91,7 +91,7 @@ func TestStartRequestsFunc(t *testing.T) {
StartRequestsFunc: func(g *geziyor.Geziyor) {
g.Get("http://quotes.toscrape.com/", g.Opt.ParseFunc)
},
ParseFunc: func(g *geziyor.Geziyor, r *http.Response) {
ParseFunc: func(g *geziyor.Geziyor, r *client.Response) {
r.HTMLDoc.Find("a").Each(func(_ int, s *goquery.Selection) {
g.Exports <- s.AttrOr("href", "")
})
@ -105,7 +105,7 @@ func TestGetRendered(t *testing.T) {
StartRequestsFunc: func(g *geziyor.Geziyor) {
g.GetRendered("https://httpbin.org/anything", g.Opt.ParseFunc)
},
ParseFunc: func(g *geziyor.Geziyor, r *http.Response) {
ParseFunc: func(g *geziyor.Geziyor, r *client.Response) {
fmt.Println(string(r.Body))
fmt.Println(r.Header)
},
@ -118,7 +118,7 @@ func TestHEADRequest(t *testing.T) {
StartRequestsFunc: func(g *geziyor.Geziyor) {
g.Head("https://httpbin.org/anything", g.Opt.ParseFunc)
},
ParseFunc: func(g *geziyor.Geziyor, r *http.Response) {
ParseFunc: func(g *geziyor.Geziyor, r *client.Response) {
fmt.Println(string(r.Body))
},
}).Start()
@ -127,7 +127,7 @@ func TestHEADRequest(t *testing.T) {
func TestCookies(t *testing.T) {
geziyor.NewGeziyor(&geziyor.Options{
StartURLs: []string{"http://quotes.toscrape.com/login"},
ParseFunc: func(g *geziyor.Geziyor, r *http.Response) {
ParseFunc: func(g *geziyor.Geziyor, r *client.Response) {
if len(g.Client.Cookies(r.Request.URL.String())) == 0 {
t.Fatal("Cookies is Empty")
}
@ -136,7 +136,7 @@ func TestCookies(t *testing.T) {
geziyor.NewGeziyor(&geziyor.Options{
StartURLs: []string{"http://quotes.toscrape.com/login"},
ParseFunc: func(g *geziyor.Geziyor, r *http.Response) {
ParseFunc: func(g *geziyor.Geziyor, r *client.Response) {
if len(g.Client.Cookies(r.Request.URL.String())) != 0 {
t.Fatal("Cookies exist")
}
@ -148,7 +148,7 @@ func TestCookies(t *testing.T) {
func TestBasicAuth(t *testing.T) {
geziyor.NewGeziyor(&geziyor.Options{
StartRequestsFunc: func(g *geziyor.Geziyor) {
req, _ := http.NewRequest("GET", "https://httpbin.org/anything", nil)
req, _ := client.NewRequest("GET", "https://httpbin.org/anything", nil)
req.SetBasicAuth("username", "password")
g.Do(req, nil)
},
@ -170,14 +170,14 @@ func TestExtractor(t *testing.T) {
}
func TestCharsetDetection(t *testing.T) {
ts := httptest.NewServer(httpstd.HandlerFunc(func(w httpstd.ResponseWriter, r *httpstd.Request) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "\xf0ültekin")
}))
defer ts.Close()
geziyor.NewGeziyor(&geziyor.Options{
StartURLs: []string{ts.URL},
ParseFunc: func(g *geziyor.Geziyor, r *http.Response) {
ParseFunc: func(g *geziyor.Geziyor, r *client.Response) {
if !utf8.Valid(r.Body) {
t.Fatal()
}
@ -187,7 +187,7 @@ func TestCharsetDetection(t *testing.T) {
geziyor.NewGeziyor(&geziyor.Options{
StartURLs: []string{ts.URL},
ParseFunc: func(g *geziyor.Geziyor, r *http.Response) {
ParseFunc: func(g *geziyor.Geziyor, r *client.Response) {
if utf8.Valid(r.Body) {
t.Fatal()
}
@ -200,10 +200,10 @@ func TestCharsetDetection(t *testing.T) {
func BenchmarkGeziyor_Do(b *testing.B) {
// Create Server
ts := httptest.NewServer(httpstd.HandlerFunc(func(w httpstd.ResponseWriter, r *httpstd.Request) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "Hello, client")
}))
ts.Client().Transport = http.NewClient().Transport
ts.Client().Transport = client.NewClient().Transport
defer ts.Close()
// As we don't benchmark creating a server, reset timer.
@ -212,7 +212,7 @@ func BenchmarkGeziyor_Do(b *testing.B) {
geziyor.NewGeziyor(&geziyor.Options{
StartRequestsFunc: func(g *geziyor.Geziyor) {
// Create Synchronized request to benchmark requests accurately.
req, _ := http.NewRequest("GET", ts.URL, nil)
req, _ := client.NewRequest("GET", ts.URL, nil)
req.Synchronized = true
// We only bench here !

View File

@ -4,7 +4,7 @@ import (
"bytes"
"fmt"
"github.com/PuerkitoBio/goquery"
"github.com/geziyor/geziyor/http"
"github.com/geziyor/geziyor/client"
"github.com/geziyor/geziyor/internal"
"log"
"math/rand"
@ -16,10 +16,10 @@ import (
// RequestMiddleware called before requests made.
// Set request.Cancelled = true to cancel request
type RequestMiddleware func(g *Geziyor, r *http.Request)
type RequestMiddleware func(g *Geziyor, r *client.Request)
// ResponseMiddleware called after request response receive
type ResponseMiddleware func(g *Geziyor, r *http.Response)
type ResponseMiddleware func(g *Geziyor, r *client.Response)
func init() {
log.SetOutput(os.Stdout)
@ -28,7 +28,7 @@ func init() {
// recoverMiddleware recovers scraping being crashed.
// Logs error and stack trace
func recoverMiddleware(g *Geziyor, r *http.Request) {
func recoverMiddleware(g *Geziyor, r *client.Request) {
if r := recover(); r != nil {
log.Println(r, string(debug.Stack()))
g.metrics.PanicCounter.Add(1)
@ -36,7 +36,7 @@ func recoverMiddleware(g *Geziyor, r *http.Request) {
}
// allowedDomainsMiddleware checks for request host if it exists in AllowedDomains
func allowedDomainsMiddleware(g *Geziyor, r *http.Request) {
func allowedDomainsMiddleware(g *Geziyor, r *client.Request) {
if len(g.Opt.AllowedDomains) != 0 && !internal.Contains(g.Opt.AllowedDomains, r.Host) {
//log.Printf("Domain not allowed: %s\n", req.Host)
r.Cancel()
@ -45,7 +45,7 @@ func allowedDomainsMiddleware(g *Geziyor, r *http.Request) {
}
// duplicateRequestsMiddleware checks for already visited URLs
func duplicateRequestsMiddleware(g *Geziyor, r *http.Request) {
func duplicateRequestsMiddleware(g *Geziyor, r *client.Request) {
if !g.Opt.URLRevisitEnabled {
key := r.Request.URL.String() + r.Request.Method
if _, visited := g.visitedURLs.LoadOrStore(key, struct{}{}); visited {
@ -56,15 +56,15 @@ func duplicateRequestsMiddleware(g *Geziyor, r *http.Request) {
}
// defaultHeadersMiddleware sets default request headers
func defaultHeadersMiddleware(g *Geziyor, r *http.Request) {
r.Header = http.SetDefaultHeader(r.Header, "Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
r.Header = http.SetDefaultHeader(r.Header, "Accept-Charset", "utf-8")
r.Header = http.SetDefaultHeader(r.Header, "Accept-Language", "en")
r.Header = http.SetDefaultHeader(r.Header, "User-Agent", g.Opt.UserAgent)
func defaultHeadersMiddleware(g *Geziyor, r *client.Request) {
r.Header = client.SetDefaultHeader(r.Header, "Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
r.Header = client.SetDefaultHeader(r.Header, "Accept-Charset", "utf-8")
r.Header = client.SetDefaultHeader(r.Header, "Accept-Language", "en")
r.Header = client.SetDefaultHeader(r.Header, "User-Agent", g.Opt.UserAgent)
}
// delayMiddleware delays requests
func delayMiddleware(g *Geziyor, r *http.Request) {
func delayMiddleware(g *Geziyor, r *client.Request) {
if g.Opt.RequestDelayRandomize {
min := float64(g.Opt.RequestDelay) * 0.5
max := float64(g.Opt.RequestDelay) * 1.5
@ -75,29 +75,29 @@ func delayMiddleware(g *Geziyor, r *http.Request) {
}
// logMiddleware logs requests
func logMiddleware(g *Geziyor, r *http.Request) {
func logMiddleware(g *Geziyor, r *client.Request) {
log.Println("Fetching: ", r.URL.String())
}
// metricsRequestMiddleware sets stats
func metricsRequestMiddleware(g *Geziyor, r *http.Request) {
func metricsRequestMiddleware(g *Geziyor, r *client.Request) {
g.metrics.RequestCounter.With("method", r.Method).Add(1)
}
// parseHTMLMiddleware parses response if response is HTML
func parseHTMLMiddleware(g *Geziyor, r *http.Response) {
func parseHTMLMiddleware(g *Geziyor, r *client.Response) {
if !g.Opt.ParseHTMLDisabled && r.IsHTML() {
r.HTMLDoc, _ = goquery.NewDocumentFromReader(bytes.NewReader(r.Body))
}
}
// metricsResponseMiddleware sets stats
func metricsResponseMiddleware(g *Geziyor, r *http.Response) {
func metricsResponseMiddleware(g *Geziyor, r *client.Response) {
g.metrics.ResponseCounter.With("method", r.Request.Method).Add(1)
}
// extractorsMiddleware extracts data from loaders conf and exports it to exporters
func extractorsMiddleware(g *Geziyor, r *http.Response) {
func extractorsMiddleware(g *Geziyor, r *client.Response) {
// Check if we have extractors and exporters
if len(g.Opt.Extractors) != 0 && len(g.Opt.Exporters) != 0 {

View File

@ -2,7 +2,7 @@ package geziyor
import (
"github.com/fpfeng/httpcache"
"github.com/geziyor/geziyor/http"
"github.com/geziyor/geziyor/client"
"github.com/geziyor/geziyor/metrics"
"time"
)
@ -20,7 +20,7 @@ type Options struct {
StartRequestsFunc func(g *Geziyor)
// ParseFunc is callback of StartURLs response.
ParseFunc func(g *Geziyor, r *http.Response)
ParseFunc func(g *Geziyor, r *client.Response)
// Extractors extracts items from pages
Extractors []Extractor