Seite 1 von 1
'for in'-Zeile als Variable schreiben
Verfasst: Donnerstag 26. Dezember 2019, 19:04
von seemarc
Ich muss um die Ausgabe weiter bearbeiten zu können folgende Zeile in eine Variable schreiben:
Code: Alles auswählen
for link in link_list:
print ("https://www.testlink.de/"+(link_list['href']))
Dazu muss die Zeile jedoch umgeschrieben werden, aber ich habe jetzt alles was mir eingefallen funktionierte nicht. Der Grund warum das Ganze so geschrieben ist, ist das ich keine andere Möglichkeit gefunden habe die "href="-Elemente aus der "class": news-morelink zu bekommen. Wäre schön wenn mir wer zeitnah helfen könnte.
LG
Hier nochmal das ganze Script:
'
Code: Alles auswählen
##IMPORT
import requests
from bs4 import BeautifulSoup
#
#
##VARIABLES
URL = 'https://testurl.de/beispielseite'
headers = {"My-User-Agent-placeholder"'}
page = requests.get(URL, headers=headers)
soup = BeautifulSoup(page.content, 'html.parser')
link_list = [div.a for div in soup.findAll ('div', attrs={'class' : 'news-morelink'})]
##
#
#
##SCRIPT
for link in link_list:
print ("https://testurl.de.de/"+(link_list['href']))
'
Re: 'for in'-Zeile als Variable schreiben
Verfasst: Donnerstag 26. Dezember 2019, 19:40
von __blackjack__
@seemarc: Diese ``for``-Schleife ist so nicht sinnvoll. Du gehst über jedes Element in `link_list` und benutzt das (`link`) *in* der Schleife gar nicht, sondern versuchst auf `link_list` was auch tatsächlich eine Liste ist, mit einer Zeichenkette zuzugreifen, was schlicht nicht geht, denn als Index bei Listen kann man nur ganze Zahlen verwenden. An der Stelle willst Du wahrscheinlich eigentlich die Schleifenlaufvariable `link` verwenden, denn die Elemente stehen ja für <a>-Tags und die haben ein 'href'-Attribut auf das man so zugreifen kann.
Edit: `page` ist ein irreführender Name weil die Seite nur ein Teil der Antwort vom Server ist. Statt `findAll()` sollte man `find_all()` verwenden. Die unkonventionell benannten Methodennamen werden irgendwann bei einem Update von BeautifulSoup verschwinden. Das `class`-Attribut wird speziell behandelt, da kann man bei `find_all()` & Co einfach den Klassennamen als zweites Argument angeben und muss da kein Wörterbuch für anlegen.
Re: 'for in'-Zeile als Variable schreiben
Verfasst: Donnerstag 26. Dezember 2019, 19:44
von Sirius3
Wo ist das Problem? Du weißt schon, wie man Listen z.B. mit List-Comprehension erzeugt. Das mußt Du doch nur auf Deine URLs anwenden.
Deine Kommentare sind übrigens wenig hilfreich. Dass ganz am Anfang Importe stehen, sieht man am ›import‹. Das was Du als VARIABLES beschreibst, sind zum einen Konstanten zum anderen nicht vom SCRIPT zu unterscheiden, weil da ja auch schon weitere Funktionen aufgerufen werden. Alles was da SCRIPT heißt und auch der Teil davor gehört eigentlich in eine Funktion. Variablennamen sollten nicht den Typ im Namen haben, denn der könnte sich leicht ändern, z.B. könnte man ohne weiteres aus der link_liste einen Generator machen. ›findAll‹ sollte man nicht mehr verwenden, weil es nicht der Namenskonvention entspricht. Dafür gibt es nun ›find_all‹. In der letzten Zeile versuchst Du auch auf die Liste link_list mit einem String zugreifen, was nicht funktionieren kann. `link` wird dagegen gar nicht verwendet.
URLs setzt man mit urllib.parse.urljoin zusammen.
Code: Alles auswählen
import requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin
URL = 'https://testurl.de/beispielseite.html'
def main():
headers = {"My-User-Agent-placeholder"}
page = requests.get(URL, headers=headers)
soup = BeautifulSoup(page.content, 'html.parser')
links = [div.a for div in soup.find_all('div', attrs={'class' : 'news-morelink'})]
for link in link_list:
print(urljoin(URL, link['href']))
if __name__ == '__main__':
main()
Re: 'for in'-Zeile als Variable schreiben
Verfasst: Donnerstag 26. Dezember 2019, 20:00
von seemarc
@sirius3 @__blackjack__
Erstmal danke euch beiden für die schnelle Antwort. Das es statt "findAll" auch "find_all" gibt wusste ich nicht. Hab es entsprechend geändert.
@__blackjack__
"page" werde ich dann ändern dankschön

@sirius3
Manchmal sieht man den Wald vor lauter Bäumen nicht. Vielen Dank

Re: 'for in'-Zeile als Variable schreiben
Verfasst: Donnerstag 26. Dezember 2019, 20:19
von seemarc
Weitere Frage wenn ich "main()" (siehe Kommentar @sirius3) nun nochmal als zweite (gleiche) Prozedur mit beispielsweise dem Namen "test()" definiere, und dann:
durchlaufen lasse, wird dann der Output (also die URLs) oder die Prozedur miteinander verglichen?
Re: 'for in'-Zeile als Variable schreiben
Verfasst: Donnerstag 26. Dezember 2019, 21:26
von snafu
Es wird natürlich die Rückgabe verglichen, da du die Funktion aufrufst. Wenn du das eigentliche Funktionsobjekt prüfen willst, dann musst du die Klammern auf beiden Seiten weglassen.
Angemerkt sei, dass man letzteres nur tun sollte, wenn man sehr gute Gründe dafür hat. Eigentlich braucht man das fast nie. Funktionsobjekte werden höchstens mal herumgereicht, wenn man sie als Callbacks verwendet. Will man hingegen eine Art Typprüfung vornehmen, dann nutzt man dafür Klassen-Exemplare und die isinstance()-Funktion.
Re: 'for in'-Zeile als Variable schreiben
Verfasst: Donnerstag 26. Dezember 2019, 22:47
von __blackjack__
Wobei man da vielleicht dann auch gleich dazu sagen sollte das man auch für eine Typprüfung mit `isinstance()` einen guten Grund haben sollte, denn Typprüfung ist in objektorientierten Programmiersprachen eine „code smell“. Das ist in wenigen Fällen sinnvoll, aber in der Regel ein Hinweis auf ein Problem beim Entwurf.
Re: 'for in'-Zeile als Variable schreiben
Verfasst: Freitag 27. Dezember 2019, 10:09
von seemarc
Alles klar vielen Dank.