// Given a show pointer, appends all the seasons/episodes found for the show func (show *CrunchyrollShow) ScrapeEpisodes(showURL string, cookies []*http.Cookie) error { // Gets the HTML of the show page showResponse, err := anirip.GetHTTPResponse("GET", showURL, nil, nil, cookies) if err != nil { return err } // Creates a goquery document for scraping showDoc, err := goquery.NewDocumentFromResponse(showResponse) if err != nil { return anirip.Error{Message: "There was an error while accessing the show page", Err: err} } // Scrapes the show metadata from the show page showMetaDataJSON := showDoc.Find("script#liftigniter-metadata").First().Text() // Parses the metadata json to a ShowMetaData object showMetaData := new(ShowMetaData) if err := json.Unmarshal([]byte(showMetaDataJSON), showMetaData); err != nil { return anirip.Error{Message: "There was an error while parsing show metadata", Err: err} } // Sets Title, and Path and URL on our show object show.Title = showMetaData.Name show.URL = showMetaData.URL show.Path = strings.Replace(show.URL, "http://www.crunchyroll.com", "", 1) // Removes the host so we have just the path // Searches first for the search div showDoc.Find("ul.list-of-seasons.cf").Each(func(i int, seasonList *goquery.Selection) { seasonList.Find("li.season").Each(func(i2 int, episodeList *goquery.Selection) { // Adds a new season to the show containing all information seasonTitle, _ := episodeList.Find("a").First().Attr("title") // Adds the title minus any "Episode XX" for shows that only have one season show.Seasons = append(show.Seasons, CrunchyrollSeason{ Title: strings.SplitN(seasonTitle, " Episode ", 2)[0], }) // Within that season finds all episodes episodeList.Find("div.wrapper.container-shadow.hover-classes").Each(func(i3 int, episode *goquery.Selection) { // Appends all new episode information to newly appended season episodeTitle := strings.TrimSpace(strings.Replace(episode.Find("span.series-title.block.ellipsis").First().Text(), "\n", "", 1)) episodeNumber, _ := strconv.ParseFloat(strings.Replace(episodeTitle, "Episode ", "", 1), 64) episodePath, _ := episode.Find("a").First().Attr("href") episodeID, _ := strconv.Atoi(episodePath[len(episodePath)-6:]) show.Seasons[i2].Episodes = append(show.Seasons[i2].Episodes, CrunchyrollEpisode{ ID: episodeID, Title: episodeTitle, Number: episodeNumber, Path: episodePath, URL: "http://www.crunchyroll.com" + episodePath, }) }) }) }) // Re-arranges seasons and episodes in the shows object so we have first to last tempSeasonArray := []CrunchyrollSeason{} for i := len(show.Seasons) - 1; i >= 0; i-- { // First sort episodes from first to last tempEpisodesArray := []CrunchyrollEpisode{} for n := len(show.Seasons[i].Episodes) - 1; n >= 0; n-- { tempEpisodesArray = append(tempEpisodesArray, show.Seasons[i].Episodes[n]) } // Lets not bother appending anything if there are no episodes in the season if len(tempEpisodesArray) > 0 { tempSeasonArray = append(tempSeasonArray, CrunchyrollSeason{ Title: show.Seasons[i].Title, Length: len(tempEpisodesArray), Episodes: tempEpisodesArray, }) } } show.Seasons = tempSeasonArray // Assigns each season a number and episode a filename for s, season := range show.Seasons { show.Seasons[s].Number = s + 1 for e, episode := range season.Episodes { show.Seasons[s].Episodes[e].FileName = anirip.GenerateEpisodeFileName(show.Title, show.Seasons[s].Number, episode.Number, "") } } // TODO Filter out episodes that aren't yet released (ex One Piece) return nil }
// Given a show pointer, appends all the seasons/episodes found for the show func (show *DaisukiShow) ScrapeEpisodes(showURL string, cookies []*http.Cookie) error { // Gets the HTML of the show page showResponse, err := anirip.GetHTTPResponse("GET", showURL, nil, nil, cookies) if err != nil { return err } // Creates a goquery document for scraping episodes showDoc, err := goquery.NewDocumentFromResponse(showResponse) if err != nil { return anirip.Error{Message: "There was an error while accessing the show page", Err: err} } // Sets Title, AdID and Path in the case where the user passes a show URL if show.Title == "" { show.Title = showDoc.Find("h1#animeTitle").First().Text() // Scrapes the show title fromt he season body if it wasn't set by a search } if show.URL == "" { show.URL = showURL } if show.Path == "" { show.Path = strings.Replace(show.URL, "http://www.daisuki.net", "", 1) // Removes the host so we have just the path } if show.AdID == "" { show.AdID = strings.Replace(show.URL, "http://www.daisuki.net/us/en/anime/detail.", "", 1) // Removes the leading path show.AdID = strings.Replace(show.AdID, ".html", "", 1) // Replaces the .html so we have just the AdID } // Searches first for the episodes/movies episodeMap := make(map[int]string) showDoc.Find("div#moviesBlock").Each(func(i int, season *goquery.Selection) { // Finds the non-movie/latest-or-first episode and adds it to our map season.Find("div#content0.content.clearFix.liquid").Each(func(i2 int, movieEpisode *goquery.Selection) { // Gets the episode number from that movie episodeThumb, exists := movieEpisode.Find("img").First().Attr("delay") episodeNumber, err := strconv.Atoi(movieEpisode.Find("p.episodeNumber").Text()) if err == nil && exists && episodeThumb != "" { episodeMap[episodeNumber] = "/us/en/anime/watch." + strings.Split(episodeThumb, "/")[6] + "." + strings.Split(episodeThumb, "/")[7] + ".html" } }) // Finds ALL non-movie/latest-or-first episodes season.Find("div#contentList0.contentList.clearFix.liquid div.item").Each(func(i2 int, episodeItem *goquery.Selection) { // Grabs episode information that isn't empty and has a url associated with an episode number episodeThumb, exists := episodeItem.Find("img").First().Attr("delay") episodeNumber, err := strconv.Atoi(episodeItem.Find("p.episodeNumber").Text()) if err == nil && exists && episodeThumb != "" { episodeMap[episodeNumber] = "/us/en/anime/watch." + strings.Split(episodeThumb, "/")[6] + "." + strings.Split(episodeThumb, "/")[7] + ".html" } }) }) // Re-arranges seasons and episodes in the shows object so we have first to last show.Seasons = append(show.Seasons, DaisukiSeason{ // appends a new season that we'll append episodes to Title: show.Title, Number: 1, Length: len(episodeMap), }) for i := 0; i < len(episodeMap); i++ { show.Seasons[0].Episodes = append(show.Seasons[0].Episodes, DaisukiEpisode{ Number: float64(i + 1), Path: episodeMap[i+1], URL: "http://www.daisuki.net" + episodeMap[i+1], }) } // Assigns each season a number and episode a filename for s, season := range show.Seasons { for e, episode := range season.Episodes { // Generates a partial file name that we'll later improve on when we get the episode html show.Seasons[s].Episodes[e].FileName = anirip.GenerateEpisodeFileName(show.Title, show.Seasons[s].Number, episode.Number, "") } } return nil }