re.findall URL?

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
2.0.0.4
User
Beiträge: 8
Registriert: Mittwoch 4. Dezember 2013, 10:18

hallo zusammen,
beschäftige mich seit einigen wochen mit Python - steche vor den folgenden Problem

möchte eine Seite durchsuchen - - und mir den gefundenen wert abspeichern

Code: Alles auswählen

import urllib2
import re

response = urllib2.urlopen('http://vk.com/friends?id=xxxxxxx&section=all')
html = response.read(20000)

datei=file('.../Privat/datei.txt','a')
textliste = html
datei.writelines(textliste)
datei.flush()
a = re.search('rexto', html)
datei=file('/Users/alex/Dropbox/Privat/Programmieren/datei.txt','r')
inhalt = datei.readlines()

a = re.findall( '\s*"\s*res\s*(\d{9})\s*"\s*>\s*<',html,re.IGNORECASE)
print a

das erste Problem ist das die seite die er sich runter zieht nicht die ist die ich im Browser als Quelltext angezeigt bekomme.


das andere ist er findet mir nicht die stellen die ich suche.

hat da einer ein Idee für mich?


Mfg
Alex
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

2.0.0.4 hat geschrieben:

Code: Alles auswählen

datei=file('.../Privat/datei.txt','a')
textliste = html
datei.writelines(textliste)
datei.flush()
Ich gehe mal kurz auf dieses Codestück ein. Dateien mit file zu öffnen ist eher ungewöhnlich und nicht empfohlen. Verwende stattdessen open. textliste ist überflüssig. Du führst ein flush durch, schließt die Datei aber nicht. Prinzipiell kannst du dir hier das flush() schenken. Um das Schließen nicht zu vergessen bietet sich die Verwendung eines Context Managers mit dem Einsatz von with an, da damit das Schließen automatisch erfolgt.

Der Code reduziert sich damit auf Folgendes und ist auch noch robuster.

Code: Alles auswählen

with open('.../Privat/datei.txt', 'a') as datei:
    datei.writelines(html)
Edit: Sollte html ein String sein, so ist natürlich nur datei.write() zu verwenden.
2.0.0.4 hat geschrieben:das erste Problem ist das die seite die er sich runter zieht nicht die ist die ich im Browser als Quelltext angezeigt bekomme.
Schau im Browser mal, ob da vielleicht eine Redirection stattfindet.
Zuletzt geändert von /me am Mittwoch 4. Dezember 2013, 11:19, insgesamt 1-mal geändert.
BlackJack

@2.0.0.4: Wenn Du da etwas anderes bekommst als der Browser, dann erkennt die Webseite das es kein Browser ist. Zum Beispiel am User-Agent, oder dass gesetzte Cookies nicht vorhanden sind, oder vielleicht musst Du Dich ja auch vorher anmelden‽

Zum öffnen von Dateien sollte man `open()` verwenden und nicht `file`. Letzteres ist als Typ zum erben gedacht, weil es ein wenig komisch aussieht wenn man eine Klasse von `open` ableitet. ;-)

Dateien die man öffnet sollte man auch wieder schliessen. Um das sicher zu machen kann man die ``with``-Anweisung verwenden. Dann braucht man auch den `flush()`-Aufruf nicht.

`writelines()` ist der falsche Aufruf für *ein* `str`-Objekt. Das endet damit das für jedes Zeichen/Byte ein einzelner Schreibaufruf gemacht wird. `write()` dagegen schreibt alles in einem Aufruf (eventuell hinter den Kulissen auch mit mehreren, aber mit so wenig wie nötig).

Der Name `textliste` ist falsch, da es sich nicht um eine Liste handelt und die Zuweisung macht auch keinen Sinn. Jetzt hast Du den *selben* Wert unter zwei Namen in dem kurzen Quelltext. Warum?

Um eine Konstante Zeichenkette in einer anderen zu suchen braucht man keine regulären Ausdrücke, dafür gibt es Methoden auf Zeichenketten. Das Ergebnis wird auch gar nicht verwendet, also kann die Zeile gestrichen werden.

Beim Einlesen der Zeilen würde ich persönlich ja ``list(datei)`` statt ``datei.readlines()`` schreiben und `datei` eher `lines` nennen. Beziehungsweise würde ich schauen ob man bei der weiteren Verarbeitung tatsächlich den gesamten Dateiinhalt auf einmal in den Arbeitsspeicher lesen muss, oder ob man die Datei nicht zeilenweise verarbeiten kann. Das kann man aber nicht sagen, weil auch `inhalt` überhaupt nicht verwendet wird und damit aus dem Programm verschwinden kann.

Zum Schluss sieht es dann so aus als wolltest Du HTML mit regulären Ausdrücken verarbeiten. Da würde ich dringend von abraten und einen HTML-Parser verwenden. `lxml.html` oder BeautifulSoup werden da gerne genommen.

An der Stelle stellt sich auch die Frage warum Du an die Datei die gespeichert wird *anhängst* statt jeweils neue Dateien zu schreiben. Eine HTML-Datei die mittendrin abbricht kann man mit einem HTML-Parser noch verarbeiten. Eine Datei die mehrere HTML-Dateien, die abbrechen, hintereinander enthält, könnte problematisch werden. Selbst komplette HTML-Dateien sind nicht dazu gedacht hintereinander in einer Datei gespeichert zu werden. Wobei man auch immer damit rechnen muss, dass gar kein gültiges HTML ausgeliefert werden muss. Man kann so etwas dann nicht mehr zuverlässig voneinander trennen was man da mal zusammen in eine Datei geworfen hat, und dann stellt sich die Frage nach dem Wert so einer Datei.
2.0.0.4
User
Beiträge: 8
Registriert: Mittwoch 4. Dezember 2013, 10:18

danke für die schnellen Antworten.
ich bin eingelogt - wie kann ich der seite vorgaukeln das ein browser zugreift?

Code: Alles auswählen

import urllib2
import re

response = urllib2.urlopen('http://vk.com/friends?id=xxxxxxx&section=all')
html = response.read(200000)

with open('/..../datei.txt', 'a') as datei:
    datei.write()


a = re.findall( '\s*"\s*res\s*(\d{9})\s*"\s*>\s*<',html,re.IGNORECASE)
print a
momentan bekomme ich einfach Eckigeklammern als Antwort - die such funktioniert auch nicht



womit würdet Ihr eine html durchsuchen ?
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

2.0.0.4 hat geschrieben:womit würdet Ihr eine html durchsuchen ?
BeautifulSoup
BlackJack

@2.0.0.4: Du bist nicht angemeldet, da ist ja gar kein Code dafür in dem Programm. Ob Du irgendwo in einem *anderen* Programm, zum Beispiel einem Browser auf der Seite angemeldet bist spielt dabei keine Rolle.

Wenn Du Dir die Antwort mal anschauen würdest, dann würde auch sehr schnell klar werden, dass Du nicht angemeldet bist, denn das ist eine Anmeldeseite mit einem Formular für Benutzername und Passwort, die Du da zurück geliefert bekommst.

Wenn ich die Seite mit meinen paranoiden Browsereinstellungen aufrufe bekomme ich keine Eingabemaske sondern einen Hinweis, dass die Seite ohne Cookies und JavaScript nicht funktioniert. Keine Ahnung ob JavaScript tatsächlich unerlässlich für Dein Vorhaben ist, aber einen Cookie bekomme ich auf jeden Fall gesendet. Ist also zu vermuten, dass man damit umgehen können muss. Das will man sich nicht mit `urllib2` antun. Da kann man zum Beispiel mit `requests` arbeiten und ein `Session`-Objekt erstellen. Oder man „simuliert” mit dem `mechanize`-Paket mehr von einem Browser.

Du weisst schon was „Eckigeklammern” in diesem Fall bedeutet, oder? Also was für einen Datentyp der Wert von `a` hat und was *dieser* Wert für eine Bedeutung hat‽ Falls nicht, leg Dein konkretes Vorhaben mal auf Eis und arbeite ein Python-Grundlagentutorial durch. Die Grunddatentypen sollte man schon kennen.

`lxml.html` oder BeautifulSoup zum Verarbeiten von HTML habe ich doch schon mal erwähnt als besseres Werkzeug als reguläre Ausdrücke.
Antworten