1+ package scraper
2+
3+ import (
4+ "aproxy/internal/logger"
5+ "bufio"
6+ "context"
7+ "fmt"
8+ "io"
9+ "net/http"
10+ "strconv"
11+ "strings"
12+ "time"
13+ )
14+
15+ type GitHubProxyScraper struct {
16+ client * http.Client
17+ userAgent string
18+ logger * logger.Logger
19+ }
20+
21+ func NewGitHubProxyScraper () * GitHubProxyScraper {
22+ return & GitHubProxyScraper {
23+ client : & http.Client {
24+ Timeout : 30 * time .Second ,
25+ },
26+ userAgent : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" ,
27+ logger : logger .New ("github" ),
28+ }
29+ }
30+
31+ func NewGitHubProxyScraperWithConfig (config ScraperConfig ) * GitHubProxyScraper {
32+ return & GitHubProxyScraper {
33+ client : & http.Client {
34+ Timeout : config .Timeout ,
35+ },
36+ userAgent : config .UserAgent ,
37+ logger : logger .New ("github" ),
38+ }
39+ }
40+
41+ func (g * GitHubProxyScraper ) Name () string {
42+ return "github"
43+ }
44+
45+ func (g * GitHubProxyScraper ) Scrape (ctx context.Context ) ([]Proxy , error ) {
46+ url := "https://raw.githubusercontent.com/proxifly/free-proxy-list/refs/heads/main/proxies/all/data.txt"
47+
48+ proxies , err := g .scrapeTextURL (ctx , url )
49+ if err != nil {
50+ return nil , fmt .Errorf ("GitHub proxy scrape failed: %w" , err )
51+ }
52+
53+ httpCount := 0
54+ for _ , proxy := range proxies {
55+ if proxy .Type == "http" || proxy .Type == "https" {
56+ httpCount ++
57+ }
58+ }
59+
60+ g .logger .InfoBg ("GitHub collected: %d HTTP/HTTPS proxies" , httpCount )
61+ return proxies , nil
62+ }
63+
64+ func (g * GitHubProxyScraper ) scrapeTextURL (ctx context.Context , url string ) ([]Proxy , error ) {
65+ req , err := http .NewRequestWithContext (ctx , "GET" , url , nil )
66+ if err != nil {
67+ return nil , err
68+ }
69+
70+ req .Header .Set ("User-Agent" , g .userAgent )
71+
72+ resp , err := g .client .Do (req )
73+ if err != nil {
74+ return nil , err
75+ }
76+ defer resp .Body .Close ()
77+
78+ if resp .StatusCode != http .StatusOK {
79+ return nil , fmt .Errorf ("HTTP %d" , resp .StatusCode )
80+ }
81+
82+ return g .parseProtocolProxies (resp .Body )
83+ }
84+
85+ func (g * GitHubProxyScraper ) parseProtocolProxies (reader io.Reader ) ([]Proxy , error ) {
86+ var proxies []Proxy
87+ scanner := bufio .NewScanner (reader )
88+
89+ for scanner .Scan () {
90+ line := strings .TrimSpace (scanner .Text ())
91+ if line == "" {
92+ continue
93+ }
94+
95+ parts := strings .Split (line , "://" )
96+ if len (parts ) != 2 {
97+ continue
98+ }
99+
100+ protocol := parts [0 ]
101+ hostPort := parts [1 ]
102+
103+ hostPortParts := strings .Split (hostPort , ":" )
104+ if len (hostPortParts ) != 2 {
105+ continue
106+ }
107+
108+ port , err := strconv .Atoi (hostPortParts [1 ])
109+ if err != nil {
110+ continue
111+ }
112+
113+ proxy := Proxy {
114+ Host : hostPortParts [0 ],
115+ Port : port ,
116+ Type : protocol ,
117+ LastSeen : time .Now (),
118+ }
119+
120+ proxies = append (proxies , proxy )
121+ }
122+
123+ return proxies , scanner .Err ()
124+ }
0 commit comments