robots.txt mit RE durchsuchen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
to.ni
User
Beiträge: 24
Registriert: Dienstag 6. Januar 2004, 15:52

Hallo Forum,

wie gesagt möchte ich robots.txt-Dateien mit Regulären-Ausdrücken durchsuchen. Habe da schon etwas gebastelt, aber leider funktioniert es nicht zu 100%:

Eine klassiche robots.txt:

Code: Alles auswählen

User-agent: *
Disallow: /verzeichnis1/
Disallow: /verzeichnis2/
Meine bisherige RE:

Code: Alles auswählen

regex = re.compile("user-agent\s*:\s*\*(?:\s*disallow\s*:\s*(.*))*", re.IGNORECASE)
print regex.search(robots_txt).groups()
Also so sollte gesucht werden:
- Zunächst nach "user-agent"
- Gefolgt von 0 oder mehreren Leerzeichen/Tabs
- Dann der Doppelpunkt (:)
- Gefolgt von 0 oder mehreren Leerzeichen/Tabs
- Dann kommt der * (Der Stern steht in der robots.txt für jeden Roboter)
(Soweit funktioniert alles wie es soll)
(Hier folgen jetzt in der Regel ein oder mehrere Zeilenumbrüche...)
- Als nächstes wird nach 0 oder mehreren Leerzeichen gesucht
- Jetzt wird nach "disallow" gesucht
- Wieder 0 oder mehr Leerzeichen
- Wieder Doppelpunkt (:)
- Wieder 0 oder mehr Leerzeichen
- jetzt Kommt endlich der Verzeichnisname. Dieser steht in Klammern, da ich im Endeffekt nur eine Liste der Verzeichnisse haben möchte.

Theoretisch funktioniert das Suchmuster. Mein einziges Problem ist, dass ich immer nur den letzten Verzeichnisnamen bekomme und sonst keine. Ich dachte eigentlich, dass ich das mit dem * am Ende lösen könnte, aber das funktioniert nicht.

Bin für jede Hilfe dankbar. Wenn was unklar ist, einfach fragen...
Danke und vg to.ni
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Hi to.ni,

nimm statt search findall.
Du kannst auch den Pattern vereinfachen:

Code: Alles auswählen

>>> a = """
... User-agent: *
... Disallow: /verzeichnis1/
... Disallow: /verzeichnis2/
... """
>>> import re
>>> regex = re.compile("Disallow:\s*(.*)",re.IGNORECASE)
>>> print regex.findall(a)
['/verzeichnis1/', '/verzeichnis2/ ']

Gruß

Dookie
to.ni
User
Beiträge: 24
Registriert: Dienstag 6. Januar 2004, 15:52

Hallo Dookie,

zunächst mal Danke für die Schnelle Antwort :)

Aber ganz so kann ich es nicht vereinfachen, da in der robots.txt auch Roboter direkt angesprochen werden können, z.B.

Code: Alles auswählen

User-agent: googlebot
Dissalow: 

User-agent: *
Dissalow: /
Und wenn ich jetzt nach Dissalow suche, bekomme ich zuerst "nichts verboten" und dann "alles verboten", da es sich ja auf verschiedene Roboter bezieht (Google darf alles durchsuchen, jeder andere nichts).

Wenn ich in meiner jetzigen RE mit .findall arbeite, finde ich auch nur das letzte Verzeichnis.

Kann ich überhaupt mit einer einzigen RE arbeiten, oder muss ich mehrere einsetzen?

mfg
to.ni
Milan
User
Beiträge: 1078
Registriert: Mittwoch 16. Oktober 2002, 20:52

Hi. Ich denke mal, mit einer einzigen RE wird es schwierig... Deine RE ist ok und findet auch alles was sie soll, aber das .groups() hat es in sich. Damit wird leider nur die letzte erkannte GRuppe zurückgegeben. Ich würde mir zwei RE's machen und dann folgendermaßen vorgehen: erst alle Disallows finden, die erwünscht sind und dann aus diesen Einzelstrings die Verzeichnisse rausholen. Also so in etwa (ungetestet):

Code: Alles auswählen

import re
regex1 = re.compile("user-agent\s*:\s*\*(?:\s*disallow\s*:\s*(?:.*))+", re.I) 
regex2 = re.compile("Disallow:\s*(.+)",re.I)
erglist=[]
teilerg=regex1.findall(text)
for i in teilerg:
    erglist.extend(regex2.findall(i))
Milan
to.ni
User
Beiträge: 24
Registriert: Dienstag 6. Januar 2004, 15:52

hey super,

das funktioniert einwandfrei.

Thanks :D
Milan
User
Beiträge: 1078
Registriert: Mittwoch 16. Oktober 2002, 20:52

Hm, vielleicht nimmst du lieber das hier, es ist effizienter:

Code: Alles auswählen

import re 
regex1 = re.compile("user-agent\s*:\s*\*(?:\s*disallow\s*:\s*.*)+", re.I) 
regex2 = re.compile("disallow:\s*(.+)",re.I) 
erglist=regex2.findall(("\n").join(regex1.findall(text)))
Antworten