AngleSharpで画像スクレイピング
まずは,この辺を一読します.
HttpClientをusingで囲わないでください - Qiita
C#でモダンにスクレイピングするならAngleSharp - Qiita
背景
ある方のブログをよく見ているのですが,印刷した際に画像が小さく,ちょっと見にくくなってます・・・.
そこで,HTMLを解析して,画像だけ頂いちゃおうっていうのが今回の狙いです.
開発環境
Windows7(サポート切れごめんなさい)
VisualStudio2019 16.5.4
.net Framework 4.7.2
まずはNuGet
まずはNuGetでAngleSharpを落としてきます.
さっそくコード!
んで,書いていきますが,HttpClientをusingで囲わないでください - Qiitaのとおり,メンバーにHttpClientを宣言します.
批判しているわけではないですが,他のQiita記事はusingしてます.
実は,ある方のブログ専用で作ってる関係で,記事ごとのタイトルと記事ごとのURLが取得済みなので,その前提で話が進みます・・・.
メンバー
static WebProxy proxy = new WebProxy(@"proxyserver.co.jp:portNO"); //必要であれば static HttpClientHandler handler = new HttpClientHandler() { Proxy = proxy, }; // HttpClient is intended to be instantiated once per application, rather than per-use. See Remarks. static readonly HttpClient client = new HttpClient(handler); public Form1() { InitializeComponent(); }
スクレイピング部
private async System.Threading.Tasks.Task scrapper(string urlstring, string folder) { var doc = default(IHtmlDocument); using (var stream = await client.GetStreamAsync(new Uri(urlstring))) { HtmlParser parser = new HtmlParser(); //htmlパーサーにぶっこむ doc = await parser.ParseDocumentAsync(stream); } var imgTag = doc.QuerySelectorAll("img");// HTMLからimgタグの値を取得する foreach (IHtmlImageElement n in imgTag) { string uri = n.Source; string[] parser = { "?" }; if ((uri.Contains("png") || uri.Contains("jpg")) && uri.Contains("落としたいブログのユーザ名")) { Debug.WriteLine(uri.Split(parser, StringSplitOptions.RemoveEmptyEntries)[0]); FileDownload(uri.Split(parser, StringSplitOptions.RemoveEmptyEntries)[0], folder); } } }
ファイルダウンロード部
private void FileDownload(string url, string folder) { try { string path = System.IO.Directory.GetCurrentDirectory() + "\\" + folder; if (!Directory.Exists(path)) { System.IO.DirectoryInfo di = System.IO.Directory.CreateDirectory(path); } HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url); req.UserAgent = "Chromeなどのブラウザのユーザエージェント"; req.Proxy = proxy; string[] sep = { "/" }; string[] fileName = url.Split(sep, StringSplitOptions.RemoveEmptyEntries); WebResponse res = req.GetResponse(); using (Stream st = res.GetResponseStream()) { using (FileStream fs = new FileStream(path +"\\" + fileName.Last(), FileMode.Create)) { st.CopyTo(fs); //ストリームのコピー(.NET Framework 4以降) } } } catch (WebException exc) { } }
ボタンクリック部
private async void button1_ClickAsync(object sender, EventArgs e) { //TextBoxに入力するフォーマットは URL,フォルダ名 です. StringReader rs = new System.IO.StringReader(textBox1.Text);//StringReaderにテキストボックスをぶっこむ while (rs.Peek() > -1)//1行ずつ読み込んで { string[] sep = { "," }; string[] paths = rs.ReadLine().ToString().Split(sep, StringSplitOptions.RemoveEmptyEntries);//カンマで分ける await scrapper(paths[0],paths[1]); } Debug.WriteLine("END"); }
実行結果
こんな感じで,実行ファイルと同じフォルダに格納できました!