"ModuleNotFoundError: No module named 'requests'" trotz "Requirement already satisfied" – wie beheben?

Probleme bei der Installation?
Antworten
Boscaiola
User
Beiträge: 3
Registriert: Mittwoch 15. Mai 2024, 22:17

Hallo zusammen,

ich beschäftige mich seit einiger Zeit mit Python auf automatetheboringstuff.com und "baue" beim Lernen auch die dort beschriebenen Projekte nach, bin aber noch ziemliche Anfängerin auf dem Gebiet – deshalb sorry, dass ich vielleicht auch mit ganz grundlegenden Dingen und Begriffen noch nicht wirklich vertraut bin.

Für eines der Projekte ("mclip.py" aus Kapitel 6) habe ich das third-party-Modul pyperclip installiert, indem ich (wie in Anhang A beschrieben) im cmd eingeben habe: pip install --user pyperclip. Und ich habe eine Batch-Datei mclip.bat erstellt, um das Programm über den Ausführen-Dialog starten zu können – was auch problemlos klappt.

Genauso habe ich das bei dem Projekt "searchpypi.py" (aus Kapitel 12) gemacht, wofür ich unter anderem das third-party-Modul requests installieren musste. Wenn ich searchpypi.py aber über den Ausführen-Dialog starten möchte, kommt folgende Fehlermeldung im cmd:

Code: Alles auswählen

Traceback (most recent call last):
  File "C:\Users\USERNAME\PythonFiles\searchpypi.py", line 3, in <module>
    import requests, sys, webbrowser, bs4
ModuleNotFoundError: No module named 'requests'
Wenn ich jetzt aber im cmd "pip install --user requests" eingebe, kommt diese Meldung:

Code: Alles auswählen

Requirement already satisfied: requests in c:\users\USERNAME\appdata\local\packages\pythonsoftwarefoundation.python.3.12_qbz5n2kfra8p0\localcache\local-packages\python312\site-packages (2.31.0)
Requirement already satisfied: charset-normalizer<4,>=2 in c:\users\USERNAME\appdata\local\packages\pythonsoftwarefoundation.python.3.12_qbz5n2kfra8p0\localcache\local-packages\python312\site-packages (from requests) (3.3.2)
Requirement already satisfied: idna<4,>=2.5 in c:\users\USERNAME\appdata\local\packages\pythonsoftwarefoundation.python.3.12_qbz5n2kfra8p0\localcache\local-packages\python312\site-packages (from requests) (3.7)
Requirement already satisfied: urllib3<3,>=1.21.1 in c:\users\USERNAME\appdata\local\packages\pythonsoftwarefoundation.python.3.12_qbz5n2kfra8p0\localcache\local-packages\python312\site-packages (from requests) (2.2.1)
Requirement already satisfied: certifi>=2017.4.17 in c:\users\USERNAME\appdata\local\packages\pythonsoftwarefoundation.python.3.12_qbz5n2kfra8p0\localcache\local-packages\python312\site-packages (from requests) (2024.2.2)
Gebe ich hingegen "pip install --user pyperclip" ein, erscheint eine viel kürzere Rückmeldung.

Code: Alles auswählen

C:\Users\USERNAME>pip install --user pyperclip
Requirement already satisfied: pyperclip in c:\users\USERNAME\appdata\local\packages\pythonsoftwarefoundation.python.3.12_qbz5n2kfra8p0\localcache\local-packages\python312\site-packages (1.8.2)
Könnte darin vielleicht der Schlüssel für die Lösung des Problems liegen?

Wahrscheinlich sind auch noch folgende Infos relevant:
Meine Python-Version ist 3.12., ich habe Windows11.
Der Ordner C:\Users\USERNAME\AppData\Local\Programs\Python\Python312\Scripts ist leer,
es gibt allerdings einen Ordner C:\Users\USERNAME\AppData\Local\Programs\Python\Python312\~cripts, der die Anwendungsdateien pip, pip 3.12 und pip3 enthält.

Der Ordner C:\Users\USERNAME\AppData\Local\Programs\Python\Python312 ist in der PATH-Umgebungsvariablen gelistet.

Meine Frage ist also: Wie kann ich den im Betreff genannten Fehler beheben? Ich würde mich sehr freuen, wenn mir jemand einen Tipp geben könnte. Alles, was ich über Google dazu gefunden habe, hat mir nicht weitergeholfen, und auch die Forumsuche hat keine Ergebnisse gebracht, die genau auf meinen Fall zutreffen.

Gruß,
Boscaiola
Benutzeravatar
__blackjack__
User
Beiträge: 13230
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Boscaiola: An der Länge der Rückmeldung liegt das nicht. `pyperclip` ist halt ein Modul das keine weiteren Abhängigkeiten hat, während `requests` noch von einigen anderen Packages abhängt, die alle installiert sind.

Wie sehen denn die Startskripte jeweils aus?

Die beiden wahrscheinlichsten Varianten sind, dass Du entweder noch einen anderen Python-Interpreter installiert hast, oder das ein venv im Spiel ist, in dem `requests` nicht installiert ist.
“There will always be things we wish to say in our programs that in all known languages can only be said poorly.” — Alan J. Perlis
Boscaiola
User
Beiträge: 3
Registriert: Mittwoch 15. Mai 2024, 22:17

@__blackjack__: Vielen Dank für die Antwort!
`pyperclip` ist halt ein Modul das keine weiteren Abhängigkeiten hat, während `requests` noch von einigen anderen Packages abhängt, die alle installiert sind.
Das ist schon mal eine neue Info für mich, wusste ich vorher nicht.

Die beiden Skripte sehen so aus:

Code: Alles auswählen

#! python3
# searchpypi.py - Opens several search results.
import requests, sys, webbrowser, bs4
print("Searching…") # display text while downloading the search result page
res = requests.get("https://google.com/search?q=" "https://pypi.org/search/?q=" + " ".join(sys.argv[1:]))
res.raise_for_status()
# Retrieve top search result links.
soup = bs4.BeautifulSoup(res.text, "html.parser")

# Open a browser tab for each result.
linkElems = soup.select(".package-snippet")
numOpen = min(5, len(linkElems))
for i in range(numOpen):
    urlToOpen = "https://pypi.org" + linkElems[i].get("href")
    print("Opening", urlToOpen)
    webbrowser.open(urlToOpen)
(funktioniert nicht)

Code: Alles auswählen

#! python3
# mapIt.py - Launches a map in the browser using an address from the
# command line or clipboard.
import webbrowser, sys, pyperclip
if len(sys.argv) > 1:
    # Get address from command line.
    address = ' '.join(sys.argv[1:])
else:
    # Get address from clipboard.
    address = pyperclip.paste()

webbrowser.open('https://www.google.com/maps/place/' + address)
(funktioniert) – Ich hatte oben zwar "mclip.py" geschrieben, meinte aber "mapIt.py".

Installiert sind bei mir laut App-Übersicht Python Launcher, Python 3.12.1 (64-bit), Mu Editor 1.2.0, TigerJython-Win64_V2 und Python 3.12. Alle Projekte habe ich aber über Mu erstellt, und die Module über cmd installiert (wie oben beschrieben).
oder das ein venv im Spiel ist, in dem `requests` nicht installiert ist.
Wie finde ich das heraus? (Sorry, ist alles leider noch ziemlich neu für mich.)
Benutzeravatar
sparrow
User
Beiträge: 4233
Registriert: Freitag 17. April 2009, 10:28

@Boscaiola: Ich denke, TigerJython kannst du schon einmal bequem vergessen. Bis heute habe ich noch nie davon gehört und "Jython" ist eine Implementierung des Python Sprachstandards in Java. Abgesehen davon, dass der Anwendungsfall dieser speziellen Implementierung eher schmall und speziell ist, steht Jython soweit ich weiß noch immer auf dem Stand von Python 2.7. In der 'echten' Python-Welt ist die Version 2.x aber schon längst EOL.
Das also schon einmal weg. Selbst wenn es dir etwas "beinbringt" ist das schon längst überholt und möglicherweise in Python 3 komplett anders gelöst. Ein schneller Blick auf die Webseite von TigerJython zeigt mir auch nichts, was dieses Projekt für einen Anfänger rechtfertigen würde.

Mu kenne ich nicht.
Aber __blackjack__ hat mit dem, was er gesagt hat, schon den Kern herausgehoben: Du musst dir einmal erarbeiten, was "venv" sind. Diese virtuellen Umgebungen, die du je Projekt anlegen kannst und solltest.
Im Großen und Ganzen: Man kann Python Packete systemweit oder in einer "virtuellen Umgebung" installieren - dahinter verbirgt sich eine Package-Sammlung die für ein Projekt zugeschnitten ist und diese "Umgebung" sind von einander isoliert. So können sich die Versionen der Packages nicht gegenseitig beeinflussen. Manche IDEs legen das sowieso für jedes Projekt an.
Um das zu verstehen, ist es wichtig, sich einmal mit dem Thema zu beschäftigen.
Ich starte meine Programme immer aus der Shell selbst - mit einem selbst eingerichteten venv für das Projekt. Das hat den Vorteil, dass es einfach immer funktioniert, nichts hinter eine Oberfläche versteckt und das Verhalten sofort nachvollziehbar ist.

Es ergeben sich also 2 Fragen:

1. Wie startest du die Installation der Packete. (und zwar nicht nur der Befehl, sondern der Weg bis dahin=
2. Wie startest du die Programme.

Edit: Nachdem dein Programm dann startet, wird es aber wohl trotzdem nicht funktionieren. Soweit ich mich erinere möchte Google eher nicht, dass man automatisiert an den Suchergebnissen nuckelt.
Benutzeravatar
__blackjack__
User
Beiträge: 13230
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Boscaiola: Löst nicht das eigentliche Problem, aber ich möchte mal auf den Style Guide for Python Code hinweisen. automatetheboringstuff.com hält sich da leider in ein paar Punkten nicht dran. Beispielsweise was die Namensschreibweisen angeht. Aber auch das man nicht mehrere Module in einer Anweisung importieren sollte. Das wird schnell unübersichtlich.

Für das ``map_it.py``-Beispiel könnte man statt ``if``/``else``-Anweisungen auch einen bedingten Ausdruck verwenden:

Code: Alles auswählen

#!/usr/env python3
"""
mapIt.py - Launches a map in the browser using an address from the command
line or clipboard.
"""
import sys
import webbrowser

import pyperclip

address = " ".join(sys.argv[1:]) if len(sys.argv) else pyperclip.paste()
webbrowser.open("https://www.google.com/maps/place/" + address)
Neben der Schreibweise fällt beim zweiten Skript auch unangenehm auf das viele Namen aus kryptischen Abkürzungen bestehen. Man sollte beispielsweise nicht raten müssen ob `res` für `result` oder `response` steht.

Beim `get()`-Aufruf steht eine kaputte URL die sowohl Google als auch den Python Package Index enthält. Das sollte wohl nur letzteres sein.

Die URL-Parameter bastelt man nicht selbst in eine Zeichenkette. Es gibt bestimmte Zeichen die URLs eine Bedeutung haben, die muss man besonders kodieren. Das macht das `requests`-Modul wenn man das richtig an die Aufrufe übergibt.

``for i in range(…)`` nur um `i` dann als Index in eine Sequenz zu verwenden ist in Python ein „anti pattern“. Man kann in Python *direkt* über die Elemente von Sequenzen wie Listen iterieren, ohne den unnötigen Umweg über einen Laufindex. Und um nur maximal 5 Ergebnisse zu verwenden, kann man die „slice“-Syntax verwenden, die aus dem anderen Skript bereits bekannt ist.

Der Kommentar behauptet die URLs werden in neuen Tabs geöffnet. Das mag zufällig stimmen, ist aber nicht die Voreinstellung von `webbrowser.open()`. Da sollte man explizit `webbrowser.open_new_tab()` für verwenden.

Code: Alles auswählen

#!/usr/bin/env python3
"""
search_pypi.py - Opens several search results.
"""
import sys
import webbrowser

import bs4
import requests

print("Searching…")
response = requests.get(
    "https://pypi.org/search/",
    params={"q": " ".join(sys.argv[1:])},
    timeout=None,
)
response.raise_for_status()

soup = bs4.BeautifulSoup(response.text, "html.parser")
for link_element in soup.select(".package-snippet")[:5]:
    url = "https://pypi.org" + link_element.get("href")
    print("Opening", url)
    webbrowser.open_new_tab(url)
“There will always be things we wish to say in our programs that in all known languages can only be said poorly.” — Alan J. Perlis
Sirius3
User
Beiträge: 17814
Registriert: Sonntag 21. Oktober 2012, 17:20

Noch ergänzend zu __blackjack__: URLs sind nicht einfach Strings, die man zusammenstückeln kann. Hier mag das zufällig funktionieren, solange pypi ihr URL-Schema nicht ändert. Normalerweise sollte man aber URLs mit urljoin zusammensetzen:

Code: Alles auswählen

url = urllib.parse.urljoin(response.url, link_element.get('href'))
Boscaiola
User
Beiträge: 3
Registriert: Mittwoch 15. Mai 2024, 22:17

Also erstmal vielen Dank euch, @sparrow, @__blackjack__ und @Sirius3, für die sehr hilfreichen Anmerkungen. Da ist wirklich eine Menge Input für mich dabei, mit dem ich mich jetzt beschäftigen werde.

In das Thema venv habe ich mich inzwischen etwas eingelesen, das wird in "automatetheboringstuff" nicht wirklich thematisiert. Deshalb schließe ich auch aus, dass bei meinem nicht funktionierenden Programm ein venv im Spiel war, in dem das Modul "requests" nicht installiert ist. Aber auch wenn ich bislang noch immer nicht den Grund für diesen ModuleNotFoundError herausgefunden habe, so habe ich immerhin das Programm in einem eigens dafür erstellten venv gestartet, und dort gibt es diese Fehlermeldung nicht mehr - yeah, schon mal ein kleiner Zwischenerfolg. 8-)

TigerJython... ja, das hängt mit dem Buch "Let's Code Python" zusammen, das ich mir zum Einstieg gekauft habe. Dort arbeitet man mit diesem Interpreter, dessen Installation auch gleich am Anfang empfohlen wird. Weil der aber teilweise andere Funktionen als das "normale" Python hat und ich mit dem Buch generell nicht wirklich zufrieden bin, habe ich dann auf automatetheboringstuff.com umgesattelt (dort wird übrigens mit Mu gearbeitet) und arbeite mich fürs Erste da durch, um ein gewisses Grundwissen aufzubauen. Aber ich sehe, dass es wohl echt sinnvoll ist, sich da auch nicht immer blind zu verlassen, sondern daneben andere Quellen anzuschauen. Der Style Guide für Python Code ist da übrigens ein super Tipp, vielen Dank dafür!

Mein Ziel ist, eigene Web Scraping-Programme zu bauen, und dazu wollte ich erstmal mit den Projekten aus automatetheboringstuff üben. Die hier genannten Korrekturtipps für die Programmcodes sind dabei extrem hilfreich für mich, die werde ich mir alle noch eingehend anschauen.
Benutzeravatar
__blackjack__
User
Beiträge: 13230
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Boscaiola: „automatetheboringstuff“ ist schon ”älter” als venvs. Das ist jetzt nicht per se schlecht. Als das erschien (ist ja nicht nur eine Webseite sondern auch ein Buch), da haben IDEs in der Regel noch nicht als Voreinstellung ein venv pro Projekt angelegt, und da haben Linux-Distributionen den Programmierer noch nicht deutlich in Richtung venv geschubst, für die Installation von Python-Packages an der eigenen Paketverwaltung vorbei.

So wie ich das bei Mu lese, lässt auch dieser Editor den Code, den man damit schreibt, in einem eigenen venv laufen: https://mu.readthedocs.io/en/latest/des ... nment.html

Was man IMHO auf jeden Fall mal durchgearbeitet haben sollte, ist das Tutorial aus der Python-Dokumentation. Das ist immer auf dem neuesten Stand, passend zur jeweiligen Python-Version, von Leuten geschrieben die sich wirklich gut mit der Sprache auskennen, und die Beispiele sind automatisiert getestet.
“There will always be things we wish to say in our programs that in all known languages can only be said poorly.” — Alan J. Perlis
Antworten