parsen oder filtern

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
The Hit-Man
User
Beiträge: 407
Registriert: Montag 20. Februar 2006, 18:11
Wohnort: Menden / Sauerland
Kontaktdaten:

Samstag 3. Mai 2008, 13:42

Der Weg mit dem Zählen der <td> ist aber recht unpraktisch, weil er vermutlich schon bei kleineren Änderungen an der Seite nicht funktioniert.
die könnten auch eben nen anderen namen, für das bildchen nehmen, würde mein messenger auch nicht mehr gehen. leider muß man damit rechnen :( allerdings habe ich bis jetzt noch nicht gesehen, das die an dem source was geändert hätten. ich denke auch mal, werden sie auch erst mal nicht machen, weil lohnt auch nicht weiter. der chat rennt ja.
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Samstag 3. Mai 2008, 14:11

The Hit-Man hat geschrieben:die könnten auch eben nen anderen namen, für das bildchen nehmen, würde mein messenger auch nicht mehr gehen.
Natürlich. Beim scrapen geht es eben um Warscheinlichkeiten. Es ist wohl warscheinlicher, dass sie ein weiteres <td> einfügen (etwa um eine Box mit Breaking News einzufügen, irgendwie so etwas) als dass sie das Bild umbenennen. Kann natürlich beides vorkommen - scraping funktioniert eben nur so lange gut, bis die Seite die gescraped wird geändert wird.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
The Hit-Man
User
Beiträge: 407
Registriert: Montag 20. Februar 2006, 18:11
Wohnort: Menden / Sauerland
Kontaktdaten:

Montag 2. Juni 2008, 10:56

@Leondias
wäre es auch möglich, das ich beautifulsoup für das suchen nehmen könnte? und wenn, wird es genau so einfach benutzt wie die html5lib. hatte mir die doku zu beautifulsoup mal angeschaut, allerdings fand ich kein gutes beispiel, wie hier, mit der html5lib.

EDIT:

Code: Alles auswählen

soup = BeautifulSoup(page)
print soup.html.findAll('td')
habs so erst mal versucht. nur jetzt bekomme ich ja alle tags angezeigt, ich möchte aber nur einen bestimmten, am besten das ich ihm sagen könnte, den 21zigste.
BlackJack

Montag 2. Juni 2008, 12:44

Na das wäre dann

Code: Alles auswählen

print soup.html.findAll('td')[20]
Ist aber wahrscheinlich nicht so besonders robust. Ich würde versuchen das etwas genauer zu beschreiben. Also zum Beispiel erst einmal die Tabelle identifizieren und dabei auch Gebrauch von eventuellen IDs machen.
The Hit-Man
User
Beiträge: 407
Registriert: Montag 20. Februar 2006, 18:11
Wohnort: Menden / Sauerland
Kontaktdaten:

Montag 2. Juni 2008, 12:46

habs jetzt so hinbekommen, das mir auch der wert gleich ausgelesen wird

Code: Alles auswählen

soup = BeautifulSoup(page)
extract1 = soup.html.findAll('td')
print extract1[31].contents[0]
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Montag 2. Juni 2008, 13:57

The Hit-Man hat geschrieben:wäre es auch möglich, das ich beautifulsoup für das suchen nehmen könnte?
Ja, kannst du aber für mich verhält sich das zu "seltsam", dss dann Sachen manchmal schlichtweg nicht funktionieren und es dann seltsame Hacks braucht. Außerdem ist eben das Ablaufen der Indizes nicht wirklich robust, da nehme ich mir lieber einen Selektor oder ein XPath-Query gegen ein Objekt von dem ich meine dass es eher beständig ist.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
The Hit-Man
User
Beiträge: 407
Registriert: Montag 20. Februar 2006, 18:11
Wohnort: Menden / Sauerland
Kontaktdaten:

Mittwoch 4. Juni 2008, 15:35

@Leondias

Code: Alles auswählen

soup = BeautifulSoup(page)
extract1 = soup.html.findAll('td')
print extract1[31].contents[0]
so bekomme ich das 30zigste Element angezeigt, aber wie kann ich feststellen, wieviele Elemente jetzt vorhanden sind, im extract1 ??? Muß das wissen, da ich ein Listfeld füllen möchte.
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Mittwoch 4. Juni 2008, 15:46

Code: Alles auswählen

print len(extract1)
Also etwas Eigeninitiative würde dir nicht schaden :P
My god, it's full of CARs! | Leonidasvoice vs Modvoice
The Hit-Man
User
Beiträge: 407
Registriert: Montag 20. Februar 2006, 18:11
Wohnort: Menden / Sauerland
Kontaktdaten:

Mittwoch 4. Juni 2008, 15:57

argh, und ich google mich dumm und dämlich. Also in der Doku habe ich nichts darüber gefunden.
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Mittwoch 4. Juni 2008, 16:51

The Hit-Man hat geschrieben:Also in der Doku habe ich nichts darüber gefunden.
Tutorial: Lists. Die meisten Dinge auf die du per Index zugreifen kannst, können dir auch ihre Länge sagen, indem du mit ``len()`` auf ihr ``__len__`` zugreifst.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
The Hit-Man
User
Beiträge: 407
Registriert: Montag 20. Februar 2006, 18:11
Wohnort: Menden / Sauerland
Kontaktdaten:

Donnerstag 5. Juni 2008, 08:18

naja, das wird schon. ich mache ja eher learning by doing. Denk mal ein paar Monate zurück, da konnte ich ja mal gar nichts. Deshalb noch mal vielen Dank an das Forum und die Leute die mir immer helfen. Ich werde bestimmt noch ganz viele Fragen haben.
The Hit-Man
User
Beiträge: 407
Registriert: Montag 20. Februar 2006, 18:11
Wohnort: Menden / Sauerland
Kontaktdaten:

Donnerstag 5. Juni 2008, 14:42

da stehe ich schon wieder. hab so weit geschafft, eine seite parsen, um mir anzeigen zu lassen, welche Leute gerade online sind. Jetzt bekomme ich eine Liste mit solchen Einträgen zurück.

Code: Alles auswählen

</tr>, <tr onclick="open_profil_by_id(1152110);"><td width="20"></td><td width="15" class="norm">20</td><td class="pic" onmouseover="mouseIn(this)" onmouseout="mouseOut(this)">nomani</td>
Jetzt brauche ich nur hinten das nmani, denn das sind die reinen Benutzernamen, die ich in mein Listfeld unterbringen möchte, mein bisheriger Befehl zum filtern lautete:

Code: Alles auswählen

result = soup.html.findAll('tr')
Gibt es da ne Möglichkeit, nur den Nicknamen auszulesen, unter BeautifulSoup? Oder eine Komination, mit meiner Suche?
BlackJack

Donnerstag 5. Juni 2008, 15:04

Natürlich gibt's da eine Möglichkeit, aber Du solltest vielleicht wirklich mal HTML und BeautifulSoup lernen, dann wüsstest Du das auch. Ein HTML-Dokument kann man sich als Baum mit Knoten und Attributen vorstellen, viele HTML-Editoren und auch Browser haben auch eine entsprechende Darstellung, und mit BeatifulSoup kann man sich daraus Knoten heraus filtern und von Knoten zu Eltern oder Kindknoten navigieren. Das heisst Du musst Dir nur anschauen wie man die gewünschten Knoten am besten und sichersten ansteuern kann.

Bei den gegebenen Informationen scheinen das also <tr>-Knoten zu sein, deren `onclick`-Attribut mit 'open_profil_by_id' beginnt. Und wenn man die hat, kann man bei jedem dieser Knoten den <td>-Knoten mit dem `class`-Attribut 'pic' identifizieren und dessen Kindknoten, den Text, auslesen.

Code: Alles auswählen

    rows = soup('tr', onclick=lambda v: v.startswith('open_profil_by_id'))
    names = [row.find('td', 'pic').contents[0] for row in rows]
Man sollte vielleicht nicht beim `soup`-Objekt beginnen, sondern erst einmal die Tabelle ansteuern.
The Hit-Man
User
Beiträge: 407
Registriert: Montag 20. Februar 2006, 18:11
Wohnort: Menden / Sauerland
Kontaktdaten:

Donnerstag 5. Juni 2008, 15:12

stecke leider noch in den Anfängen und habe mir auch die Doku auf der Homepage durchgelesen. Irgendwie immer alle zu trocken. Ihr erkärt es irgendwie besser. Klar weiß ich wie eine HTML Seite ungefähr aufgebaut ist, und kann mir auch den Baum vorstellen, wie eine XML Datei, nur eben mit Tabellen und so weiter. Ist nicht so, das ich hier wegen jeder kleinen Sache eine Frage stellen würde ( vielleicht sieht es für Euch so aus, da ihr ja bei weitem mehr Ahnung davon habt, wie ich ). Bevor ich Frage, google ich und suche erst im Forum nach, was passen könnte. Ich denke mal meine Fragen, sind irgendwie zu speziell ;)

EDIT:
by the way, das lambda verwirrt mich.
BlackJack

Donnerstag 5. Juni 2008, 19:08

Das ist einfach eine Funktion ohne Namen. Man hätte auch extra eine Funktion mit ``def`` vorher definieren können und dann beim Aufruf den Namen angeben.
Antworten