Seite 1 von 1
RE und html...
Verfasst: Montag 6. August 2007, 17:24
von jens
Ich weiß normalerweise sollte man BeautifulSoup nehmen, hab ich aber nicht
Deswegen versuche ich es mit einer RE, aber es klappt nicht richtig:
Code: Alles auswählen
import re
txt = """...</form>
</fieldset>
<script language="javascript" type="text/javascript" src="/media/PyLucid/sha1.js"></script>
<script type="text/javascript">
debug_msg = true;
salt = 'dfe08';
challenge = 'debug';
submit_url = '.';
focus_id = 'plaintext_pass';
init();
</script>
</div>
<p id="footer">
powered by <a href="http://www.pylucid.org">PyLucid v0.8.0 alpha3SVN</a> | <a href="/_command/1/auth/login/">Log in</a> | Rendered in render time: 0.223 - overall: 0.2 - Queries: 16 sec. | last modified: 2007-06-26 01:30:09
</p>"""
regex = re.compile(r'<script [^>]+?(.+?)<\/script>(?uimx)')
print regex.findall(txt)
ich brauche die Zeilen aus dem Beispielcode:
Code: Alles auswählen
debug_msg = true;
salt = 'dfe08';
challenge = 'debug';
submit_url = '.';
focus_id = 'plaintext_pass';
init();
Meine RE trifft aber nur auf den ersten <script> Tag

Kann mir jemand helfen?
Verfasst: Montag 6. August 2007, 17:33
von jens
Ah, ich habs:
Code: Alles auswählen
regex1 = re.compile(
r'<script [^>]+?'
'(?P<code>.+?)'
'<\/script>'
'(?uisx)'
)
regex2 = re.compile(r'(.+?)=(.+?);')
JS_data = {}
for line in regex1.findall(txt):
for line2 in regex2.findall(line):
key, value = line2
key = key.strip(" '")
value = value.strip(" '")
JS_data[key] = value
print JS_data
Ausgabe:
Code: Alles auswählen
{'submit_url': '.', 'focus_id': 'plaintext_pass', 'debug_msg': 'true', 'salt': 'dfe08', 'challenge': 'debug'}
Schön ist es nicht, funktioniert aber... Könnte man sicherlich auch mit einigen Tricks mit einer einzigen RE lösen... Wenn jemand lust dazu hat, immer her damit

Verfasst: Montag 6. August 2007, 20:13
von HWK
Z.B. so:
Code: Alles auswählen
regex = re.compile(r'<script .+>\n?((.+\n?)+)</script>(?imux)')
MfG
HWK
Edit: Viel besser ist aber
Code: Alles auswählen
regex = re.compile(r'<script .+?>(.*?)</script>(?imuxs)')
Das entscheidende ist das s in (?imuxs) für DOTALL.
Verfasst: Montag 6. August 2007, 20:36
von EnTeQuAk
Und um den Wunsch nach einer möglichst kurzen Lösung zu stillen:
Code: Alles auswählen
In [40]: dict(
[(x.strip('\'"; '), y.strip('\'"; ')) for x, y in
[z.split('=') for z in re.compile(r'<script .+>\n?((.+\n?)+)</script>(?imux)').search(txt).group(1).split('\n') if len(z.split('='))>1]
]
)
Habe es nicht viel kürzer hinbekommen
MfG EnTeQuAk
Verfasst: Montag 6. August 2007, 21:17
von BlackJack
Es geht 20 Zeichen kürzer. Ich habe zum Vergleich aus Deiner Lösung alle überflüssigen Leerzeichen und Zeilenumbrüche entfernt.
Code: Alles auswählen
dict((x.strip('\'"; ') for x in y) for y in (z.split('=') for z in re.search(r'<script .+>\n?((.+\n?)+)</script>(?imux)', txt).group(1).split('\n') if len(z.split('='))>1))
Verfasst: Montag 6. August 2007, 22:25
von thelittlebug
Code: Alles auswählen
print dict(re.compile(r"(\w+)\s*=\s*['\"]*([^'\"]+)['\"]*;").findall(txt))
lgherby
Verfasst: Montag 6. August 2007, 23:02
von BlackJack
Da kann man noch das `compile()` rausnehmen:
Code: Alles auswählen
dict(re.findall(r"(\w+)\s*=\s*['\"]*([^'\"]+)['\"]*;", txt))
Verfasst: Dienstag 7. August 2007, 07:22
von jens
Perfekt. Danke euch... Trift zwar auf mehr Dinge in der HTML Datei zu, als nur die Teile innerhalb eines <script> Tags, aber für meinen Fall ist das egal.
Verfasst: Dienstag 7. August 2007, 12:31
von HWK
Jetzt sollte es nur auf den Inhalt eines <script>-Tags zutreffen. Ist zwar etwas länger, aber vielleicht doch interessant:
Code: Alles auswählen
[dict(re.findall(r'(\w+)\s*=\s*[\'"]*([^\'"]+)[\'"]*;', x))
for x in re.findall(r'<script .+?>(.*?)</script>(?imuxs)', txt)]
MfG
HWK
Verfasst: Montag 13. August 2007, 13:19
von jens
Thx. Ich hab es allerdings doch noch ein wenig Aufgebröselt:
Code: Alles auswählen
js_regex1 = re.compile(r'<script .+?>(.*?)</script>(?imuxs)')
js_regex2 = re.compile(r"(\w+)\s*=\s*['\"]*([^'\"]+)['\"]*;")
def _get_JS_data(content):
"""
retuned the JS variable statements from the given html page content.
"""
result = {}
for txt in js_regex1.findall(content):
data = dict(js_regex2.findall(txt))
result.update(data)
return result
Findet zwar eigentlich immer noch zuviel. Aber es stecken die wichtigen Daten drin

Verfasst: Montag 13. August 2007, 13:54
von BlackJack
Musst Du nur noch hoffen, dass nie Zeichenketten vorkommen, bei denen es Probleme mit Anführungszeichen geben kann. Also zum Beispiel 'O\'Reilly' oder 'The knights who say "Ni!"'.
