add progress bar and variables
This commit is contained in:
parent
77d6e3bcd7
commit
66691780ea
4 changed files with 78 additions and 56 deletions
60
README.md
60
README.md
|
@ -1,21 +1,23 @@
|
||||||
# Pad Stratum0 Link Extractor
|
# Universal Link Extractor for Etherpad Lite
|
||||||
|
|
||||||
## Beschreibung
|
## 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.
|
- Extrahiert Links von einer oder mehreren initialen URLs
|
||||||
- Navigiert durch verschachtelte iFrames, um versteckte Links zu finden.
|
- Navigiert rekursiv durch gefundene Links bis zu einer konfigurierbaren maximalen Tiefe
|
||||||
- Vermeidet doppelte Besuche von URLs.
|
- Durchsucht verschachtelte iFrames, um versteckte Links zu finden
|
||||||
- Bietet detaillierte Konsolenausgaben über den Fortschritt des Scrapings.
|
- Vermeidet doppelte Besuche von URLs
|
||||||
- Sammelt Statistiken über gefundene und besuchte Links.
|
- Bietet eine Fortschrittsanzeige für den Extraktionsprozess
|
||||||
|
- Sammelt und zeigt Statistiken über gefundene und besuchte Links
|
||||||
|
|
||||||
## Voraussetzungen
|
## Voraussetzungen
|
||||||
|
|
||||||
- Go 1.16 oder höher
|
- Go 1.16 oder höher
|
||||||
- go-rod Bibliothek
|
- go-rod Bibliothek
|
||||||
|
- progressbar/v3 Bibliothek
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
|
@ -23,8 +25,8 @@ Dieses Go-Programm ist ein spezialisierter Web Scraper, der entwickelt wurde, um
|
||||||
|
|
||||||
2. Klonen Sie das Repository:
|
2. Klonen Sie das Repository:
|
||||||
```
|
```
|
||||||
git clone https://github.com/yourusername/pad-stratum0-link-extractor.git
|
git clone https://github.com/yourusername/universal-link-extractor-etherpad.git
|
||||||
cd pad-stratum0-link-extractor
|
cd universal-link-extractor-etherpad
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Installieren Sie die erforderlichen Abhängigkeiten:
|
3. Installieren Sie die erforderlichen Abhängigkeiten:
|
||||||
|
@ -34,10 +36,12 @@ Dieses Go-Programm ist ein spezialisierter Web Scraper, der entwickelt wurde, um
|
||||||
|
|
||||||
## Konfiguration
|
## 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
|
```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
|
## Verwendung
|
||||||
|
@ -47,13 +51,13 @@ maxDepth = 3 // Ändern Sie diesen Wert nach Bedarf
|
||||||
go run main.go
|
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
|
## Ausgabe
|
||||||
|
|
||||||
Das Programm gibt folgende Informationen aus:
|
Das Programm liefert folgende Informationen:
|
||||||
|
|
||||||
- Fortschrittsmeldungen für jede verarbeitete URL
|
- Fortschrittsmeldungen für jede verarbeitete URL
|
||||||
- Informationen über gefundene und geladene iFrames
|
- Informationen über gefundene und geladene iFrames
|
||||||
|
@ -62,32 +66,14 @@ Das Programm gibt folgende Informationen aus:
|
||||||
|
|
||||||
## Anpassung
|
## Anpassung
|
||||||
|
|
||||||
- Um andere Websites zu scrapen, passen Sie die initiale URL und den regulären Ausdruck für die Link-Erkennung an.
|
- Um andere Etherpad Lite Instanzen zu durchsuchen, passen Sie die `initialURLs` und `linkRegexPattern` an.
|
||||||
- Für komplexere Scraping-Logik können Sie die `extractLinks` Funktion modifizieren.
|
- Für komplexere Extraktionslogik können Sie die `extractLinks` Funktion modifizieren.
|
||||||
|
|
||||||
## Fehlerbehebung
|
## Fehlerbehebung
|
||||||
|
|
||||||
- Wenn Sie Probleme mit dem Laden von iFrames haben, überprüfen Sie die CSS-Selektoren in der `processNestedIframes` Funktion.
|
- Bei Problemen mit dem Laden von iFrames ü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.
|
- Wenn Sie Timeout-Probleme haben, passen Sie die `MustWaitLoad` Aufrufe an oder fügen Sie zusätzliche Wartezeiten ein.
|
||||||
|
|
||||||
## Beitrag
|
## Beitrag
|
||||||
|
|
||||||
Beiträge zum Projekt sind willkommen. Bitte öffnen Sie ein Issue oder einen Pull Request für Vorschläge oder Verbesserungen.
|
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
|
|
||||||
|
|
5
go.mod
5
go.mod
|
@ -5,9 +5,14 @@ go 1.19
|
||||||
require github.com/go-rod/rod v0.116.2
|
require github.com/go-rod/rod v0.116.2
|
||||||
|
|
||||||
require (
|
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/fetchup v0.2.3 // indirect
|
||||||
github.com/ysmood/goob v0.4.0 // indirect
|
github.com/ysmood/goob v0.4.0 // indirect
|
||||||
github.com/ysmood/got v0.40.0 // indirect
|
github.com/ysmood/got v0.40.0 // indirect
|
||||||
github.com/ysmood/gson v0.7.3 // indirect
|
github.com/ysmood/gson v0.7.3 // indirect
|
||||||
github.com/ysmood/leakless v0.9.0 // 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
|
||||||
)
|
)
|
||||||
|
|
18
go.sum
18
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 h1:A5t2Ky2A+5eD/ZJQr1EfsQSe5rms5Xof/qj296e+ZqA=
|
||||||
github.com/go-rod/rod v0.116.2/go.mod h1:H+CMO9SCNc2TJ2WfrG+pKhITz57uGNYU43qYHh438Mg=
|
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 h1:ulX+SonA0Vma5zUFXtv52Kzip/xe7aj4vqT5AJwQ+ZQ=
|
||||||
github.com/ysmood/fetchup v0.2.3/go.mod h1:xhibcRKziSvol0H1/pj33dnKrYyI2ebIvz5cOOkYGns=
|
github.com/ysmood/fetchup v0.2.3/go.mod h1:xhibcRKziSvol0H1/pj33dnKrYyI2ebIvz5cOOkYGns=
|
||||||
github.com/ysmood/goob v0.4.0 h1:HsxXhyLBeGzWXnqVKtmT9qM7EuVs/XOgkX7T6r1o1AQ=
|
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/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 h1:qxCG5VirSBvmi3uynXFkcnLMzkphdh3xx5FtrORwDCU=
|
||||||
github.com/ysmood/leakless v0.9.0/go.mod h1:R8iAXPRaG97QJwqxs74RdwzcRHT1SWCGTNqY8q0JvMQ=
|
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=
|
||||||
|
|
51
scraper.go
51
scraper.go
|
@ -5,12 +5,17 @@ import (
|
||||||
"regexp"
|
"regexp"
|
||||||
"time"
|
"time"
|
||||||
"github.com/go-rod/rod"
|
"github.com/go-rod/rod"
|
||||||
|
"github.com/schollz/progressbar/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
visitedURLs = make(map[string]bool)
|
visitedURLs = make(map[string]bool)
|
||||||
allLinks = make(map[string]bool)
|
allLinks = make(map[string]bool)
|
||||||
maxDepth = 3 // Hier können Sie die maximale Tiefe festlegen
|
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() {
|
func main() {
|
||||||
|
@ -20,14 +25,24 @@ func main() {
|
||||||
browser := rod.New().MustConnect()
|
browser := rod.New().MustConnect()
|
||||||
defer browser.MustClose()
|
defer browser.MustClose()
|
||||||
|
|
||||||
initialURL := "https://pad.stratum0.org/p/dc"
|
fmt.Printf("Initiale URLs: %v\n", initialURLs)
|
||||||
fmt.Printf("Beginne mit der initialen URL: %s\n", initialURL)
|
fmt.Printf("Link Regex Pattern: %s\n", linkRegexPattern)
|
||||||
fmt.Printf("Maximale Tiefe: %d\n", maxDepth)
|
fmt.Printf("Maximale Tiefe: %d\n", maxDepth)
|
||||||
|
|
||||||
toVisit := []struct {
|
toVisit := make([]struct {
|
||||||
url string
|
url string
|
||||||
depth int
|
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 {
|
for len(toVisit) > 0 {
|
||||||
current := toVisit[0]
|
current := toVisit[0]
|
||||||
|
@ -41,8 +56,12 @@ func main() {
|
||||||
url string
|
url string
|
||||||
depth int
|
depth int
|
||||||
}{link, current.depth + 1})
|
}{link, current.depth + 1})
|
||||||
|
totalURLs++
|
||||||
|
bar.ChangeMax(totalURLs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bar.Add(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("\nAlle gefundenen Links:")
|
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)
|
fmt.Printf("Seite geladen: %s\n", url)
|
||||||
|
|
||||||
|
bar := progressbar.Default(100)
|
||||||
|
|
||||||
var newLinks []string
|
var newLinks []string
|
||||||
|
|
||||||
// Verarbeite die Hauptseite
|
mainLinks := extractLinks(page, url)
|
||||||
newLinks = append(newLinks, extractLinks(page, url)...)
|
newLinks = append(newLinks, mainLinks...)
|
||||||
|
bar.Add(50)
|
||||||
|
|
||||||
// Verarbeite die verschachtelten iFrames
|
iframeLinks := processNestedIframes(page, url)
|
||||||
newLinks = append(newLinks, processNestedIframes(page, url)...)
|
newLinks = append(newLinks, iframeLinks...)
|
||||||
|
bar.Add(50)
|
||||||
|
|
||||||
return newLinks
|
return newLinks
|
||||||
}
|
}
|
||||||
|
@ -91,32 +114,22 @@ func extractLinksFromPage(browser *rod.Browser, url string, depth int) []string
|
||||||
func processNestedIframes(page *rod.Page, sourceURL string) []string {
|
func processNestedIframes(page *rod.Page, sourceURL string) []string {
|
||||||
fmt.Printf("Suche nach äußerem iFrame auf %s\n", sourceURL)
|
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)")
|
outerIframeElement := page.MustElement("#editorcontainer > iframe:nth-child(1)")
|
||||||
|
|
||||||
// Wechseln Sie zum Kontext des ersten iFrames
|
|
||||||
outerFrame := outerIframeElement.MustFrame()
|
outerFrame := outerIframeElement.MustFrame()
|
||||||
|
|
||||||
// Warten Sie, bis der Inhalt des ersten iFrames geladen ist
|
|
||||||
outerFrame.MustWaitLoad()
|
outerFrame.MustWaitLoad()
|
||||||
|
|
||||||
fmt.Printf("Äußeres iFrame geladen auf %s\n", sourceURL)
|
fmt.Printf("Äußeres iFrame geladen auf %s\n", sourceURL)
|
||||||
|
|
||||||
// Extrahiere Links aus dem äußeren iFrame
|
|
||||||
outerLinks := extractLinks(outerFrame, sourceURL+" (äußeres iFrame)")
|
outerLinks := extractLinks(outerFrame, sourceURL+" (äußeres iFrame)")
|
||||||
|
|
||||||
fmt.Printf("Suche nach innerem iFrame auf %s\n", sourceURL)
|
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)")
|
innerIframeElement := outerFrame.MustElement("#outerdocbody > iframe:nth-child(1)")
|
||||||
|
|
||||||
// Wechseln Sie zum Kontext des zweiten iFrames
|
|
||||||
innerFrame := innerIframeElement.MustFrame()
|
innerFrame := innerIframeElement.MustFrame()
|
||||||
innerFrame.MustWaitLoad()
|
innerFrame.MustWaitLoad()
|
||||||
|
|
||||||
fmt.Printf("Inneres iFrame geladen auf %s\n", sourceURL)
|
fmt.Printf("Inneres iFrame geladen auf %s\n", sourceURL)
|
||||||
|
|
||||||
// Extrahiere Links aus dem inneren iFrame
|
|
||||||
innerLinks := extractLinks(innerFrame, sourceURL+" (inneres iFrame)")
|
innerLinks := extractLinks(innerFrame, sourceURL+" (inneres iFrame)")
|
||||||
|
|
||||||
return append(outerLinks, innerLinks...)
|
return append(outerLinks, innerLinks...)
|
||||||
|
@ -125,7 +138,7 @@ func processNestedIframes(page *rod.Page, sourceURL string) []string {
|
||||||
func extractLinks(page *rod.Page, sourceURL string) []string {
|
func extractLinks(page *rod.Page, sourceURL string) []string {
|
||||||
text := page.MustElement("body").MustText()
|
text := page.MustElement("body").MustText()
|
||||||
|
|
||||||
re := regexp.MustCompile(`https://pad\.stratum0\.org/p/dc[^\s"']+`)
|
re := regexp.MustCompile(linkRegexPattern)
|
||||||
links := re.FindAllString(text, -1)
|
links := re.FindAllString(text, -1)
|
||||||
|
|
||||||
fmt.Printf("Gefundene Links auf %s: %d\n", sourceURL, len(links))
|
fmt.Printf("Gefundene Links auf %s: %d\n", sourceURL, len(links))
|
||||||
|
|
Loading…
Reference in a new issue