2016-08-10 2 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: я нашел своего коллегу, который написал очень большие сценарии, которые имели много линий и сложности, которые я мог бы уменьшить до гораздо меньших сценариев (4 строки вместо 40). После сравнения результатов меньшие скрипты дали одинаковые результаты. Однако более длинные скрипты, сделанные моим коллегой, работали почти в десять раз быстрее. Фильтрация данных, которые вам не нужны, является самым большим улучшением производительности в нашей ситуации. Не сказать, что это то же самое для вашей ситуации, но минимизация длины кода не всегда является лучшим вариантом. –

Смежные вопросы