@Jappes: Eingerückt wird mit 4 Leerzeichen pro Ebene. Nicht mal 5 und mal nur eines.
Es sind ein paar Leerzeilen zu viel in dem Quelltext. Die grossen Abstände machen das nur schwerer lesbar.
Auf Modulebene sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst.
Und ``global`` bitte gleich wieder vergessen. Alles was eine Funktion ausser Konstanten benötigt, bekommt sie als Argument(e) übergeben.
Namen sollten nicht so weit von der Stelle definiert werden an der sie dann tatsächlich verwendet werden. `move` wird beispielsweise ganz am Anfang definiert, aber erst gegen Ende tatsächlich verwendet. Wenn man dann mit zur Verwendung gelesen hat, muss man erst mal wieder viel weiter oben suchen wie das eigentlich definiert ist. Und so steigt auch die Gefahr das man Code ändert, Namen nicht mehr verwendet, aber vergisst, das die irgendwo weiter oben trotzdem noch definiert sind.
Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (PascalCase).
Und es sollten sprechende Namen sein, die dem Leser verraten was der Wert dahinter bedeutet. `xV` oder `numerX` hinterlassen beim Lesen eher Fragezeichen als das sie verständliche Information transportieren.
`move` und `numerX` haben immer den gleichen Wert — warum braucht man dafür zwei Namen?
Der Name `page` ist falsch für ein `Response`-Objekt. Das ist mehr als eine Seite, oder auch weniger, denn die Antwort muss ja nicht zwingend eine Seite enthalten.
`search` ist falsch, weil es sich nicht um eine Suche handelt, sondern um das Ergebnis einer Suche.
Und man sollte den Namen nicht sowohl an ein komplexeres `Tag`-Objekt und an eine Zeichenkette binden. Das ist verwirrend.
Der weiterverarbeitende Code muss mit unter das ``if``, wenn sonst wird versucht mit dem `None` weiter zu arbeiten.
Die ``while``-Schleife sollte eine ``for``-Schleife sein und ich vermute mal nicht am Ende stehen, sondern den gesamten Code umfassen.
Da wird dann das `numerX` überflüssig weil man in Python nicht den Umweg über einen Laufindex nimmt, wenn man direkt über die Elemente eines Objekts wie einer DataFrame-Spalte iterieren kann.
Falls man zusätzlich eine laufende Zahl benötigt, gibt es die `enumerate()`-Funktion.
`my_function` ist dann wieder ein schlechter Name. Die Vorsilbe `my` macht in 99,999% der Fälle keinen Sinn, weil da keine Information drin steckt, wenn das nicht gegen `our_*` oder `their_*` abgegrenzt wird. Und `function` sagt auch nichts sinnvolles aus solange das nicht tatsächlich ein Name für eine völlig generische Funktion ist.
Das der Funktion sowohl der `DataFrame` als auch der Zeilenindex übergeben wird, riecht komisch.
Ungetestet:
Code: Alles auswählen
#!/usr/bin/env python3
import pandas as pd
import requests
from bs4 import BeautifulSoup
URL_TEMPLATE = (
"https://www.amazon.de/gp/offer-listing/{}/"
"ref=dp_olp_NEW_mbc?ie=UTF8&condition=NEW"
)
HEADERS = {
"User-Agent": (
"Mozilla/9.0 (Macintosh; Intel Mac OS X 10_14_5)"
" AppleWebKit/537.36 (KHTML, like Gecko)"
" Chrome/84.0.4147.89 Safari/537.36"
)
}
def this_name_should_reflect_what_the_function_does(
data, variable_in_need_of_a_better_name, index
):
...
def main():
data = pd.read_csv("Mappe1.csv")
for i, variable_in_need_of_a_better_name in enumerate(
map(str, data.iloc[:, 0])
):
response = requests.get(
URL_TEMPLATE.format(variable_in_need_of_a_better_name),
headers=HEADERS,
)
response.raise_for_status()
search_result = BeautifulSoup(response.content, "lxml").find(
"div", "olp-text-box"
)
if search_result:
text = search_result.get_text(strip=True)
print(text, variable_in_need_of_a_better_name, i)
this_name_should_reflect_what_the_function_does(
data, variable_in_need_of_a_better_name, i
)
if __name__ == "__main__":
main()