// 웹툰 리스트 페이지의 글로벌 정보를 가져오는 메소드 // ex : http://comic.naver.com/webtoon/list.nhn?titleId=570503&weekday=thu public static WebtoonListPageInformations?GetWebtoonListPageInformations(string url) { try { HttpWebRequest request = ( HttpWebRequest )WebRequest.Create(url); request.Method = "GET"; request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36"; using (HttpWebResponse response = ( HttpWebResponse )request.GetResponse( )) { using (Stream responseStream = response.GetResponseStream( )) { HtmlDocument document = new HtmlDocument( ); document.Load(responseStream, Encoding.UTF8); WebtoonListPageInformations data = new WebtoonListPageInformations( ); foreach (HtmlNode i in document.DocumentNode.SelectNodes("//meta")) { switch (i.GetAttributeValue("property", "")) { case "og:title": // 웹툰 이름 data.title = HttpUtility.HtmlDecode(i.GetAttributeValue("content", "")); break; case "og:description": // 수정 필요 data.description = HttpUtility.HtmlDecode(i.GetAttributeValue("content", "")); break; case "og:image": // 웹툰 썸네일 data.thumbnail = i.GetAttributeValue("content", ""); break; } } HtmlNode webtoonAuthorLabel = document.DocumentNode.SelectSingleNode("//span[@class=\"wrt_nm\"]"); // 웹툰 작가 이름 찾기 -> author data.author = webtoonAuthorLabel.InnerText.Trim( ); data.url = url; return(data); } } } catch (Exception ex) { Util.WriteErrorLog(ex.Message, Util.LogSeverity.EXCEPTION); return(null); } }
public static void GetWebtoonListPageInformations(string url) { try { HttpWebRequest request = ( HttpWebRequest )WebRequest.Create(url); request.Method = "GET"; request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36"; using (HttpWebResponse response = ( HttpWebResponse )request.GetResponse( )) { using (Stream responseStream = response.GetResponseStream( )) { HtmlDocument document = new HtmlDocument( ); document.Load(responseStream, Encoding.UTF8); WebtoonListPageInformations data = new WebtoonListPageInformations( ); foreach (HtmlNode i in document.DocumentNode.SelectNodes("//meta")) { switch (i.GetAttributeValue("property", "")) { case "og:title": data.title = HttpUtility.HtmlDecode(i.GetAttributeValue("content", "")); break; case "og:description": data.description = HttpUtility.HtmlDecode(i.GetAttributeValue("content", "")); break; case "og:image": data.thumbnail = i.GetAttributeValue("content", ""); break; } } int maxListPage = GetWebtoonListPageMaxPage(url); if (maxListPage > 0) { //File.AppendAllText( "data.txt", data.title + "\n" + data.description + "\n" + data.thumbnail + "\n\n" ); data.specificPageInformations = new List <WebtoonListSpecificPageInformations>( ); for (int currentListPage = 1; currentListPage <= maxListPage; currentListPage++) { if (currentListPage != 2) { continue; // for test } Console.WriteLine(currentListPage + " / " + maxListPage); List <WebtoonListSpecificPageInformations> specificPageInformations = GetInternalWebtoonListPageInformations(url, currentListPage); if (specificPageInformations != null) { data.specificPageInformations = data.specificPageInformations.Concat(specificPageInformations).ToList( ); } } //File.AppendAllText( "data.txt", maxListPage + " -> maxpage > \n\n\n" ); foreach (WebtoonListSpecificPageInformations i in data.specificPageInformations) { //File.AppendAllText( "data.txt", i.title + "/" + i.starRate + "/" + i.uploadDate + " \n" ); } } else { } //Console.WriteLine( data.title + Environment.NewLine + data.description + Environment.NewLine + data.thumbnail ); //} } } } catch (Exception ex) { Console.WriteLine(ex); } }
// 웹툰을 다운로드 할 때 호출하는 메소드 // <!> 위의 메소드들은 전부 이 메소드 안에서 호출됨 public static void Download(WebtoonListPageInformations info, string baseDir, Action <string> MessageChangeCallBack, Action <WebtoonListSpecificPageInformations> DownloadPageChanged, Action <float, float> DownloadProgressChanged, Action <bool> WorkFinished, Action <string> ErrorHandler) { try { int maxListPage = GetWebtoonListPageMaxPage(info.url); if (maxListPage > 0) { info.specificPageInformations = new List <WebtoonListSpecificPageInformations>( ); int totalDownloadImageCount = 0; int currentDownloadImageCount = 0; for (int currentListPage = 1; currentListPage <= maxListPage; currentListPage++) { List <WebtoonListSpecificPageInformations> specificPageInformations = GetInternalWebtoonListPageInformations(info.url, currentListPage); if (specificPageInformations != null) { info.specificPageInformations = info.specificPageInformations.Concat(specificPageInformations).ToList( ); } foreach (WebtoonListSpecificPageInformations i in specificPageInformations) { if (i.contents == null) { continue; } totalDownloadImageCount += i.contents.Count; } MessageChangeCallBack.Invoke("서버에서 기본적인 정보를 불러오는 중 ... [" + currentListPage + "/" + maxListPage + "] <총 " + totalDownloadImageCount + "개 이미지>"); } try { if (GlobalVar.DownloadSections == null) // 다운로드 구간 세부 설정이 없으면? { foreach (WebtoonListSpecificPageInformations i in info.specificPageInformations) { if (i.num >= GlobalVar.BeginDownloadDetailNum && i.num <= GlobalVar.EndDownloadDetailNum) { string path = baseDir + "\\" + (i.num + " - " + Util.StripFolderName(i.title)); DownloadPageChanged.Invoke(i); MessageChangeCallBack.Invoke(i.num + "화 다운로드 중 ..."); Directory.CreateDirectory(path); Directory.CreateDirectory(path + "\\데이터"); if (!DownloadImageResourceCompress(i.thumbnail, path + @"\데이터\thumanail.jpg")) { ErrorHandler.Invoke("썸네일 이미지를 다운로드 하지 못했습니다."); } if (GlobalVar.BGMDownloadOption && !string.IsNullOrEmpty(i.bgm)) { if (!DownloadResource(i.bgm, path + @"\데이터\bgm.mp3")) { ErrorHandler.Invoke("BGM 데이터를 다운로드 하지 못했습니다."); } } int count = 0; foreach (string i2 in i.contents) { if (!DownloadImageResourceCompress(i2, path + @"\데이터\" + ++count + "_image.jpg")) { ErrorHandler.Invoke("이미지 데이터를 다운로드 하지 못했습니다."); } DownloadProgressChanged.Invoke(0, ( float )++currentDownloadImageCount / ( float )totalDownloadImageCount); //( ( float ) count / ( float ) i.contents.Count ), Util.AppliactionDelay(10); } if (GlobalVar.ViewerCreateOption) // HTML 뷰어 생성 { BrowserViewer.Create( info.title + " - " + i.title, path, i.url, count, !string.IsNullOrEmpty(i.bgm), null ); } } } } else { foreach (WebtoonListSpecificPageInformations i in info.specificPageInformations) { if (GlobalVar.DownloadSections.IndexOf(i.num) > -1) { string path = baseDir + "\\" + (i.num + " - " + Util.StripFolderName(i.title)); DownloadPageChanged.Invoke(i); MessageChangeCallBack.Invoke(i.num + "화 다운로드 중 ..."); Directory.CreateDirectory(path); Directory.CreateDirectory(path + "\\데이터"); if (!DownloadImageResourceCompress(i.thumbnail, path + @"\데이터\thumanail.jpg")) { ErrorHandler.Invoke("썸네일 이미지를 다운로드 하지 못했습니다."); } if (GlobalVar.BGMDownloadOption && !string.IsNullOrEmpty(i.bgm)) { if (!DownloadResource(i.bgm, path + @"\데이터\bgm.mp3")) { ErrorHandler.Invoke("BGM 데이터를 다운로드 하지 못했습니다."); } } int count = 0; foreach (string i2 in i.contents) { if (!DownloadImageResourceCompress(i2, path + @"\데이터\" + ++count + "_image.jpg")) { ErrorHandler.Invoke("이미지 데이터를 다운로드 하지 못했습니다."); } DownloadProgressChanged.Invoke(0, ( float )++currentDownloadImageCount / ( float )totalDownloadImageCount); //( ( float ) count / ( float ) i.contents.Count ), Util.AppliactionDelay(10); } if (GlobalVar.ViewerCreateOption) // HTML 뷰어 생성 { BrowserViewer.Create( info.title + " - " + i.title, path, i.url, count, !string.IsNullOrEmpty(i.bgm), null ); } } } } } catch (Exception ex) { Util.WriteErrorLog(ex); } finally { WorkFinished.Invoke(true); } } else { WorkFinished.Invoke(false); } } catch (ThreadAbortException) { GC.Collect(0, GCCollectionMode.Forced); // 다운로드가 종료된 후 남은 리소스를 정리하기 위해 GC 강제 실행 } }