|
|
@ -19,7 +19,9 @@ |
|
|
|
package worker |
|
|
|
package worker |
|
|
|
|
|
|
|
|
|
|
|
import ( |
|
|
|
import ( |
|
|
|
|
|
|
|
"encoding/json" |
|
|
|
"fmt" |
|
|
|
"fmt" |
|
|
|
|
|
|
|
"io" |
|
|
|
"net/url" |
|
|
|
"net/url" |
|
|
|
"os" |
|
|
|
"os" |
|
|
|
"path" |
|
|
|
"path" |
|
|
@ -46,12 +48,13 @@ type WorkerConf struct { |
|
|
|
BlacklistedDomains []string |
|
|
|
BlacklistedDomains []string |
|
|
|
AllowedDomains []string |
|
|
|
AllowedDomains []string |
|
|
|
VisitQueue VisitQueue |
|
|
|
VisitQueue VisitQueue |
|
|
|
|
|
|
|
TextOutput io.Writer |
|
|
|
|
|
|
|
EmailsOutput io.Writer |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Web worker
|
|
|
|
// Web worker
|
|
|
|
type Worker struct { |
|
|
|
type Worker struct { |
|
|
|
Jobs chan web.Job |
|
|
|
Jobs chan web.Job |
|
|
|
Results chan web.Result |
|
|
|
|
|
|
|
Conf *WorkerConf |
|
|
|
Conf *WorkerConf |
|
|
|
visited *visited |
|
|
|
visited *visited |
|
|
|
stats *Statistics |
|
|
|
stats *Statistics |
|
|
@ -62,7 +65,6 @@ type Worker struct { |
|
|
|
func NewWorker(jobs chan web.Job, results chan web.Result, conf *WorkerConf, visited *visited, stats *Statistics) Worker { |
|
|
|
func NewWorker(jobs chan web.Job, results chan web.Result, conf *WorkerConf, visited *visited, stats *Statistics) Worker { |
|
|
|
return Worker{ |
|
|
|
return Worker{ |
|
|
|
Jobs: jobs, |
|
|
|
Jobs: jobs, |
|
|
|
Results: results, |
|
|
|
|
|
|
|
Conf: conf, |
|
|
|
Conf: conf, |
|
|
|
visited: visited, |
|
|
|
visited: visited, |
|
|
|
stats: stats, |
|
|
|
stats: stats, |
|
|
@ -138,6 +140,25 @@ func (w *Worker) savePage(baseURL *url.URL, pageData []byte) { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (w *Worker) saveResult(result web.Result) { |
|
|
|
|
|
|
|
// write result to the output file
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var output io.Writer |
|
|
|
|
|
|
|
if result.Search.Query == config.QueryEmail { |
|
|
|
|
|
|
|
output = w.Conf.EmailsOutput |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
output = w.Conf.TextOutput |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// each entry in output file is a self-standing JSON object
|
|
|
|
|
|
|
|
entryBytes, err := json.MarshalIndent(result, " ", "\t") |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
return |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
output.Write(entryBytes) |
|
|
|
|
|
|
|
output.Write([]byte("\n")) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Launch scraping process on this worker
|
|
|
|
// Launch scraping process on this worker
|
|
|
|
func (w *Worker) Work() { |
|
|
|
func (w *Worker) Work() { |
|
|
|
if w.Stopped { |
|
|
|
if w.Stopped { |
|
|
@ -319,11 +340,11 @@ func (w *Worker) Work() { |
|
|
|
// search for email
|
|
|
|
// search for email
|
|
|
|
emailAddresses := web.FindPageEmailsWithCheck(pageData) |
|
|
|
emailAddresses := web.FindPageEmailsWithCheck(pageData) |
|
|
|
if len(emailAddresses) > 0 { |
|
|
|
if len(emailAddresses) > 0 { |
|
|
|
w.Results <- web.Result{ |
|
|
|
w.saveResult(web.Result{ |
|
|
|
PageURL: job.URL, |
|
|
|
PageURL: job.URL, |
|
|
|
Search: job.Search, |
|
|
|
Search: job.Search, |
|
|
|
Data: emailAddresses, |
|
|
|
Data: emailAddresses, |
|
|
|
} |
|
|
|
}) |
|
|
|
w.stats.MatchesFound += uint64(len(emailAddresses)) |
|
|
|
w.stats.MatchesFound += uint64(len(emailAddresses)) |
|
|
|
savePage = true |
|
|
|
savePage = true |
|
|
|
} |
|
|
|
} |
|
|
@ -339,22 +360,22 @@ func (w *Worker) Work() { |
|
|
|
contentLinks = append(contentLinks, web.FindPageDocuments(pageData, pageURL)...) |
|
|
|
contentLinks = append(contentLinks, web.FindPageDocuments(pageData, pageURL)...) |
|
|
|
w.saveContent(contentLinks, pageURL) |
|
|
|
w.saveContent(contentLinks, pageURL) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if len(contentLinks) > 0 { |
|
|
|
|
|
|
|
savePage = true |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// email
|
|
|
|
// email
|
|
|
|
emailAddresses := web.FindPageEmailsWithCheck(pageData) |
|
|
|
emailAddresses := web.FindPageEmailsWithCheck(pageData) |
|
|
|
if len(emailAddresses) > 0 { |
|
|
|
if len(emailAddresses) > 0 { |
|
|
|
w.Results <- web.Result{ |
|
|
|
w.saveResult(web.Result{ |
|
|
|
PageURL: job.URL, |
|
|
|
PageURL: job.URL, |
|
|
|
Search: job.Search, |
|
|
|
Search: job.Search, |
|
|
|
Data: emailAddresses, |
|
|
|
Data: emailAddresses, |
|
|
|
} |
|
|
|
}) |
|
|
|
w.stats.MatchesFound += uint64(len(emailAddresses)) |
|
|
|
w.stats.MatchesFound += uint64(len(emailAddresses)) |
|
|
|
savePage = true |
|
|
|
savePage = true |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if len(contentLinks) > 0 || len(emailAddresses) > 0 { |
|
|
|
|
|
|
|
savePage = true |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
default: |
|
|
|
default: |
|
|
|
// text search
|
|
|
|
// text search
|
|
|
|
switch job.Search.IsRegexp { |
|
|
|
switch job.Search.IsRegexp { |
|
|
@ -368,11 +389,11 @@ func (w *Worker) Work() { |
|
|
|
|
|
|
|
|
|
|
|
matches := web.FindPageRegexp(re, pageData) |
|
|
|
matches := web.FindPageRegexp(re, pageData) |
|
|
|
if len(matches) > 0 { |
|
|
|
if len(matches) > 0 { |
|
|
|
w.Results <- web.Result{ |
|
|
|
w.saveResult(web.Result{ |
|
|
|
PageURL: job.URL, |
|
|
|
PageURL: job.URL, |
|
|
|
Search: job.Search, |
|
|
|
Search: job.Search, |
|
|
|
Data: matches, |
|
|
|
Data: matches, |
|
|
|
} |
|
|
|
}) |
|
|
|
logger.Info("Found matches: %+v", matches) |
|
|
|
logger.Info("Found matches: %+v", matches) |
|
|
|
w.stats.MatchesFound += uint64(len(matches)) |
|
|
|
w.stats.MatchesFound += uint64(len(matches)) |
|
|
|
savePage = true |
|
|
|
savePage = true |
|
|
@ -380,11 +401,11 @@ func (w *Worker) Work() { |
|
|
|
case false: |
|
|
|
case false: |
|
|
|
// just text
|
|
|
|
// just text
|
|
|
|
if web.IsTextOnPage(job.Search.Query, true, pageData) { |
|
|
|
if web.IsTextOnPage(job.Search.Query, true, pageData) { |
|
|
|
w.Results <- web.Result{ |
|
|
|
w.saveResult(web.Result{ |
|
|
|
PageURL: job.URL, |
|
|
|
PageURL: job.URL, |
|
|
|
Search: job.Search, |
|
|
|
Search: job.Search, |
|
|
|
Data: []string{job.Search.Query}, |
|
|
|
Data: []string{job.Search.Query}, |
|
|
|
} |
|
|
|
}) |
|
|
|
logger.Info("Found \"%s\" on page", job.Search.Query) |
|
|
|
logger.Info("Found \"%s\" on page", job.Search.Query) |
|
|
|
w.stats.MatchesFound++ |
|
|
|
w.stats.MatchesFound++ |
|
|
|
savePage = true |
|
|
|
savePage = true |
|
|
|