Python & PHP Hilfe: Fehlersuche bei Problemen

Bin Neueinsteiger, Anfänger – wie finde ich den Fehler?

Der Teufel – auch bei Python und PHP – steckt immer im Detail und trotz stundenlanger Suche findest Du selten die richtigen Antworten auf Deine Fragen. Oft hängt es daran, dass scheinbar niemand Deine Probleme hat. Mysteriös wird es für Dich, wenn eine Pythondatei in der IDLE Shell auf Deinem Computer läuft, aber nicht, wenn dasselbe Script in einem PHP Script mittels „exec“ oder „shell_exec“ aufgerufen wird.

Module, Pfade & Versionen

Bei mir auf dem Windows-PC ist Python 3.8.10 installiert, mein Webhoster legt mir leider eine ältere Version (Python 2.7) ins Paket. Das ist eine häufige Erklärung dafür, weshalb ein auf dem Computer funktionierendes Python-Skript bei Deinem Webhosting-Anbieter nicht funktioniert.

Es gibt ein Modul, das ist immer vorhanden – das Modul „sys. Dieses Modul bietet Zugriff auf verschiedene Variablen (die von Interpreter verwendet, verwaltet werden) und auf grundlegende Funktionen. Wir nutzen dieses Modul – indirekt – für unsere Fehlersuche.

Python-Pfad ermitteln

Oft sind falsche Pfade daran schuld, dass Module nicht geladen werden und einen Fehler wie „ImportError(‚No module named requests‘,)“ erzeugen. Die richtigen Pfade in Deinem Webspace bekommst Du mit folgendem Code heraus:

import sys
print(sys.path)

#  AUSGABE
# '/homepages/38/d805973522/htdocs/d_ddr',
# '/usr/lib/python2.7', 
# '/usr/lib/python2.7/plat-x86_64-linux-gnu', 
# '/usr/lib/python2.7/lib-tk', 
# '/usr/lib/python2.7/lib-old', 
# '/usr/lib/python2.7/lib-dynload', 
# '/usr/local/lib/python2.7/dist-packages', 
# '/usr/lib/python2.7/dist-packages'

Wenn der Import eines Modul/Bibliothek nicht funktioniert, kannst Du mit dem folgenden Befehl einen neuen Pfad für Deine Importe anzulegen.

sys.path.append("path-to-the-missing-directory")

Python Version des Webhosters anzeigen

Python 3 unterscheidet sich teilweise stark vom veralteten Python 2.7, sie nutzen teilweise völlig verschiedene Bibliotheken. Wenn Du einen eigenen Server gemietet hast, liegt es bei Dir, welche Python-Version Du installierst. Doch bist Du bei einem Anbieter für Web-/Shared-Hosting, wie 1blu, alfahosting, Domain Factory,Host Europe oder united domains, musst Du oft selbt die zur Verfügung gestellte Python-Version herausfinden.
Der folgende kleine Befehl zeigt Dir Deine installierte Python-Version an.

print(sys.version)

#  AUSGABE
# 2.7.16 (default, Oct 10 2019, 22:02:15)

Fehler in Python finden und ausgeben

Wer mit PHP aufgewachsen ist, muss bei Python etwas umdenken. Damit Deine Python-Scripte trotz Fehler – beispielsweise aufgrund eines nicht geladenen Moduls – ein Lebenszeichen von sich geben, eine Fehlermeldung erzeugen, die Du anzeigen/ausgeben lassen kannst, gibt es die „try / except“ Kontrollblöcke, Strukturen.

Damit deine Python-Scripte trotz Fehler – beispielsweise aufgrund eines nicht geladenen Moduls – ein Lebenszeichen von sich geben, eine Fehlermeldung erzeugen, die Du anzeigen/ausgeben lassen kannst, gibt es die „try / except“ Kontrollblöcke, Strukturen.

In dem „try-Block“ schreibst Du den produktiven Quellcode und der „except-Block2 enthält Anweisungen für den Fall, dass etwas schiefläuft.

try:
  # dein Quellcode
    print(y)
except:
  # wenn ein Fehler auftritt ...
    print('Konnte y nicht ausgeben')

# AUSGABE    
# Konnte y nicht in der Konsole anzeigen

Es geht aber auch noch etwas genauer bei der Ausgabe aufgetretener Fehler und Problemen.

try:
    print(y)
except Exception as e:
    print("Fehlermeldung:", e)
    
# AUSGABE     
# Fehlermeldung: name 'x' is not defined

Die folgende Fehlermeldung dürfte bei vielen, welche über einem Webhoster ihren Webspace gemietet haben, angezeigt werden. Bei mir macht beispielsweise STRATO zicken, doch würde es mich nicht wundern, wenn Python auch bei den Webhosting Angeboten von 1und1 (IONOS, 1&1) nicht auf Anhieb funktioniert.

try:
    import requests
    head = {'User-Agent': 'Mozilla/4.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTM, like Gecko) Chrome/51.0.2704.103 Safari/537.36 '}
except Exception as e:
    print("Fehlermeldung:", e)
    
# AUSGABE     
# Fehlermeldung: ImportError('No module named requests')

Diese Ausgabe einer Fehlermeldung ist interessant – Das Modul requests konnte nicht geladen werden. Ist es nicht vorhanden? Doch, sowohl in der Python Version 2.7 als auch unter Python 3 ist dieses Modul bekannt und verfügbar. Es muss also an einem Pfad liegen, der standardmäßig nicht gesetzt ist?

Übersicht der Fehlermeldungen

Liste meiner Python Module anzeigen

Es wurde kein Modul mit dem Namen „requests“ gefunden? Okay, gibt es das Modul überhaupt in meinem Webhosting-Paket? Um mir alle verfügbaren Module auflisten zu lassen, verwende ich den Befehl:

help('modules')

# AUSGABE
    [7] => BaseHTTPServer      antigravity         hmac                select
    [8] => Bastion             anydbm              hotshot             sets
    [9] => CDROM               apt                 htmlentitydefs      sgmllib
    [10] => CGIHTTPServer       apt_inst            htmllib             sha
    [11] => Canvas              apt_pkg             httplib             shelve
    [12] => ConfigParser        aptsources          ihooks              shlex
    [13] => Cookie              argparse            imaplib             shutil
    [14] => DLFCN               array               imghdr              signal
    [15] => Dialog              ast                 imp                 site
    [16] => DocXMLRPCServer     asynchat            importlib           sitecustomize
    [17] => FileDialog          asyncore            imputil             six
    [18] => FixTk               atexit              inspect             smtpd
    [19] => HTMLParser          audiodev            io                  smtplib
    [20] => IN                  audioop             itertools           sndhdr
    [21] => MimeWriter          base64              json                socket
    [22] => MySQLdb             bdb                 keyword             spwd
    [23] => PIL                 binascii            lib2to3             sqlite3
    [24] => Queue               binhex              linecache           sre
    [25] => ScrolledText        bisect              linuxaudiodev       sre_compile
    [26] => SimpleDialog        bsddb               locale              sre_constants
    [27] => SimpleHTTPServer    bz2                 logging             sre_parse
    [28] => SimpleXMLRPCServer  bzrlib              lsb_release         ssl
    [29] => SocketServer        cPickle             macpath             stat
    [30] => StringIO            cProfile            macurl2path         statvfs
    [31] => TYPES               cStringIO           mailbox             string
    [32] => Tix                 calendar            mailcap             stringold
    [33] => Tkconstants         cgi                 markupbase          stringprep
    [34] => Tkdnd               cgitb               marshal             strop
    [35] => Tkinter             chunk               math                struct
    [36] => UserDict            cmath               md5                 subprocess
    [37] => UserList            cmd                 mercurial           sunau
    [38] => UserString          code                mhlib               sunaudio
    [39] => _LWPCookieJar       codecs              mimetools           symbol
    [40] => _MozillaCookieJar   codeop              mimetypes           symtable
    [41] => __builtin__         collections         mimify              sys
    [42] => __future__          colorsys            mmap                sysconfig
    [43] => _abcoll             commands            modulefinder        syslog
    [44] => _ast                compileall          multifile           tabnanny
    [45] => _bisect             compiler            multiprocessing     tarfile
    [46] => _bsddb              configobj           mutex               telnetlib
    [47] => _codecs             contextlib          mx                  tempfile
    [48] => _codecs_cn          cookielib           my_benzin_polen     termios
    [49] => _codecs_hk          copy                netrc               test
    [50] => _codecs_iso2022     copy_reg            new                 textwrap
    [51] => _codecs_jp          crypt               nis                 this
    [52] => _codecs_kr          csv                 nntplib             thread
    [53] => _codecs_tw          ctypes              ntpath              threading
    [54] => _collections        curses              nturl2path          time
    [55] => _csv                datetime            numbers             timeit
    [56] => _ctypes             dbhash              opcode              tkColorChooser
    [57] => _ctypes_test        dbm                 operator            tkCommonDialog
    [58] => _curses             decimal             optparse            tkFileDialog
    [59] => _curses_panel       difflib             os                  tkFont
    [60] => _elementtree        dircache            os2emxpath          tkMessageBox
    [61] => _functools          dis                 ossaudiodev         tkSimpleDialog
    [62] => _hashlib            distutils           parser              toaiff
    [63] => _heapq              doctest             pdb                 token
    [64] => _hotshot            dumbdbm             pickle              tokenize
    [65] => _io                 dummy_thread        pickletools         trace
    [66] => _json               dummy_threading     pipes               traceback
    [67] => _locale             email               pkgutil             ttk
    [68] => _lsprof             encodings           platform            tty
    [69] => _md5                ensurepip           plistlib            turtle
    [70] => _multibytecodec     errno               popen2              types
    [71] => _multiprocessing    exceptions          poplib              unicodedata
    [72] => _mysql              fcntl               posix               unittest
    [73] => _mysql_exceptions   filecmp             posixfile           urllib
    [74] => _osx_support        fileinput           posixpath           urllib2
    [75] => _pyio               fnmatch             pprint              urlparse
    [76] => _random             formatter           profile             user
    [77] => _sha                fpformat            pstats              uu
    [78] => _sha256             fractions           pty                 uuid
    [79] => _sha512             ftplib              pwd                 validate
    [80] => _socket             functools           py_compile          warnings
    [81] => _sqlite3            future_builtins     pyclbr              wave
    [82] => _sre                gasoline_polen      pydoc               weakref
    [83] => _ssl                gc                  pydoc_data          webbrowser
    [84] => _strptime           gdbm                pyexpat             whichdb
    [85] => _struct             genericpath         quopri              wsgiref
    [86] => _symtable           getopt              random              xdrlib
    [87] => _sysconfigdata      getpass             re                  xml
    [88] => _sysconfigdata_nd   gettext             readline            xmllib
    [89] => _testcapi           glob                repr                xmlrpclib
    [90] => _threading_local    grp                 resource            xxsubtype
    [91] => _version            gzip                rexec               zipfile
    [92] => _warnings           hashlib             rfc822              zipimport
    [93] => _weakref            heapq               rlcompleter         zlib
    [94] => _weakrefset         hgdemandimport      robotparser
    [95] => abc                 hgext               runpy
    [96] => aifc                hgext3rd            sched
    [97] => 
    [98] => Enter any module name to get more help.  Or, type "modules spam" to search
    [99] => for modules whose descriptions contain the word "spam".

Den Befehl schreibst Du in das Pythonskript, welches Du auf einer Website mit PHP Befehl exec() aufrufst. Das Ergebnis wird im Browser angezeigt.

Wie ich sehe, wird das Modul „requests“ nicht erwähnt.

Neue Python Pfade einfügen

Wenn Du ein Python Modul in Dein Python-Script einbindest, durchsucht Python die ihm bekannten Verzeichnisse auf der Suche nach diesem Modul. Findet Python dieses Modul in keinem der bekannten Verzeichnisse, bekommst Du Fehlermeldung „ImportError(‚No module named requests‘,)“ angezeigt.

Die Variable sys.path verwaltet Pfadinformationen in Python. Wenn ein Modul importiert werden soll, nutzut der Pythoninterpreter diese ihm bekannten Pfadinformationen.

Die Methode append() wird über das Modul sys.path bereitgestellt. Um append() zu verwenden, muss zuvor das sys-Modul importiert werden.

Mit dem folgenden Befehl sys.path.append() kannst Du Pfade inzufügen, die bei der Suche nach Modulen einbezogen werden sollen.

import sys
sys.path.append('/usr/bin/python3.7')
sys.path.append('/usr/lib/python3.7')
sys.path.append('/usr/local/lib/python3.7')
sys.path.append('/usr/lib/python3.7/dist-packages')
print(sys.path)

Python prüft dabei nicht, ob diese Pfade auch tatsächlich auf Deinen Server existieren. Mit „print(sys.path)“ kannst Du Dir jetzt alle Python-Pfade anzeigen lassen.

ERST neuen Pfad eintragen – DANN Modul importieren

Variablen aus PHP heraus an Python übergeben

Siehe Link

codegree.de/python-exceptions-try-except/