2016-08-10 10 views
1

最初にエラーが返されても、実行するたびにコードが機能しているようです。何が起こっているのか、それをどう修正するのかが不思議です。破損していないエラーで問題が発生しました

マイコードを使用して、ウェブサイトリンクの配列からメタデータをスクレイプします。

非破壊エラー:

Cannot index into a null array. 
At C:\test\websiteScrape.ps1:127 char:5 
+  $List += [pscustomobject]@{ 
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
+ CategoryInfo   : InvalidOperation: (:) [], RuntimeException 
+ FullyQualifiedErrorId : NullArray 

コード:

$web = New-Object Net.WebClient 
$web | Get-Member 

function getMetaData($Array){ 
$fullArray = @() 

foreach ($element in $Array){ 

    $metaString = $web.DownloadString($element) 

    $metaArray = $metaString| Select-String -AllMatches '(meta name=".*?".+")|(a lang="fr" href=".*?")' | % { $_.Matches } | % { $_.Value } 
     select -expa matches | select -expa value 

     $fullArray += ,($element,$metaArray) 
     } 

return $fullArray 
} 
#$Array is a System.Array and it holds a bunch of strings"links" to a website. 

$metaData = getMetaData $Array 

$List = @() 
for ($i=0; $i -le $metaData.length; $i++){ 

    $List += [pscustomobject]@{ 

    PageName = $metaData[$i][0] 

    Description = [regex]::Replace($metaData[$i][1][1], 'meta name=".*?" content="(.*?)"', '$1'); 

    Creator = [regex]::Replace($metaData[$i][1][2], 'meta name=".*?" content="(.*?)"', '$1'); 

    Instituation = [regex]::Replace($metaData[$i][1][3], 'meta name=".*?" content="(.*?)"', '$1'); 

    Languague = [regex]::Replace($metaData[$i][1][4], 'meta name=".*?" content="(.*?)"', '$1'); 

    Subject =[regex]::Replace($metaData[$i][1][5], 'meta name=".*?" content="(.*?)"', '$1'); 

    Indentifier= [regex]::Replace($metaData[$i][1][6], 'meta name=".*?" content="(.*?)"', '$1'); 
    } 
} 
List| Select-Object -Property PageName, Description| Export-Csv -path C:\Desktop\urlsAndMetaData.csv -NoTypeInformation 
+1

は、私はちょうどこれを追加しました '$ web'は次 –

+0

@MartinBrandl、感謝の定義を欠場します。 – ImTrying

+1

にも '$ List'の宣言がありません –

答えて

2

私は(残念ながら、私はそれをテストするためのリンクを持っていない)正しくコードを読めば、あなたあなたのコードを簡単にすることができます。これは、同じことを行う必要があります。

$web = New-Object Net.WebClient 
$urls = @('www.firstlink.com', 'www.link2.com') 

$regex = '<meta\s+name="([^"]+)" content="([^"]+)' 

$urls | ForEach-Object { 
    $webSiteContent = $web.DownloadString($_) 
    $metaData = @{} 
    [regex]::Matches($webSiteContent, $regex) | ForEach-Object { 
     $metaData.Add($_.Groups[1].Value, $_.Groups[2].Value) 
    } 
    [PSCustomObject]@{ 
     PageName = $_ 
     Description = $metaData['gc.description.long'] 
     Creator = $metaData['dc.creator'] 
     Instituation = $metaData['dc.institution'] 
     Languague = $metaData['dc.language'] 
    } 
} | Export-Csv -path C:\Desktop\urlsAndMetaData.csv -NoTypeInformation 

$web.Dispose() 
+0

ありがとうございます。私はこれを撃つだろう。そのコードは美しく、私はpowershellとプログラミングにはかなり新しいので、コードを最適化/最小化するのはあまりよくありません。 – ImTrying

+1

@ImTrying PowerShellでの自分の学習に関するコメント:私は、私の同僚が、はるかに小さなスクリプト(40行ではなく4行)に減らすことができる、非常に大きなスクリプトを書くことができました。結果を比較した結果、小さなスクリプトでも同じ結果が得られました。しかし、私の同僚が作成した長いスクリプトは、ほぼ10倍速く働いていました。必要のないデータをフィルタリングすることは、私たちの状況で最大のパフォーマンス向上でした。それはあなたの状況では同じだと言っているわけではありませんが、コードの長さを最小にすることは常に最善の選択肢ではありません。 –

関連する問題