Unmark fetch anime and play as BROKEN and fix type errors (#8988)
* updating DIRECTORY.md
* type(fetch-anime-and-play): Fix type errors and re-enable
* updating DIRECTORY.md
---------
Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
5f7819e1cd
commit
945803f65d
186
web_programming/fetch_anime_and_play.py
Normal file
186
web_programming/fetch_anime_and_play.py
Normal file
@@ -0,0 +1,186 @@
|
||||
import requests
|
||||
from bs4 import BeautifulSoup, NavigableString, Tag
|
||||
from fake_useragent import UserAgent
|
||||
|
||||
BASE_URL = "https://ww1.gogoanime2.org"
|
||||
|
||||
|
||||
def search_scraper(anime_name: str) -> list:
|
||||
"""[summary]
|
||||
|
||||
Take an url and
|
||||
return list of anime after scraping the site.
|
||||
|
||||
>>> type(search_scraper("demon_slayer"))
|
||||
<class 'list'>
|
||||
|
||||
Args:
|
||||
anime_name (str): [Name of anime]
|
||||
|
||||
Raises:
|
||||
e: [Raises exception on failure]
|
||||
|
||||
Returns:
|
||||
[list]: [List of animes]
|
||||
"""
|
||||
|
||||
# concat the name to form the search url.
|
||||
search_url = f"{BASE_URL}/search/{anime_name}"
|
||||
|
||||
response = requests.get(
|
||||
search_url, headers={"UserAgent": UserAgent().chrome}
|
||||
) # request the url.
|
||||
|
||||
# Is the response ok?
|
||||
response.raise_for_status()
|
||||
|
||||
# parse with soup.
|
||||
soup = BeautifulSoup(response.text, "html.parser")
|
||||
|
||||
# get list of anime
|
||||
anime_ul = soup.find("ul", {"class": "items"})
|
||||
if anime_ul is None or isinstance(anime_ul, NavigableString):
|
||||
msg = f"Could not find and anime with name {anime_name}"
|
||||
raise ValueError(msg)
|
||||
anime_li = anime_ul.children
|
||||
|
||||
# for each anime, insert to list. the name and url.
|
||||
anime_list = []
|
||||
for anime in anime_li:
|
||||
if isinstance(anime, Tag):
|
||||
anime_url = anime.find("a")
|
||||
if anime_url is None or isinstance(anime_url, NavigableString):
|
||||
continue
|
||||
anime_title = anime.find("a")
|
||||
if anime_title is None or isinstance(anime_title, NavigableString):
|
||||
continue
|
||||
|
||||
anime_list.append({"title": anime_title["title"], "url": anime_url["href"]})
|
||||
|
||||
return anime_list
|
||||
|
||||
|
||||
def search_anime_episode_list(episode_endpoint: str) -> list:
|
||||
"""[summary]
|
||||
|
||||
Take an url and
|
||||
return list of episodes after scraping the site
|
||||
for an url.
|
||||
|
||||
>>> type(search_anime_episode_list("/anime/kimetsu-no-yaiba"))
|
||||
<class 'list'>
|
||||
|
||||
Args:
|
||||
episode_endpoint (str): [Endpoint of episode]
|
||||
|
||||
Raises:
|
||||
e: [description]
|
||||
|
||||
Returns:
|
||||
[list]: [List of episodes]
|
||||
"""
|
||||
|
||||
request_url = f"{BASE_URL}{episode_endpoint}"
|
||||
|
||||
response = requests.get(url=request_url, headers={"UserAgent": UserAgent().chrome})
|
||||
response.raise_for_status()
|
||||
|
||||
soup = BeautifulSoup(response.text, "html.parser")
|
||||
|
||||
# With this id. get the episode list.
|
||||
episode_page_ul = soup.find("ul", {"id": "episode_related"})
|
||||
if episode_page_ul is None or isinstance(episode_page_ul, NavigableString):
|
||||
msg = f"Could not find any anime eposiodes with name {anime_name}"
|
||||
raise ValueError(msg)
|
||||
episode_page_li = episode_page_ul.children
|
||||
|
||||
episode_list = []
|
||||
for episode in episode_page_li:
|
||||
if isinstance(episode, Tag):
|
||||
url = episode.find("a")
|
||||
if url is None or isinstance(url, NavigableString):
|
||||
continue
|
||||
title = episode.find("div", {"class": "name"})
|
||||
if title is None or isinstance(title, NavigableString):
|
||||
continue
|
||||
|
||||
episode_list.append(
|
||||
{"title": title.text.replace(" ", ""), "url": url["href"]}
|
||||
)
|
||||
|
||||
return episode_list
|
||||
|
||||
|
||||
def get_anime_episode(episode_endpoint: str) -> list:
|
||||
"""[summary]
|
||||
|
||||
Get click url and download url from episode url
|
||||
|
||||
>>> type(get_anime_episode("/watch/kimetsu-no-yaiba/1"))
|
||||
<class 'list'>
|
||||
|
||||
Args:
|
||||
episode_endpoint (str): [Endpoint of episode]
|
||||
|
||||
Raises:
|
||||
e: [description]
|
||||
|
||||
Returns:
|
||||
[list]: [List of download and watch url]
|
||||
"""
|
||||
|
||||
episode_page_url = f"{BASE_URL}{episode_endpoint}"
|
||||
|
||||
response = requests.get(
|
||||
url=episode_page_url, headers={"User-Agent": UserAgent().chrome}
|
||||
)
|
||||
response.raise_for_status()
|
||||
|
||||
soup = BeautifulSoup(response.text, "html.parser")
|
||||
|
||||
url = soup.find("iframe", {"id": "playerframe"})
|
||||
if url is None or isinstance(url, NavigableString):
|
||||
msg = f"Could not find url and download url from {episode_endpoint}"
|
||||
raise RuntimeError(msg)
|
||||
|
||||
episode_url = url["src"]
|
||||
if not isinstance(episode_url, str):
|
||||
msg = f"Could not find url and download url from {episode_endpoint}"
|
||||
raise RuntimeError(msg)
|
||||
download_url = episode_url.replace("/embed/", "/playlist/") + ".m3u8"
|
||||
|
||||
return [f"{BASE_URL}{episode_url}", f"{BASE_URL}{download_url}"]
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
anime_name = input("Enter anime name: ").strip()
|
||||
anime_list = search_scraper(anime_name)
|
||||
print("\n")
|
||||
|
||||
if len(anime_list) == 0:
|
||||
print("No anime found with this name")
|
||||
else:
|
||||
print(f"Found {len(anime_list)} results: ")
|
||||
for i, anime in enumerate(anime_list):
|
||||
anime_title = anime["title"]
|
||||
print(f"{i+1}. {anime_title}")
|
||||
|
||||
anime_choice = int(input("\nPlease choose from the following list: ").strip())
|
||||
chosen_anime = anime_list[anime_choice - 1]
|
||||
print(f"You chose {chosen_anime['title']}. Searching for episodes...")
|
||||
|
||||
episode_list = search_anime_episode_list(chosen_anime["url"])
|
||||
if len(episode_list) == 0:
|
||||
print("No episode found for this anime")
|
||||
else:
|
||||
print(f"Found {len(episode_list)} results: ")
|
||||
for i, episode in enumerate(episode_list):
|
||||
print(f"{i+1}. {episode['title']}")
|
||||
|
||||
episode_choice = int(input("\nChoose an episode by serial no: ").strip())
|
||||
chosen_episode = episode_list[episode_choice - 1]
|
||||
print(f"You chose {chosen_episode['title']}. Searching...")
|
||||
|
||||
episode_url, download_url = get_anime_episode(chosen_episode["url"])
|
||||
print(f"\nTo watch, ctrl+click on {episode_url}.")
|
||||
print(f"To download, ctrl+click on {download_url}.")
|
||||
Reference in New Issue
Block a user