'NoneType' object is not callable bei String replace

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
schneseb
User
Beiträge: 7
Registriert: Donnerstag 13. August 2009, 12:40

Guten morgen :-)

Ich bin dabei gerade eine Webseite auszulesen und habe mit guter Unterstützung schon fein meine Tags auslesen können. Ich habe jetzt ein weiteres Problem, was ich nicht mehr deuten kann.

Code: Alles auswählen

# this is the URL to access the history
        url = 'https://www.name.de'
        # open the URL with urllib2
        fileHandle = urllib2.urlopen(url)
        # read the result and store in a string
        str1 = fileHandle.read()
        # Create a beautiful instance with the string
        soup = BeautifulSoup(str1)
        # Close the connection
        fileHandle.close()
      
        # this pattern detects all HTML tags
        tagPattern = r"<[a-zA-Z\/][^>]*>"
        
        # allTdsAsList contains something like <td class="std" onclick="...">
        # the_data_i'm_interessted_in </td> for all hits (list)
        allTdsAsList = soup.findAll('td',{'class' : 'std', 'onclick' : True})
               
        # check if there is at least one singleTdEntryToRemove...
        if allTdsAsList != None:
            # we iterate over all entries
            for singleTdEntry in allTdsAsList:
                # at this point we have only one <td> tag here: 
                # <td class="std" onclick="..."> the_data_i'm_interessted_in </td>
                
                # Our tdEntriesToRemove is the complete <td> tag data
                # the result is a list with all entries that can be removed           
                tdEntriesToRemove = re.findall(str(tagPattern), str(singleTdEntry))
                
                # if we have some entries to remove...
                if tdEntriesToRemove != None:
                    # iterate over every single entry
                    for singleTdEntryToRemove in tdEntriesToRemove:
                        print singleTdEntry
                        print singleTdEntryToRemove
                        singleTdEntry = singleTdEntry.replace(tagPattern, '')
1. Ich rufe die Webseite auf und lese meine Daten raus, mich interessieren die TD Tags, welche ich auch ohne Probleme bekomme
2. ich will dann mit einer RegExp über die <td> Einträge laufen und nur noch den Nutztext überlassen, dass mache ich mit der Regular Expression. Die funktioniert auch - das habe ich getestet.
3. Ich bekomme immer folgenden Fehler: TypeError: 'NoneType' object is not callable (In der Zeile 37). Ich habe die Print Anweisungen mal vorgesetzt um zu sehen was drin ist. Das sieht soweit gut aus: <td class="std" onclick="function(232);">Payload</td> ist in singleTdEntry drin, soweit gut. Nun will ich das Payload haben und will die HTML Tags entfernen. Das was ich entfernen will steht nun in singleTdEntryToRemove = <td class="std" onclick="function(232);">. Passt alles soweit gut, nur ich kann jetzt mit der Fehlermeldung nichts anfangen. Ich will in der Zeile 37 einfach nur aus dem singleTdEntry die Nutzdaten machen und das HTML entfernen.

Mein googeln zu der Fehlernachricht war nicht richtig erfolgreich und ich konnte meine Ursache nicht ableiten. Wenn ich mir jetzt ein kleines Minimalbeispiel baue und die replace Funktion nutze klappt das so schon, nur hier nicht. Ich finde das Problem aber nicht. Sieht jemand meinen Fehler?

Danke!
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Code: Alles auswählen

In [1]: html = '<td class="std" onclick="function(232);">Payload</td><td>No onclick</td><td class="std" onclick="function(42);">Python is not a snake</td>'

In [2]: from BeautifulSoup import BeautifulSoup

In [3]: soup = BeautifulSoup(html)             

In [4]: elements = soup.findAll('td', 'std', onclick=True)

In [5]: elements
Out[5]: 
[<td class="std" onclick="function(232);">Payload</td>,
 <td class="std" onclick="function(42);">Python is not a snake</td>]

In [6]: [element.string for element in elements]
Out[6]: [u'Payload', u'Python is not a snake']
schneseb
User
Beiträge: 7
Registriert: Donnerstag 13. August 2009, 12:40

subba :D

das

Code: Alles auswählen

[element.string for element in elements] 
ist cool, dachte mir schon, dass es noch schneller geht 8)

Dankeschön!
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Zeile 21 und 32 lassen sich im uebrigen auf ``if name`` verkuerzen.
Deine Kommentare sagen das gleiche wie der Code daneben, sie haben ueberhaupt keinen Mehrwert.
Und generell willst du dir mal PEP 8 anschaun ;)
schneseb
User
Beiträge: 7
Registriert: Donnerstag 13. August 2009, 12:40

cofi hat geschrieben:Zeile 21 und 32 lassen sich im uebrigen auf ``if name`` verkuerzen.
okey danke :-)
cofi hat geschrieben: Deine Kommentare sagen das gleiche wie der Code daneben, sie haben ueberhaupt keinen Mehrwert.
Ja, ich hab doch noch nichts mit Python gemacht und schreib mir dann gerne schon mal so auf, was ich machen will. Ich hätte es auch weglassen können im Posting, das stimmt.
cofi hat geschrieben: Und generell willst du dir mal PEP 8 anschaun ;)
... bin am Lesen :-)

Thx!
BlackJack

Die beiden ``if``\s lassen sich nicht nur kürzen, sondern man kann sie komplett weg lassen. Denn beide Suchoperationen geben *nicht* `None` zurück, wenn nichts gefunden wird, sondern konsequenterweise eine leere Liste:

Code: Alles auswählen

In [12]: soup.findAll('x')
Out[12]: []

In [13]: re.findall('x', 'a')
Out[13]: []
Antworten