Quelltext-Suche + Listbox

Fragen zu Tkinter.
Antworten
Skorab
User
Beiträge: 20
Registriert: Donnerstag 2. Juli 2015, 20:30

Hallo Python-Gemeinde,

ich habe mein erstes Python-Projekt gerade laufen. Dabei programmiere ich ein GUI das eine Website nach dem Input im Entry-Feld absucht, es als passenden Link ausgibt und es zur Auswahl in die Listbox setzt. Dabei bin ich mir mit den regulären Ausdrücken noch nicht ganz vertraut. Aber hier ersteinmal mein Code:

Code: Alles auswählen

from tkinter import *
from re import *
import urllib.request



class Window:

	def __init__(self, master):

		frame = Frame(master)
		frame.pack(fill=BOTH, expand=1)

		Button(frame, text='Suche', command=self.seriencheck).grid(row=0, column=0, sticky=W+E+N+S)

		self.entry = StringVar()
		Entry(frame, textvariable=self.entry).grid(row=0, column=1, sticky=W+E+N+S)

		self.set = IntVar()
		r1 = Radiobutton(frame, text='Zufall', variable=self.set, value=1)
		r1.grid(row=1, column=0)
		r2 = Radiobutton(frame, text='Reihenfolge', variable=self.set, value=2)
		r2.grid(row=1, column=1)

		listbox = Listbox(frame, height=10, selectmode = SINGLE,)
		listbox.grid(row=2, column=1)

		frame.columnconfigure(1, weight=1)
		frame.rowconfigure(1, weight=1)

	def suche(self, self.entry):

		try:
			url = 'http://www.bs.to/search'
			file = urllib.request.urlopen(url)
			contents = file.read() 
			file.close()
#hier kommt nun die Suche mit regular expressions:
			re = compile((str(self.entry))
			


		except:
			print('program needs to be updated')
		



			
		
	

root = Tk()
root.wm_title('Programm1')
root.geometry("500x400+0+0")
window = Window(root)
root.mainloop()
So nun mein Problem:

Wie kann ich die Suche gestalten damit der Quelltext nach der Eingabe abgesucht wird, egal ob er vollständig ist oder nicht? Ein Kriterium was dazugenohmen werden muss ist, dass jeder String im Quelltext, mit < anfängt und mit > aufhört- Das Ergebnis soll ergäntzt werden und mit Bindestrichen aufgefüllt werden, damit diese als Links nutzbar sind.
Zuletzt geändert von Anonymous am Sonntag 27. Dezember 2015, 21:14, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
BlackJack

@Skorab: Ich sehe hier gerade den Bezug zu Tkinter nicht wirklich. Das Problem ist ja die Webseite nach einem Text zu durchsuchen. Wo der Text herkommt ist dabei ja erst einmal egal. Zum verarbeiten von HTML sollte man keine regulären Ausdrücke verwenden sondern eine Bibliothek die HTML versteht. `lxml.html` oder BeautifulSoup zum Beispiel. Denn gerade bei der zusätzlichen Bedingung das der Text mit ``<`` und ``>`` beginnt und endet hat man schon das Problem das diese Zeichen nicht so im HTML stehen werden, weil sie dann als Teil von HTML-Tags angesehen würden (zumindest das <) und da gibt es verschiedene Möglichkeiten diese Zeichen zu kodieren. Eine Bibliothek die HTML parst kann die Tags und den Inhalt auseinanderhalten und macht beim Text auch wieder < und > aus der wie auch immer gearteten Kodierung dieser Zeichen.
Skorab
User
Beiträge: 20
Registriert: Donnerstag 2. Juli 2015, 20:30

Ich lade mir die den Quellcode ja als Text herunter da sollte es doch eigentlich kein Problem sein wenn ich nach < > suche. Hatte ich schon mal eine Suche ala:

Code: Alles auswählen

while True:
				i=contents.find(z, i)
				if i == -1:
					break
				i=contents.find('>', i+1)

				j=contents.find('<', i+1)
				title = contents[i+1:j]
				serien = [title]
				
				
was ich persönlich nicht passend finde, was aber funktioniert. Ich möchte die Eingabe vervollständigt sehen und mit Bindestrichen versehen. Das soll dann in die Listbox und von da aus dann ausgewählt werden und in einem tab im Browser als url geöffnet werden. Ist das möglich. <Mit der Listbox habe ich nicht so viel erfahrung.
BlackJack

@Skorab: Du lädtst da HTML-Quelltext herunter und verarbeitest den als wäre das eine ganz normale Textdatei und nicht eine Datei die den Syntaxregeln von HTML folgt. Die Zeichen ``<`` und ``>`` haben in HTML eine besondere Bedeutung aber nicht jedes Vorkommen dieser beiden Zeichen bedeutet das selbe. Die Zeichen können Tags begrenzen, aber auch Kommentare und innerhalb von Kommentaren oder Attributen von HTML-Tags stehen. Falls es sich um XHTML handelt können die Zeichen auch in CDATA-Blöcken vorkommen. Um HTML robust zu verarbeiten braucht man einen HTML-Parser und keine simplen Zeichenkettenoperationen und reguläre Ausdrücke.
Skorab
User
Beiträge: 20
Registriert: Donnerstag 2. Juli 2015, 20:30

Also ich weiß nicht ob ich dich richtig verstehe aber ich halte es lieber einfach. Solange kein Interpreter/compiler über das "Skript" läuft brauche ich ja "nur" ein Textverarbeitungsskript der mir die richtigen Ausdrücke liefert wenn die Nutzer nur unvollständig ihre Serientitel eingeben und diese dann in die Listbox als Treffer einfügt :)
BlackJack

@Skorab: Du hältst es gerade nicht einfach, Du machst es Dir kompliziert wenn Du's richtig machen willst, oder *zu* einfach und schreibst damit kaputten Code der nicht das macht was er soll, oder wenn dann nur zufällig und ganz sicher nicht zuverlässig. Einfach wäre es einen HTML-Parser die Arbeit zu überlassen und die gewünschten Teile über die Struktur im HTML und vielleicht sogar IDs oder CSS zu identifizieren statt das als unstrukturierten Text zu behandeln und sich da irgendwie an < und > Zeichen zu orientieren ohne die tatsächliche Struktur zu verarbeiten. Das ist schlicht kaputt.
Skorab
User
Beiträge: 20
Registriert: Donnerstag 2. Juli 2015, 20:30

Mhmm.. davon habe ich einfach keine Ahnung deswegen versuche ich einen textverarbeitenden code zu entwickeln. Es ist im Prinzip eine Autocompletion für Serien aller Art. das wäre mir genüge falls ihr da ein paar Tips habt, ist ja mein erstes eigenes Python Projekt..
BlackJack

@Skorab: Mein Tipp wäre einen HTML-Parser zu verwenden um Daten aus HTML zu holen. Und die Programmlogik von der GUI beziehungsweise generell der Benutzerinteraktion zu trennen.
Skorab
User
Beiträge: 20
Registriert: Donnerstag 2. Juli 2015, 20:30

So habe jetzt den regulären Ausdruck rausbekommen, Nun bekomme ich aber für meinen Code die Fehlermeldung:
Can't convert int object to str implicitly
(line 14)

Code: Alles auswählen

from tkinter import *
from re import *
import urllib.request



class Window:

	def __init__(self, master):

		frame = Frame(master)
		frame.pack(fill=BOTH, expand=1)

		Button(frame, text='Suche', command=self.seriencheck).grid(row=0, column=0, sticky=W+E+N+S)

		self.entry = tkinter.StringVar()
		Entry(frame, textvariable=self.entry).grid(row=0, column=1, sticky=W+E+N+S)

		self.set = IntVar()
		r1 = Radiobutton(frame, text='Zufall', variable=self.set, value=1)
		r1.grid(row=1, column=0)
		r2 = Radiobutton(frame, text='Reihenfolge', variable=self.set, value=2)
		r2.grid(row=1, column=1)

		listbox = Listbox(frame, height=10, selectmode = SINGLE,)
		listbox.grid(row=2, column=1)

		frame.columnconfigure(1, weight=1)
		frame.rowconfigure(1, weight=1)

	def seriencheck(self, entry):
		
		
		try:
			url = 'http.//www.bs.to/search'
			file = urllib.request.urlopen(url)
			re = compile('>.*?(self.entry).*?<')
			contents = file.read() 
			file.close()
			
			return re.findall(contents)
			


		except:
			print('program needs to be updated')
		



			
		
	

fenster = Tk()
fenster.wm_title('Programm1')
fenster.geometry("500x400+0+0")
window = Window(fenster)
fenster.mainloop()

Ich verstehe das nicht, da ich überhaupt keine integer werte in meinem code habe..
Zuletzt geändert von cofi am Dienstag 29. Dezember 2015, 19:32, insgesamt 1-mal geändert.
Grund: Code Highlighting korrigiert
BlackJack

@Skorab: Schönes Beispiel warum Sternchenimporte keine gute Idee sind. Wie die Fehlermeldung schon sagt wird in Zeile 14 ein Zahlenwert verwendet wo eine Zeichenkette erwartet wird. Überlege Dir mal wo welcher Name in der Zeile dort herkommt und welchen Wert die jeweils haben, und dann überprüfe Deine Annahme einfach mal.
Sirius3
User
Beiträge: 17759
Registriert: Sonntag 21. Oktober 2012, 17:20

@Skorab: es wäre sehr großer Zufall, wenn wirklich dieser Reguläre Ausdruck gefunden würde. Es ist für mich auch sehr schwer zu lesen, alles aus dem re-Modul zu importieren und dann den compilierten regulären Ausdruck an eine Variable re zu binden. Variablennamen in Strings sind in Python einfach nur Zeichen ohne besondere Bedeutung.
Antworten