Skip to content

Commit db213f7

Browse files
committed
feat: add srcSet scraping
1 parent 0f1477d commit db213f7

1 file changed

Lines changed: 73 additions & 22 deletions

File tree

cmd/wp-go-static/commands/root.go

Lines changed: 73 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package commands
33
import (
44
"crypto/tls"
55
"fmt"
6+
"log"
67
"net/http"
78
"net/url"
89
"regexp"
@@ -70,21 +71,17 @@ func init() {
7071
RootCmd.PersistentFlags().String("cache", "", "Cache directory")
7172
RootCmd.PersistentFlags().Bool("parallel", false, "Fetch in parallel")
7273
RootCmd.PersistentFlags().Bool("images", true, "Download images")
74+
RootCmd.MarkFlagRequired("url")
7375

7476
// Bind command-line flags to Viper
75-
viper.BindPFlag("dir", RootCmd.PersistentFlags().Lookup("dir"))
76-
viper.BindPFlag("url", RootCmd.PersistentFlags().Lookup("url"))
77-
viper.BindPFlag("cache", RootCmd.PersistentFlags().Lookup("cache"))
78-
viper.BindPFlag("images", RootCmd.PersistentFlags().Lookup("images"))
77+
err := viper.BindPFlags(RootCmd.PersistentFlags())
78+
if err != nil {
79+
log.Fatal(err)
80+
}
7981

8082
viper.AutomaticEnv()
8183
viper.EnvKeyReplacer(strings.NewReplacer("-", "_"))
8284
viper.SetEnvPrefix("WGS")
83-
84-
// Execute root command
85-
if err := RootCmd.Execute(); err != nil {
86-
fmt.Println(err)
87-
}
8885
}
8986

9087
func rootCmdF(command *cobra.Command, args []string) error {
@@ -103,9 +100,9 @@ func rootCmdF(command *cobra.Command, args []string) error {
103100

104101
scrape.c.Async = parallel
105102

106-
// Ignore SSL errors
103+
// Use a custom TLS config to verify server certificates
107104
scrape.c.WithTransport(&http.Transport{
108-
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
105+
TLSClientConfig: &tls.Config{},
109106
})
110107

111108
parsedURL, err := url.Parse(commandURL)
@@ -120,31 +117,44 @@ func rootCmdF(command *cobra.Command, args []string) error {
120117
// On every a element which has href attribute call callback
121118
scrape.c.OnHTML("a[href]", func(e *colly.HTMLElement) {
122119
link := e.Attr("href")
123-
scrape.visitURL(e.Request.AbsoluteURL(link))
120+
scrape.visitURL(link)
124121
})
125122

126123
// On every link element call callback
127124
scrape.c.OnHTML("link[href]", func(e *colly.HTMLElement) {
128125
link := e.Attr("href")
129-
scrape.visitURL(e.Request.AbsoluteURL(link))
126+
scrape.visitURL(link)
130127
})
131128

132129
// On every script element call callback
133130
scrape.c.OnHTML("script[src]", func(e *colly.HTMLElement) {
134131
link := e.Attr("src")
135-
scrape.visitURL(e.Request.AbsoluteURL(link))
132+
scrape.visitURL(link)
136133
})
137134

138135
// On every img element call callback
139-
140136
scrape.c.OnHTML("img", func(e *colly.HTMLElement) {
141-
link := e.Attr("src")
142-
scrape.visitURL(e.Request.AbsoluteURL(link))
137+
src := e.Attr("src")
138+
srcSet := e.Attr("srcset")
139+
scrape.visitURL(src)
140+
141+
if srcSet != "" {
142+
srcSetList := strings.Split(srcSet, ",")
143+
for _, srcSetURL := range srcSetList {
144+
srcSetURL = strings.TrimSpace(srcSetURL)
145+
innerSrcSet := strings.Split(srcSetURL, " ")[0]
146+
if innerSrcSet == "" {
147+
continue
148+
}
149+
150+
scrape.visitURL(innerSrcSet)
151+
}
152+
}
143153
})
144154

145155
// Before making a request print "Visiting ..."
146156
scrape.c.OnRequest(func(r *colly.Request) {
147-
fmt.Println("Visiting", r.URL.String())
157+
log.Println("Visiting", r.URL.String())
148158
})
149159

150160
// On response
@@ -154,7 +164,7 @@ func rootCmdF(command *cobra.Command, args []string) error {
154164

155165
err := file.SaveFile(r, dir, fileName)
156166
if err != nil {
157-
fmt.Println(err)
167+
log.Println(err)
158168
return
159169
}
160170
})
@@ -172,15 +182,38 @@ func rootCmdF(command *cobra.Command, args []string) error {
172182
}
173183

174184
func (s *Scrape) visitURL(link string) {
175-
// Download image found on page if it hasn't been visited before
185+
link = s.getAbsoluteURL(link)
186+
187+
if link == "" {
188+
return
189+
}
190+
191+
u, err := url.Parse(link)
192+
if err != nil {
193+
log.Printf("Error parsing URL %s: %s", link, err)
194+
return
195+
}
196+
197+
if u.Scheme == "" || u.Host == "" {
198+
log.Printf("Invalid URL %s", link)
199+
return
200+
}
201+
202+
u.Fragment = ""
203+
204+
link = u.String()
205+
206+
// Download page if it hasn't been visited before
176207
if !s.urlCache.Get(link) {
177208
s.urlCache.Add(link)
178-
s.c.Visit(link)
209+
err := s.c.Visit(link)
210+
if err != nil {
211+
log.Println(err)
212+
}
179213
}
180214
}
181215

182216
func (s *Scrape) parseBody(body []byte) []byte {
183-
// Find all URLs in the CSS file
184217
cssUrls := regexp.MustCompile(`url\((https?://[^\s]+)\)`).FindAllStringSubmatch(string(body), -1)
185218

186219
// Download each referenced file if it hasn't been visited before
@@ -208,3 +241,21 @@ func (s *Scrape) parseBody(body []byte) []byte {
208241

209242
return body
210243
}
244+
245+
func (s *Scrape) getAbsoluteURL(inputURL string) string {
246+
parsedURL, err := url.Parse(inputURL)
247+
if err != nil {
248+
return ""
249+
}
250+
251+
if parsedURL.IsAbs() {
252+
return inputURL
253+
}
254+
255+
baseURL, err := url.Parse(s.domain)
256+
if err != nil {
257+
return ""
258+
}
259+
260+
return baseURL.ResolveReference(parsedURL).String()
261+
}

0 commit comments

Comments
 (0)