Seite 1 von 1

'NoneType' object is not callable bei String replace

Verfasst: Donnerstag 10. September 2009, 10:00
von schneseb
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!

Verfasst: Donnerstag 10. September 2009, 11:53
von snafu

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']

Verfasst: Donnerstag 10. September 2009, 12:22
von schneseb
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!

Verfasst: Donnerstag 10. September 2009, 14:15
von cofi
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 ;)

Verfasst: Freitag 11. September 2009, 07:04
von schneseb
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!

Verfasst: Freitag 11. September 2009, 07:11
von 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]: []