diff --git a/README.md b/README.md index 3448410..3546a2f 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,23 @@ -# Pad Stratum0 Link Extractor +# Universal Link Extractor for Etherpad Lite ## Beschreibung -Dieses Go-Programm ist ein spezialisierter Web Scraper, der entwickelt wurde, um Links von der Pad Stratum0 Plattform zu extrahieren. Es navigiert durch verschachtelte iFrames und sammelt alle URLs, die mit "https://pad.stratum0.org/p/dc" beginnen. +Der Universal Link Extractor for Etherpad Lite ist ein leistungsfähiges Go-Programm, das entwickelt wurde, um Links von Etherpad Lite Instanzen zu extrahieren. Es navigiert durch verschachtelte iFrames und sammelt alle URLs, die einem bestimmten Muster entsprechen. Dieses Tool ist besonders nützlich für die Analyse und Kartierung von Etherpad-basierten Kollaborationsplattformen. -## Funktionen +## Hauptfunktionen -- Extrahiert Links von einer initialen URL und folgt diesen rekursiv bis zu einer konfigurierbaren maximalen Tiefe. -- Navigiert durch verschachtelte iFrames, um versteckte Links zu finden. -- Vermeidet doppelte Besuche von URLs. -- Bietet detaillierte Konsolenausgaben über den Fortschritt des Scrapings. -- Sammelt Statistiken über gefundene und besuchte Links. +- Extrahiert Links von einer oder mehreren initialen URLs +- Navigiert rekursiv durch gefundene Links bis zu einer konfigurierbaren maximalen Tiefe +- Durchsucht verschachtelte iFrames, um versteckte Links zu finden +- Vermeidet doppelte Besuche von URLs +- Bietet eine Fortschrittsanzeige für den Extraktionsprozess +- Sammelt und zeigt Statistiken über gefundene und besuchte Links ## Voraussetzungen - Go 1.16 oder höher - go-rod Bibliothek +- progressbar/v3 Bibliothek ## Installation @@ -23,8 +25,8 @@ Dieses Go-Programm ist ein spezialisierter Web Scraper, der entwickelt wurde, um 2. Klonen Sie das Repository: ``` - git clone https://github.com/yourusername/pad-stratum0-link-extractor.git - cd pad-stratum0-link-extractor + git clone https://github.com/yourusername/universal-link-extractor-etherpad.git + cd universal-link-extractor-etherpad ``` 3. Installieren Sie die erforderlichen Abhängigkeiten: @@ -34,10 +36,12 @@ Dieses Go-Programm ist ein spezialisierter Web Scraper, der entwickelt wurde, um ## Konfiguration -Sie können die maximale Suchtiefe anpassen, indem Sie den Wert der `maxDepth` Variable am Anfang der `main.go` Datei ändern: +Passen Sie die folgenden Variablen am Anfang der `main.go` Datei an Ihre Bedürfnisse an: ```go -maxDepth = 3 // Ändern Sie diesen Wert nach Bedarf +maxDepth = 3 // Maximale Rekursionstiefe +initialURLs = []string{"https://pad.stratum0.org/p/dc"} // Startseiten +linkRegexPattern = `https://pad\.stratum0\.org/p/dc[^\s"']+` // Regex für zu extrahierende Links ``` ## Verwendung @@ -47,13 +51,13 @@ maxDepth = 3 // Ändern Sie diesen Wert nach Bedarf go run main.go ``` -2. Das Programm wird mit der Extraktion von Links beginnen und den Fortschritt in der Konsole ausgeben. +2. Das Programm wird mit der Extraktion von Links beginnen und den Fortschritt in der Konsole anzeigen. -3. Nach Abschluss wird eine Liste aller gefundenen Links sowie Statistiken angezeigt. +3. Nach Abschluss wird eine Liste aller gefundenen Links sowie Statistiken ausgegeben. ## Ausgabe -Das Programm gibt folgende Informationen aus: +Das Programm liefert folgende Informationen: - Fortschrittsmeldungen für jede verarbeitete URL - Informationen über gefundene und geladene iFrames @@ -62,32 +66,14 @@ Das Programm gibt folgende Informationen aus: ## Anpassung -- Um andere Websites zu scrapen, passen Sie die initiale URL und den regulären Ausdruck für die Link-Erkennung an. -- Für komplexere Scraping-Logik können Sie die `extractLinks` Funktion modifizieren. +- Um andere Etherpad Lite Instanzen zu durchsuchen, passen Sie die `initialURLs` und `linkRegexPattern` an. +- Für komplexere Extraktionslogik können Sie die `extractLinks` Funktion modifizieren. ## Fehlerbehebung -- Wenn Sie Probleme mit dem Laden von iFrames haben, überprüfen Sie die CSS-Selektoren in der `processNestedIframes` Funktion. -- Bei Timeout-Problemen können Sie die `MustWaitLoad` Aufrufe anpassen oder zusätzliche Wartezeiten einbauen. +- Bei Problemen mit dem Laden von iFrames überprüfen Sie die CSS-Selektoren in der `processNestedIframes` Funktion. +- Wenn Sie Timeout-Probleme haben, passen Sie die `MustWaitLoad` Aufrufe an oder fügen Sie zusätzliche Wartezeiten ein. ## Beitrag Beiträge zum Projekt sind willkommen. Bitte öffnen Sie ein Issue oder einen Pull Request für Vorschläge oder Verbesserungen. - -## Lizenz - -[Fügen Sie hier Ihre gewählte Lizenz ein, z.B. MIT, GPL, etc.] - -``` - -Diese README.md bietet eine umfassende Übersicht über Ihr Projekt und enthält Abschnitte für: - -1. Eine Beschreibung des Projekts und seiner Hauptfunktionen -2. Installationsanweisungen -3. Konfigurationsmöglichkeiten -4. Verwendungshinweise -5. Erklärung der Ausgabe -6. Anpassungsmöglichkeiten -7. Tipps zur Fehlerbehebung -8. Informationen zum Beitragen zum Projekt -9. Einen Platzhalter für die Lizenz diff --git a/go.mod b/go.mod index 852a58a..88921f5 100755 --- a/go.mod +++ b/go.mod @@ -5,9 +5,14 @@ go 1.19 require github.com/go-rod/rod v0.116.2 require ( + github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect + github.com/rivo/uniseg v0.4.7 // indirect + github.com/schollz/progressbar/v3 v3.15.0 // indirect github.com/ysmood/fetchup v0.2.3 // indirect github.com/ysmood/goob v0.4.0 // indirect github.com/ysmood/got v0.40.0 // indirect github.com/ysmood/gson v0.7.3 // indirect github.com/ysmood/leakless v0.9.0 // indirect + golang.org/x/sys v0.25.0 // indirect + golang.org/x/term v0.24.0 // indirect ) diff --git a/go.sum b/go.sum index 09e669a..c8c94d0 100755 --- a/go.sum +++ b/go.sum @@ -1,5 +1,18 @@ +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-rod/rod v0.116.2 h1:A5t2Ky2A+5eD/ZJQr1EfsQSe5rms5Xof/qj296e+ZqA= github.com/go-rod/rod v0.116.2/go.mod h1:H+CMO9SCNc2TJ2WfrG+pKhITz57uGNYU43qYHh438Mg= +github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ= +github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/schollz/progressbar/v3 v3.15.0 h1:cNZmcNiVyea6oofBTg80ZhVXxf3wG/JoAhqCCwopkQo= +github.com/schollz/progressbar/v3 v3.15.0/go.mod h1:ncBdc++eweU0dQoeZJ3loXoAc+bjaallHRIm8pVVeQM= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/ysmood/fetchup v0.2.3 h1:ulX+SonA0Vma5zUFXtv52Kzip/xe7aj4vqT5AJwQ+ZQ= github.com/ysmood/fetchup v0.2.3/go.mod h1:xhibcRKziSvol0H1/pj33dnKrYyI2ebIvz5cOOkYGns= github.com/ysmood/goob v0.4.0 h1:HsxXhyLBeGzWXnqVKtmT9qM7EuVs/XOgkX7T6r1o1AQ= @@ -13,3 +26,8 @@ github.com/ysmood/gson v0.7.3 h1:QFkWbTH8MxyUTKPkVWAENJhxqdBa4lYTQWqZCiLG6kE= github.com/ysmood/gson v0.7.3/go.mod h1:3Kzs5zDl21g5F/BlLTNcuAGAYLKt2lV5G8D1zF3RNmg= github.com/ysmood/leakless v0.9.0 h1:qxCG5VirSBvmi3uynXFkcnLMzkphdh3xx5FtrORwDCU= github.com/ysmood/leakless v0.9.0/go.mod h1:R8iAXPRaG97QJwqxs74RdwzcRHT1SWCGTNqY8q0JvMQ= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= +golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= diff --git a/scraper.go b/scraper.go index 7f48ce5..34334ee 100644 --- a/scraper.go +++ b/scraper.go @@ -5,12 +5,17 @@ import ( "regexp" "time" "github.com/go-rod/rod" + "github.com/schollz/progressbar/v3" ) var ( visitedURLs = make(map[string]bool) allLinks = make(map[string]bool) maxDepth = 3 // Hier können Sie die maximale Tiefe festlegen + + // Neue Variablen für initiale URLs und Regex-Pattern + initialURLs = []string{"https://pad.stratum0.org/p/dc"} + linkRegexPattern = `https://pad\.stratum0\.org/p/dc[^\s"']+` ) func main() { @@ -20,14 +25,24 @@ func main() { browser := rod.New().MustConnect() defer browser.MustClose() - initialURL := "https://pad.stratum0.org/p/dc" - fmt.Printf("Beginne mit der initialen URL: %s\n", initialURL) + fmt.Printf("Initiale URLs: %v\n", initialURLs) + fmt.Printf("Link Regex Pattern: %s\n", linkRegexPattern) fmt.Printf("Maximale Tiefe: %d\n", maxDepth) - toVisit := []struct { + toVisit := make([]struct { url string depth int - }{{initialURL, 0}} + }, len(initialURLs)) + + for i, url := range initialURLs { + toVisit[i] = struct { + url string + depth int + }{url, 0} + } + + totalURLs := len(toVisit) + bar := progressbar.Default(int64(totalURLs)) for len(toVisit) > 0 { current := toVisit[0] @@ -41,8 +56,12 @@ func main() { url string depth int }{link, current.depth + 1}) + totalURLs++ + bar.ChangeMax(totalURLs) } } + + bar.Add(1) } fmt.Println("\nAlle gefundenen Links:") @@ -77,13 +96,17 @@ func extractLinksFromPage(browser *rod.Browser, url string, depth int) []string fmt.Printf("Seite geladen: %s\n", url) + bar := progressbar.Default(100) + var newLinks []string - // Verarbeite die Hauptseite - newLinks = append(newLinks, extractLinks(page, url)...) + mainLinks := extractLinks(page, url) + newLinks = append(newLinks, mainLinks...) + bar.Add(50) - // Verarbeite die verschachtelten iFrames - newLinks = append(newLinks, processNestedIframes(page, url)...) + iframeLinks := processNestedIframes(page, url) + newLinks = append(newLinks, iframeLinks...) + bar.Add(50) return newLinks } @@ -91,32 +114,22 @@ func extractLinksFromPage(browser *rod.Browser, url string, depth int) []string func processNestedIframes(page *rod.Page, sourceURL string) []string { fmt.Printf("Suche nach äußerem iFrame auf %s\n", sourceURL) - // Finden Sie das erste iFrame-Element outerIframeElement := page.MustElement("#editorcontainer > iframe:nth-child(1)") - - // Wechseln Sie zum Kontext des ersten iFrames outerFrame := outerIframeElement.MustFrame() - - // Warten Sie, bis der Inhalt des ersten iFrames geladen ist outerFrame.MustWaitLoad() fmt.Printf("Äußeres iFrame geladen auf %s\n", sourceURL) - // Extrahiere Links aus dem äußeren iFrame outerLinks := extractLinks(outerFrame, sourceURL+" (äußeres iFrame)") fmt.Printf("Suche nach innerem iFrame auf %s\n", sourceURL) - // Finden Sie das zweite iFrame-Element innerhalb des ersten iFrames innerIframeElement := outerFrame.MustElement("#outerdocbody > iframe:nth-child(1)") - - // Wechseln Sie zum Kontext des zweiten iFrames innerFrame := innerIframeElement.MustFrame() innerFrame.MustWaitLoad() fmt.Printf("Inneres iFrame geladen auf %s\n", sourceURL) - // Extrahiere Links aus dem inneren iFrame innerLinks := extractLinks(innerFrame, sourceURL+" (inneres iFrame)") return append(outerLinks, innerLinks...) @@ -125,7 +138,7 @@ func processNestedIframes(page *rod.Page, sourceURL string) []string { func extractLinks(page *rod.Page, sourceURL string) []string { text := page.MustElement("body").MustText() - re := regexp.MustCompile(`https://pad\.stratum0\.org/p/dc[^\s"']+`) + re := regexp.MustCompile(linkRegexPattern) links := re.FindAllString(text, -1) fmt.Printf("Gefundene Links auf %s: %d\n", sourceURL, len(links))