Seite 1 von 1

Nach Links suchen

Verfasst: Samstag 20. November 2010, 09:36
von Stegi95
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...

Re: Nach Links suchen

Verfasst: Samstag 20. November 2010, 10:44
von nomnom
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 ;)
Bei re.findall() werden die Treffer schon als Array gespeichert.
Du könntest sowas in der Art machen:

Code: Alles auswählen

re.findall('<a .* href=".*"', source_code)
Musst halt noch den Rest wegmachen (<a href=")

Re: Nach Links suchen

Verfasst: Samstag 20. November 2010, 11:09
von karolus
Hallo

Vielleicht solltest du dann besser gleich:

Code: Alles auswählen

re.findall(r'''a href="(.+?)">''', seiten_quelltext)
nehmen.

Gruß Karo

Re: Nach Links suchen

Verfasst: Samstag 20. November 2010, 11:25
von sma
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.

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)))
Stefan

Re: Nach Links suchen

Verfasst: Samstag 20. November 2010, 11:28
von lunar
@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.

Re: Nach Links suchen

Verfasst: Samstag 20. November 2010, 13:01
von nomnom
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())

Re: Nach Links suchen

Verfasst: Samstag 20. November 2010, 13:20
von lunar
@nomnom: Verwende statt expat, sax oder minidom doch ElementTree.

Re: Nach Links suchen

Verfasst: Samstag 20. November 2010, 13:30
von nomnom
lunar hat geschrieben:@nomnom: Verwende statt expat, sax oder minidom doch ElementTree.
Wieso denn? Tu ich nicht, wenn mir nicht gesagt wird wieso ;)

Re: Nach Links suchen

Verfasst: Samstag 20. November 2010, 13:34
von sma
nomnom hat geschrieben:
lunar hat geschrieben:@nomnom: Verwende statt expat, sax oder minidom doch ElementTree.
Wieso denn? Tu ich nicht, wenn mir nicht gesagt wird wieso ;)
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.

Stefan

Re: Nach Links suchen

Verfasst: Samstag 20. November 2010, 13:43
von BlackJack
@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:

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()

Re: Nach Links suchen

Verfasst: Samstag 20. November 2010, 13:52
von Stegi95
@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

Re: Nach Links suchen

Verfasst: Samstag 20. November 2010, 14:13
von nomnom
@Lunar und BlackJack:

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")
Ja, ist kürzer und schöner, stimmt

Re: Nach Links suchen

Verfasst: Samstag 20. November 2010, 14:18
von sma
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.
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.

Stefan

Re: Nach Links suchen

Verfasst: Samstag 20. November 2010, 14:28
von Stegi95
Also macht man mit Exeptions, oder? Ich kenn mich da noch nicht sooo mit aus...

Re: Nach Links suchen

Verfasst: Sonntag 21. November 2010, 02:16
von Leonidas
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.