Search/text-google.go
partisan 614ce8903e
All checks were successful
Run Integration Tests / test (push) Successful in 33s
added SOCKS5 proxy support
2025-01-12 16:46:52 +01:00

138 lines
3.3 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package main
import (
"fmt"
"net/http"
"net/url"
"strings"
"time"
"github.com/PuerkitoBio/goquery"
)
func PerformGoogleTextSearch(query, safe, lang string, page int) ([]TextSearchResult, time.Duration, error) {
const resultsPerPage = 10
var results []TextSearchResult
startTime := time.Now() // Start the timer
// Build the search URL
searchURL := buildSearchURL(query, safe, lang, page, resultsPerPage)
// Create a new request
req, err := http.NewRequest("GET", searchURL, nil)
if err != nil {
return nil, 0, fmt.Errorf("failed to create request: %v", err)
}
// Generate and set User-Agent header
TextUserAgent, err := GetUserAgent("Google-Text-Search")
if err != nil {
return nil, 0, err
}
req.Header.Set("User-Agent", TextUserAgent)
// Perform the request using proxy if MetaProxy is enabled
var resp *http.Response
if config.MetaProxyEnabled && metaProxyClient != nil {
resp, err = metaProxyClient.Do(req)
} else {
client := &http.Client{}
resp, err = client.Do(req)
}
if err != nil {
return nil, 0, fmt.Errorf("making request: %v", err)
}
defer resp.Body.Close()
// Check for HTTP status code
if resp.StatusCode != http.StatusOK {
return nil, 0, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
}
// Parse the HTML response
doc, err := goquery.NewDocumentFromReader(resp.Body)
if err != nil {
return nil, 0, fmt.Errorf("loading HTML document: %v", err)
}
// Extract search results
results = parseResults(doc)
duration := time.Since(startTime) // Calculate the duration
if len(results) == 0 {
printDebug("No results found from Google Search")
}
return results, duration, nil
}
func buildSearchURL(query, safe, lang string, page, resultsPerPage int) string {
safeParam := "&safe=off"
if safe == "active" {
safeParam = "&safe=active"
}
langParam := ""
var glParam string
if lang != "" {
// Use lang as the geolocation
langParam = "&lr=lang_" + lang
glParam = "&gl=" + lang
} else {
// Use default geolocation
glParam = "&gl=us"
}
startIndex := (page - 1) * resultsPerPage
printDebug(fmt.Sprintf("https://www.google.com/search?q=%s%s%s%s&start=%d",
url.QueryEscape(query), safeParam, langParam, glParam, startIndex))
return fmt.Sprintf("https://www.google.com/search?q=%s%s%s%s&start=%d",
url.QueryEscape(query), safeParam, langParam, glParam, startIndex)
}
// func getRandomGeoLocation() (string, string) {
// countries := []string{"us", "ca", "gb", "fr", "de", "au", "in", "jp", "br", "za"}
// randomCountry := countries[rand.Intn(len(countries))]
// glParam := "&gl=" + randomCountry
// uuleParam := ""
// return glParam, uuleParam
// }
func parseResults(doc *goquery.Document) []TextSearchResult {
var results []TextSearchResult
doc.Find(".yuRUbf").Each(func(i int, s *goquery.Selection) {
link := s.Find("a")
href, exists := link.Attr("href")
if !exists {
printDebug("No href attribute found for result %d\n", i)
return
}
header := link.Find("h3").Text()
header = strings.TrimSpace(strings.TrimSuffix(header, ""))
description := ""
descSelection := doc.Find(".VwiC3b").Eq(i)
if descSelection.Length() > 0 {
description = descSelection.Text()
}
result := TextSearchResult{
URL: href,
Header: header,
Description: description,
}
results = append(results, result)
})
return results
}