Seite 1 von 1

redirect/überprüfungs Problem

Verfasst: Donnerstag 13. Januar 2022, 20:02
von FlorianW
Hallo ich bin relativ neu in Python und möchte ein Konsolenprogramm schreiben, welches für mich automatisch Animefolgen downloaded.

Ich habe mich für die Website https://anicloud.io/ entschieden weil sie legal ist/sein sollte.

ich habe bereits eine "such function" geschrieben, die mithilfe von requests_html und lxml arbeitet.

Code: Alles auswählen

searchUrlResults = []
searchNameResluts = []
def searchAnime(animeName):
    page_url = "https://anicloud.io/search?q=" + animeName.replace(" ", "+")
    html_parser = etree.HTMLParser()
    session = HTMLSession()
    resp = session.get(page_url)
    resp.html.render()
    web_page = resp.html.html
    str_io_obj = StringIO(web_page)
    dom_tree = etree.parse(str_io_obj, parser=html_parser)
    searchResults_list = dom_tree.xpath('//*[@id="searchResults"]')
    session.close()
    for a in searchResults_list:
        listChildren = a.getchildren()

        for c in listChildren:
            cChildren = c.getchildren()
            for cc in cChildren:
                episodeUrl = cc.get("href")

                if episodeUrl.startswith("/anime/stream/"):
                    if "staffel" in str(episodeUrl):
                        episodeUrl = "".join([j for j in episodeUrl if not j.isdigit()])
                        episodeUrl = episodeUrl.replace("/staffel-/episode-", "")
                    
                    if episodeUrl not in searchUrlResults:
                        searchUrlResults.append(episodeUrl)

                    episodeUrl = episodeUrl.replace("-", " ")
                    episodeUrl = episodeUrl.replace("/anime/stream/", "")
                    
                    if episodeUrl not in searchNameResluts:
                        searchNameResluts.append(episodeUrl)
außerdem habe ich eine funktion die alle Episoden "holt"

Code: Alles auswählen

def getEpisodes(url):
    episodes = []
    html_parser = etree.HTMLParser()
    session = HTMLSession()
    resp = session.get(url)
    resp.html.render()
    web_page = resp.html.html
    str_io_obj = StringIO(web_page)
    dom_tree = etree.parse(str_io_obj, parser=html_parser)
    selectedElement = dom_tree.xpath('//*[@id="stream"]/ul[2]')
    session.close()

    for a in selectedElement:
        aListChildren = a.getchildren()

        for b in aListChildren:
            bListChildren = b.getchildren()

            for c in bListChildren:
                link = c.get("href")
                if isinstance(link, str):
                    episodes.append(link)

    return episodes
Und eine Function die alle Staffeln "holt"

Code: Alles auswählen

def getEpisodes(url):
    episodes = []
    html_parser = etree.HTMLParser()
    session = HTMLSession()
    resp = session.get(url)
    resp.html.render()
    web_page = resp.html.html
    str_io_obj = StringIO(web_page)
    dom_tree = etree.parse(str_io_obj, parser=html_parser)
    selectedElement = dom_tree.xpath('//*[@id="stream"]/ul[2]')
    session.close()

    for a in selectedElement:
        aListChildren = a.getchildren()

        for b in aListChildren:
            bListChildren = b.getchildren()

            for c in bListChildren:
                link = c.get("href")
                if isinstance(link, str):
                    episodes.append(link)

    return episodes
Ich habe auch eine Function die Videos downloaded

Code: Alles auswählen

def downloadFile(fileName, downloadLink):
    print("connecting...")
    r = requests.get(downloadLink, stream=True)
    print("CONNECTED")
    with open(fileName, "wb") as f:

        total_length = int(r.headers.get('content-length'))

        for ch in progress.bar(r.iter_content(chunk_size = 255), expected_size=(total_length/255)):
            if ch:
                f.write(ch)
    print("DOWNLOAD FINISHED " + fileName)
Also brauche ich nur noch eine Funktion mit der ich die Video Url bekomme.

Ich habe mich für den Dienst https://vidoza.net/ entschieden weil man von dort sehr einfach den Link zur mp4 Datei bekommen kann.
Das Problem ist, dass ich gar nicht erst auf die Seite komme weil ich "redirected" und/oder auch "überprüft" werde.

Kann man vielleicht den "redirect" umgehen?
Oder Gibt es ein Modul welches das ermöglicht?
Ich würde mich Freuen, wenn mir Jemand helfen könnte.
Danke schonmal im vor raus :)

Re: redirect/überprüfungs Problem

Verfasst: Donnerstag 13. Januar 2022, 21:53
von __blackjack__
@FlorianW: Die Seite scheint eine API anzubieten. In Verbindung damit, dass der ”Redirect” auf dem Du von der ersten Seite aus landest ein Captcha enthalten kann, um zu prüfen ob das da ein Mensch abruft und kein Programm, *will* der Anbieter das offensichtlich *nicht* was Du da vorhast.

Re: redirect/überprüfungs Problem

Verfasst: Donnerstag 13. Januar 2022, 23:59
von FlorianW
Also gibt es dafür keine Lösung, kann ich das Programm nicht beenden? :/

Re: redirect/überprüfungs Problem

Verfasst: Freitag 14. Januar 2022, 08:40
von sparrow
Nicht auf dem Weg. Schau dir die API an und guck, ob dort angeboten wird, was du machen möchtest.

Re: redirect/überprüfungs Problem

Verfasst: Freitag 14. Januar 2022, 10:19
von __blackjack__
@FlorianW: Du kannst auch schauen ob eine der anderen Quellen sich nicht so sehr dagegen sträubt automatisiert abgefragt zu werden.

Anmerkungen zum Quelltext: Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (PascalCase).

Namen sollten nicht kryptisch abgekürzt werden. Drei verschachtelte Schleifen die über `a`, `c`, und `cc` oder `a`, `b`, und `c` laufen sind nicht wirklich verständlich. Zumal das auch nicht wirklich robust ist.

`requests_html` wird auf mehrere Arten falsch verwendet. Zum Beispiel ist es nicht Sinn eines `HTMLSession`-Objektes das man da für jede Anfrage ein neues von erstellt. Ebenfalls unsinnig ist das abfragen des HTMLs von einem Response-Objekt um das dann in ein `StringIO` zu stecken um dass dann an `lxml.etree` zu verfüttern. Das alles hat `requests_html` doch bereits gemacht, darum verwendet man das doch gegenüber reinem `requests`, weil das diesen granzen Kram bereits erledigt. Der Code der beiden Funktionen die das machen kann deutlich kürzer sein.

(Selbst wenn `requests_html` das nicht machen würde — man würde das dann nicht in jede Funktion rein schreiben, sondern das selbst in eine Funktion heraus ziehen.)

`HTMLSession`-Objekte sind Kontextmanager, die sollte man mit der ``with``-Anweisung verwenden.

Den Query-String bastelt man nicht selbst zusammen, das kann/macht `get()` bereits wenn man die Daten separat als Parameter-Argument übergibt. Wenn man das robust machen will ist das auch ein bisschen mehr als Leerzeichen durch "+" zu ersetzen.

`requests_html` parst nicht nur in einen `lxml`-Objektbaum, sondern bietet auch CSS-Selektoren + jQuery-Erweiterungen. Das wäre einfacher als einen XPath zu formulieren der ein `id`-Attribut sucht.

Was in `searchAnime()` an Zeichenkettenoperationen mit den URLs gemacht wird, sieht nicht robust aus.

Die Funktion verändert globale Listen — ganz Böse™. Funktionen kommunizieren über Argumente und Rückgabewerte, nicht über globale Variablen. In `getEpisodes()` wird es ja richtig gemacht.

Dass das Listen sind ist von der Effizienz nicht so toll wenn man da immer mit ``not in`` schaut ob etwas bereits enthalten ist. Da würden sich `set()`-Objekte eher anbieten.

Mit "href" und Zeichenketten scheint es ein Problem beim verständnis zu geben. Das sind Zeichenketten, die braucht man weder mit `str()` umwandeln noch mit `isinstance()` prüfen. Und falls dieser Unsinn gemacht wird weil `get()` auch `None` liefern könnte: dann testet man *das* explizit und verschleiert das nicht mit anderen komischen Aktionen.

Re: redirect/überprüfungs Problem

Verfasst: Freitag 14. Januar 2022, 15:52
von FlorianW
@__blackjack__ Vielen dank für die ganzen Informationen ich werde meinen Code überarbeiten^^
@sparrow danke ich werde mir die API angucken