Hey Leute,
ich habe (wieder einmal) eine Frage wegen re...
Hier zum Problem: Ich habe einen String mit dem Quelltext einer zuvor geöffneten Seite. Ich möchte aus diesem String alle Links raussuchen(also nur die verlinkte Seite, nicht das ganze mit <a href=...> sondern nur die Seite hinter dem a href ). Das macht man ja normalerweise mit re.findall(). Dafür bin ich allerdings zu dumm... Könnt ihr mir da helfen? Die Links sollen am besten in einem Array gespeichert werden
Danke schonmal im Vorraus
PS: Ich möchte keine 3rd Party Module benutzen, also bitte empfehlt mir nicht Beautiyful Soup und co...
Nach Links suchen
Bei re.findall() werden die Treffer schon als Array gespeichert.Stegi95 hat geschrieben:Hey Leute,
ich habe (wieder einmal) eine Frage wegen re...
Hier zum Problem: Ich habe einen String mit dem Quelltext einer zuvor geöffneten Seite. Ich möchte aus diesem String alle Links raussuchen(also nur die verlinkte Seite, nicht das ganze mit <a href=...> sondern nur die Seite hinter dem a href ). Das macht man ja normalerweise mit re.findall(). Dafür bin ich allerdings zu dumm... Könnt ihr mir da helfen? Die Links sollen am besten in einem Array gespeichert werden
Du könntest sowas in der Art machen:
Code: Alles auswählen
re.findall('<a .* href=".*"', source_code)
Hallo
Vielleicht solltest du dann besser gleich:
nehmen.
Gruß Karo
Vielleicht solltest du dann besser gleich:
Code: Alles auswählen
re.findall(r'''a href="(.+?)">''', seiten_quelltext)
Gruß Karo
Eigentlich kann man mit regulären Ausdrücken nicht vernünftig HTML parsen. Wenn du weißt, dass deine Eingabe gültiges XHTML ist, könntest du Pythons eingebauten XML-Parser benutzen. Reguläre Ausdrücke können nur ein Notbehelf sein. Hier ein Beispiel für Python 3.1. Beachte, dass die gefundene URL noch Entities (z.B. &) enthalten kann, die noch entfernt werden müssten.
Stefan
Code: Alles auswählen
import re, urllib.request
from urllib.parse import urljoin
b = "http://python-forum.de"
s = urllib.request.urlopen(b).read().decode('utf-8')
def get_a(b, s):
for m in re.finditer(r"""(?is)<a[^>]*href[\s\n]*=[\s\n]*("[^"]*"|'[^']*')""", s):
yield urljoin(b, m.group(1)[1:-1])
print(list(get_a(b, s)))
Zuletzt geändert von sma am Samstag 20. November 2010, 11:30, insgesamt 1-mal geändert.
@OP: "lxml.html" sollte dennoch erwähnt werden, auch wenn Du keine Drittmodule nutzen möchtest. Es ist die beste Lösung zur Arbeit mit HTML, und bietet insbesondere auch komfortable Methoden für Verarbeitung von Links.
Uh, wow. Mit nem XML-Parser geht das ja super! Aber natürlich nur für valides XML
Code: Alles auswählen
import xml.parsers.expat
def start_element(name, attrs):
if name == 'a':
links.append(attrs['href'])
links = []
p = xml.parsers.expat.ParserCreate()
p.StartElementHandler = start_element
with open("irgendeine_datei.xml", "r") as f:
p.Parse(f.read())
Ist auch in diesem Fall kein guter Tipp, denn alles DOM-artige saugt sich das gesamte Dokument in den Hauptspeicher, was zum Finden von a[href] nun wirklich nicht notwendig ist. Hier ist das SAX-API auch nicht wirklich kompliziert zu benutzen.nomnom hat geschrieben:Wieso denn? Tu ich nicht, wenn mir nicht gesagt wird wiesolunar hat geschrieben:@nomnom: Verwende statt expat, sax oder minidom doch ElementTree.
Stefan
@nomnom: Die `ElementTree`-API ist nicht so ekelig Java-artig.
@sma: Die `iterparse()`-Funktion legt kein DOM an.
Edit: So könnte das ohne DOM mit `ElementTree` aussehen:
@sma: Die `iterparse()`-Funktion legt kein DOM an.
Edit: So könnte das ohne DOM mit `ElementTree` aussehen:
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from xml.etree import ElementTree as etree
def main():
result = list()
for _type, node in etree.iterparse('test.xml', ['start']):
if node.tag == 'a':
result.append(node.get('href'))
print result
if __name__ == '__main__':
main()
@sma
Mit deiner Methode klappt es bestens
Aber, was kann ich tun, wenn ich nicht weiß, ob die Seite valides XHTML ist? Wenn ich zum Beispiel die Seiten automatisch aufrufen lasse, und dann scnnen lasse...dann weiß ich ja nicht, ob es gutes, reines XHTML ist.
Danke aber schonmal an alle, das geht wirklich fix hier
Mit deiner Methode klappt es bestens
Aber, was kann ich tun, wenn ich nicht weiß, ob die Seite valides XHTML ist? Wenn ich zum Beispiel die Seiten automatisch aufrufen lasse, und dann scnnen lasse...dann weiß ich ja nicht, ob es gutes, reines XHTML ist.
Danke aber schonmal an alle, das geht wirklich fix hier
@Lunar und BlackJack:Ja, ist kürzer und schöner, stimmt
Code: Alles auswählen
import xml.etree.ElementTree
tree = xml.etree.ElementTree.parse("beispiel.xml")
links = tree.getiterator("a")
for link in links:
print link.get("href")
Ein nicht valides XML-Dokument muss einen validierenden XML-Parser einen Fehler werfen lassen. Daran kann man's dann erkennen. Nützen tut es natürlich recht wenig, wenn man trotzdem die Links ermitteln will. Dann hilft vielleicht immer noch der reguläre Ausdruck.Stegi95 hat geschrieben:Aber, was kann ich tun, wenn ich nicht weiß, ob die Seite valides XHTML ist? Wenn ich zum Beispiel die Seiten automatisch aufrufen lasse, und dann scnnen lasse...dann weiß ich ja nicht, ob es gutes, reines XHTML ist.
Stefan
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
Ja. Oder echt mal lxml.html oder zumindest html5lib nutzen. Letztere benötigt auch keinen C-Code, kann also der Applikation zur Not mitgeliefert werden.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice