Я пытаюсь написать скрипт, загружающий информацию с веб-сайтов. Я могу загрузить информацию, но не могу заставить работать фильтрацию. У меня есть ряд значений, которые я хочу пропустить, сохраненных в $TakeOut
, но он не распознает значения в if -eq $TakeOut
. Я должен написать строку для каждого значения.
Мне интересно, есть ли способ использовать $value
, так как со временем будет пропущено значительное количество значений.
Это работает, но не практично в долгосрочной перспективе.
if ($R.innerText -eq "Home") {Continue}
Что-то вроде этого было бы предпочтительнее.
if ($R.innerText -eq $TakeOut) {Continue}
Вот пример моего кода.
#List of values to skip
$TakeOut = @()
$TakeOut = (
"Help",
"Home",
"News",
"Sports",
"Terms of use",
"Travel",
"Video",
"Weather"
)
#Retrieve website information
$Results = ((Invoke-WebRequest -Uri "https://www.msn.com/en-ca/").Links)
#Filter and format to new table of values
$objects = @()
foreach($R in $Results) {
if ($R.innerText -eq $TakeOut) {Continue}
$objects += New-Object -Type PSObject -Prop @{'InnerText'= $R.InnerText;'href'=$R.href;'Title'=$R.href.split('/')[4]}
}
#output to file
$objects | ConvertTo-HTML -As Table -Fragment | Out-String >> $list_F
Вы не можете осмысленно использовать массив в качестве RHS операции -eq
(массив будет неявно преобразован в строку, что не будет работать должным образом).
В PowerShell есть операторы -contains
и -in
для проверки принадлежности значения к массиву. (используя -eq
для каждого элемента — см. этот ответ для информации); следовательно:
if ($R.innerText -in $TakeOut) {Continue}
Как правило, ваш код можно упростить (синтаксис PSv3+):
$TakeOut =
"Help",
"Home",
"News",
"Sports",
"Terms of use",
"Travel",
"Video",
"Weather"
#Retrieve website information
$Results = (Invoke-WebRequest -Uri "https://www.msn.com/en-ca/").Links
#Filter and format to new table of values
$objects = foreach($R in $Results) {
if ($R.innerText -in $TakeOut) {Continue}
[pscustomobject @{
InnerText = $R.InnerText
href = $R.href
Title = $R.href.split('/')[4]
}
}
#output to file
$objects | ConvertTo-HTML -As Table -Fragment >> $list_F
Обратите внимание на отсутствие @(...)
, который никогда не нужен для литералов массива.
Построение массива в цикле с помощью +=
происходит медленно (и многословно); просто используйте оператор foreach
в качестве выражения, которое возвращает выходные данные тела цикла в виде массива.
[pscustomobject] @{ ... }
— синтаксический сахар PSv3+ для создания пользовательских объектов; помимо того, что он быстрее, чем вызов New-Object
, он имеет дополнительное преимущество, заключающееся в сохранении порядка свойств.
Вы можете написать все это как один конвейер:
#Retrieve website information
(Invoke-WebRequest -Uri "https://www.msn.com/en-ca/").Links | ForEach-Object {
#Filter and format to new table of values
if ($_.innerText -in $TakeOut) {return}
[pscustomobject @{
InnerText = $_.InnerText
href = $_.href
Title = $_.href.split('/')[4]
}
} | ConvertTo-HTML -As Table -Fragment >> $list_F
Обратите внимание на необходимость использовать return
вместо continue
, чтобы перейти к следующему входу.
Рад это слышать, @Вуди.