2017-05-27 13 views
0

先ほど書いたように、code snippet私は現在、特定のサブディレクトリから複数の画像をローカルディレクトリに一度に格納しようとしています。私の問題は、LINQ文が正しく機能することができないということです。LINQでSystem.NullReferenceExceptionが発生しました

(...) 
Level 1: <div class="content">...</div> 
    Level 2: <div class="spacer">...</div> 
     Level 3: <div class="siteTable">...</div> 
      Level 4: <div class=" thing id-t3_6dj7qp odd link ">...</div>      
       Level 5: <a class="thumbnail may-blank outbound" href="href="http://i.imgur.com/jZ2ZAyk.jpg"">...</a> 

:私はまた、私はHTMLページを見ていたし、私が取得することを目指しリンクはhref属性の中にレベル5に隠されていることが判明したのはなぜサムネイル画像をダウンロードしたくありませんそれはラインで私の最善の策だった「???」:悲しいことに十分な、それはそれはワットではありません、なぜ

Object reference not set to an instance of an object 

さて、今私が知っていることを示すerrorをスロー

.Where(link => Directory.GetParent(link).Equals(@"http://i.imgur.com")) 

しかし、私はまだラムダ式にはまったく新しいので、この行をどのように書き直すのか分かりません。正直言って、なぜ私が最初にSystem.NullReferenceExceptionを得たのか分からないが、次の行にはない。違いは何ですか?多分この問題に対する私のアプローチはまったく良い練習ではありませんので、どうすれば進んでいくか教えてください。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.IO; 
using System.Net; 
using HtmlAgilityPack; 

namespace GetAllImages 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      List<string> imageLinks = new List<string>(); 

      // Specify Directory manually 
      string dirName = "Jessica Clements"; 
      string rootPath = @"C:\Users\Stefan\Desktop"; 
      string dirPath = Path.Combine(rootPath, dirName); 

      // Specify the subReddit manually 
      string subReddit = "r/Jessica_Clements"; 
      string url = @"https://www.reddit.com/" + subReddit; 

      try 
      { 
       DirectoryInfo imageFolder = Directory.CreateDirectory(dirPath);     

       HtmlDocument document = new HtmlWeb().Load(url); 
       imageLinks = document.DocumentNode.Descendants("a") 
          .Select(element => element.GetAttributeValue("href", null)) 
          .Where(???) 
          .Where(stringLink => !String.IsNullOrEmpty(stringLink)) 
          .ToList(); 

       foreach(string link in imageLinks) 
       { 
        using (WebClient _wc = new WebClient()) 
        { 
         _wc.DownloadFileAsync(new Uri(link), Path.Combine(dirPath, Path.GetFileName(link))); 
        }       
       } 

      Console.WriteLine($"Files successfully saved in '{Path.GetFileName(dirPath)}'.");    

      } 

      catch(Exception e) 
      { 
       while(e != null) 
       { 
        Console.WriteLine(e.Message); 
        e = e.InnerException; 
       } 
      } 

      if(System.Diagnostics.Debugger.IsAttached) 
      { 
       Console.WriteLine("Press any key to continue . . ."); 
       Console.ReadKey(true); 
      } 
     } 
    } 
} 

編集:この行は、例外をスローすることを考えると

HtmlDocument document = new HtmlWeb().Load(url); 
imageLinks = document.DocumentNode.Descendants("a") 
      .Select(element => element.GetAttributeValue("href", null)) 
      .Where(link => (link?.Contains(@"http://i.imgur.com") == true)) 
      .Distinct() 
      .ToList(); 
+0

あなたの問題へのより良いアプローチは、[JSONのAPI](httpsを使用することであるようなものが必要です。// WWWを。 reddit.com/r/Jessica_Clements/.json)を使用してください。 – Nasreddine

答えて

2

:誰かが私はそれが以下の回答を使用して最終的に働かせた方法です。このソリューションに興味があるだけの場合には

.Where(link => Directory.GetParent(link).Equals(@"http://i.imgur.com")) 

私はlinkがnullでないことを確認してくださいしたいとGetParent(link)の結果は、いずれかのnullでないこと。だから、何ができる:

.Where(link => link != null && (Directory.GetParent(link)?.Equals(@"http://i.imgur.com") ?? false)) 

お知らせヌルチェックとGetParent()?.を。 GetParent()からnullが返された場合、この実行は中止されます。それはNull Conditional Operatorまたは "エルヴィスオペレーター"と呼ばれています。なぜなら、それはツイストヘアで2つの目として見ることができるからです。 ?? falseは、NULL値のために実行が停止した場合のデフォルト値を示します。

ただし、HTMLコードを解析する場合は、Html Agility Pack (HAP)を必ずご覧ください。

+0

私は新しい考え方を持っています。そうすれば、リンクがnullにならないようにすることはできませんか?私は今、携帯電話ですので、それが真実かどうかを確認することはできません。 – Stefan

+0

うん、まさに正しい。それからヌルチェックをスキップして、elvis演算子に行きます。あるいは、 'String.Equals(link、" ... ")'を使用してください。メソッドを呼び出す際に変数 'link'を使用しないことで、NullRefを実行することはできません – Waescher

1

あなたはhttp://i.imgur.comを指しているすべてのリンクを取得しようとしている場合、あなたはこの

imageLinks = document.DocumentNode.Descendants("a") 
       .Select(element => element.GetAttributeValue("href", null)) 
       .Where(link => link?.Contains(@"http://i.imgur.com") == true) 
       .ToList(); 
関連する問題