|
Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » PowerShell - [решено] Скрипт парсера потребляет много памяти и не отрабатывает полностью |
|
PowerShell - [решено] Скрипт парсера потребляет много памяти и не отрабатывает полностью
|
Старожил Сообщения: 216 |
Профиль | Отправить PM | Цитировать
Добрый вечер всем!
Прошу помощи у знатоков тонкостей работы PoSh. Написал парсер, создающий плейлист одного сайта. Скрипт работает вроде неплохо, правда достаточно долго, но это думаю связано с длительными ответами от сервера. Но при работе скрипта постоянно растёт память, потребляемая PoSh, доходит почти до 2 ГБ. И в какой-то момент процесс просто вырубается, не доработав до конца. При запуске через консоль выскакивает какая-то ошибка, но не успеваю её прочитать, так как консоль тут же закрывается. Если запустить скрипт в ISE, то появляется такая ошибка: Сам скрипт: $url = 'http://какой-то сайт' $file = New-TemporaryFile $d = '#EXTM3U' (Invoke-WebRequest -UseBasicParsing -Uri $url -TimeoutSec 20).Links.Href | Where {$_ -match "html"} | Sort-Object -Unique ` | ForEach {$_ -replace "(.*html)","http://этот сайт`$1"} | Out-File $file.FullName Get-Content $file.FullName -Encoding utf8 | ForEach { $l = Invoke-WebRequest -Uri $_ -TimeoutSec 20 if ($l.Content -notmatch "iframe src") { $n = ($l.ParsedHtml.getElementsByTagName("title") | select IHTMLTitleElement_text).IHTMLTitleElement_text -replace "(.*) смотреть онлайн прямой эфир","`$1" $ln = ($l.ParsedHtml.getElementsByTagName("iFrame") | select IHTMLFrameBase_src).IHTMLFrameBase_src ForEach ($link in $ln) { ((Invoke-WebRequest -UseBasicParsing -URI $link -Headers @{"Referer"="$_"}).Content | Select-String -Pattern 'file:"([^"]+)"' -AllMatches).Matches ` | ForEach-Object {"$($_.Groups[1].Value)"}| ForEach {$_ -replace "(https?.*)","#EXTINF:-1,$n`n`$1"} | Out-File .\parser.txt -Append -Encoding utf8 } } else { $n = ($l.ParsedHtml.getElementsByTagName("title") | select IHTMLTitleElement_text).IHTMLTitleElement_text -replace "(.*) смотреть онлайн прямой эфир","`$1" $ln = ($l.ParsedHtml.getElementsByTagName("iFrame") | select IHTMLFrameBase_src).IHTMLFrameBase_src ForEach ($link in $ln) { ((Invoke-WebRequest -UseBasicParsing -URI $link -Headers @{"Referer"="$_"}).Content | Select-String -Pattern 'var videoLink.*(https?[^"]+m3u8)' -AllMatches).Matches ` | ForEach-Object {"$($_.Groups[1].Value)"}| ForEach {$_ -replace "(https?.*)","#EXTINF:-1,$n`n`$1"} | Out-File .\parser.txt -Append -Encoding utf8 } } } $c = Get-Content .\parser.txt -Encoding utf8 Set-Content .\parser.txt -Encoding utf8 -value $d,$c Заранее благодарен за помощь и советы. |
|
Отправлено: 21:33, 15-12-2019 |
Старожил Сообщения: 216
|
Профиль | Отправить PM | Цитировать Charg, забыл я как-то за Select-Object -Unique.
Сейчас код полностью переписал, работает быстро и утечки памяти больше нет. Но возникла немного другая проблема. Сервер на некоторые ссылки возвращает 404, наверное из-за частых запросов. Добавил в цикл Start-Sleep -s 3, но только общее время работы увеличилось, а ошибки 404 встречаются всёравно. |
Отправлено: 14:33, 16-12-2019 | #11 |
Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети. Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля. |
Ветеран Сообщения: 27449
|
Профиль | Отправить PM | Цитировать Цитата Uragan66:
Скорее, ошибки в этих «некоторых» url'ах. Попробуйте сформировать их в файл и проверить «ручками». |
|
Отправлено: 17:29, 16-12-2019 | #12 |
Ветеран Сообщения: 2798
|
Профиль | Отправить PM | Цитировать Я бы добавил проверку на код ответа и если он не 2** (двухсотые это когда всё ок) - писал в stdout содержимое каждой переменной.
Так же не забывай про автоматическую переменную $error и Start\Stop-Transcript |
Отправлено: 17:30, 16-12-2019 | #13 |
Старожил Сообщения: 216
|
Профиль | Отправить PM | Цитировать Charg, спасибо!
Действительно некоторые url'ы для вторых запросов формировались неправильно, RegExr глючил... Сейчас исправил, вроде всё нормально. Нелёгкое дело отладка скрипта Остался один вопрос нерешенный по данному скрипту. Подскажите, пожалуйста, есть ли возможность на PoSh указать автоматическую вертикальную прокрутку listbox по мере его заполнения ? Пробовал добавлять AutoScrollOffset, консоль ругается. |
Отправлено: 19:19, 16-12-2019 | #14 |
Ветеран Сообщения: 2798
|
Профиль | Отправить PM | Цитировать Цитата Uragan66:
Быстрый гугл говорит что по-человечески это не сделать, но можно костылями, типа так (не пробовал): Цитата Uragan66:
|
||
Отправлено: 19:58, 16-12-2019 | #15 |
Старожил Сообщения: 216
|
Профиль | Отправить PM | Цитировать Цитата Charg:
|
|
Отправлено: 20:19, 16-12-2019 | #16 |
Ветеран Сообщения: 2798
|
Профиль | Отправить PM | Цитировать Uragan66, сначала заполняешь листбокс данными, потом вот этот костыль, а уже потом рисуешь листбокс? Должно быть так, если я правильно понимаю.
Ну либо листбокс - неправильный выбор для задачи которую ты решаешь с помощью листбокса. |
Отправлено: 20:43, 16-12-2019 | #17 |
Старожил Сообщения: 216
|
Профиль | Отправить PM | Цитировать Цитата Charg:
|
|
Отправлено: 21:13, 16-12-2019 | #18 |
Ветеран Сообщения: 27449
|
Профиль | Отправить PM | Цитировать Цитата Uragan66:
|
|
Отправлено: 21:19, 16-12-2019 | #19 |
Старожил Сообщения: 216
|
Профиль | Отправить PM | Цитировать Код такой:
function GenerateForm { [reflection.assembly]::loadwithpartialname("System.Windows.Forms") | Out-Null [reflection.assembly]::loadwithpartialname("System.Drawing") | Out-Null $form1 = New-Object System.Windows.Forms.Form $button1 = New-Object System.Windows.Forms.Button $listBox1 = New-Object System.Windows.Forms.ListBox $RadioButton = New-Object System.Windows.Forms.RadioButton $InitialFormWindowState = New-Object System.Windows.Forms.FormWindowState $b1= $false $b2= $false $b3= $false #---------------------------------------------- #Generated Event Script Blocks #---------------------------------------------- $handler_button1_Click= { $listBox1.Items.Clear(); if ($RadioButton.Checked) { $url = 'http://какой-то сайт/' $file = New-TemporaryFile $d = '#EXTM3U' (Invoke-WebRequest -UseBasicParsing -Uri $url -TimeoutSec 20).Links.Href | Where {$_ -match "html"} | Sort-Object -Unique ` | ForEach {$_ -replace "(.*html)","http://какой-то сайт`$1"} | Out-File $file.FullName $ls = Get-Content $file.FullName -Encoding utf8 ForEach ($link in $ls){ $a = Invoke-WebRequest -Uri $link -TimeoutSec 20 -Method GET if ($a -notmatch "iframe src") { $a.Content -match '<title>(.*)</title>' | Out-Null $matches[1] | ForEach-Object {[Void]$listbox1.Items.Add($_)} $listBox1.SelectedIndex = $listBox1.Items.Count -1 $listBox1.SelectedIndex = -1 $n = '#EXTINF:-1,'+$matches[1] $a.Content -match 'iframe.*"(https?.+php)".*' | Out-Null $Global:l = $matches[1] if ($l -notmatch "free") { (Invoke-WebRequest -UseBasicParsing -URI $l -Headers @{"Referer"=$link}).Content -match 'file:"([^"]+)"' | Out-Null $m = $matches[1] Add-Content .\only-tv.m3u -Encoding utf8 -Value $n,$m } else { continue } } else { $a.Content -match '<title>(.*)</title>' | Out-Null $matches[1] | ForEach-Object {[Void]$listbox1.Items.Add($_)} $listBox1.SelectedIndex = $listBox1.Items.Count -1 $listBox1.SelectedIndex = -1 $n = '#EXTINF:-1,'+$matches[1] $a.Content -match 'iframe.*"(https?.+html)".*' | Out-Null $Global:l = $matches[1] (Invoke-WebRequest -UseBasicParsing -URI $l -Headers @{"Referer"=$link}).Content -match 'videoLink.*(https?[^"]+m3u8)' | Out-Null $m = $matches[1] Add-Content .\tv.m3u -Encoding utf8 -Value $n,$m } sleep -s 2 } $c = Get-Content .\tv.m3u -Encoding utf8 Set-Content .\tv.m3u -Encoding utf8 -value $d,$c Remove-Item $file.FullName -errorAction silentlycontinue $listBox1.Items.Add("Лист создан!") } if ( !$RadioButton.Checked ) { $listBox1.Items.Add("No CheckBox selected....")} } $OnLoadForm_StateCorrection= {#Correct the initial state of the form to prevent the .Net maximized form issue $form1.WindowState = $InitialFormWindowState } #---------------------------------------------- #region Generated Form Code $form1.Text = "TV" $form1.Name = "form1" $form1.DataBindings.DefaultDataSourceUpdateMode = 0 $form1.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::Fixed3D $form1.StartPosition = [System.Windows.Forms.FormStartPosition]::CenterScreen $System_Drawing_Size = New-Object System.Drawing.Size $System_Drawing_Size.Width = 450 $System_Drawing_Size.Height = 660 $form1.BackColor = "0x7AC5E7" $form1.Opacity = 0.96 $form1.ClientSize = $System_Drawing_Size $button1.TabIndex = 21 $button1.Name = "button1" $System_Drawing_Size = New-Object System.Drawing.Size $System_Drawing_Size.Width = 75 $System_Drawing_Size.Height = 23 $button1.Size = $System_Drawing_Size $button1.UseVisualStyleBackColor = $True $button1.Text = "Run Script" $System_Drawing_Point = New-Object System.Drawing.Point $System_Drawing_Point.X = 25 $System_Drawing_Point.Y = 585 $button1.Location = $System_Drawing_Point $button1.DataBindings.DefaultDataSourceUpdateMode = 0 $button1.add_Click($handler_button1_Click) $form1.Controls.Add($button1) $CancelButton = New-Object System.Windows.Forms.Button $CancelButton.Location = New-Object System.Drawing.Point(25,615) $CancelButton.Size = New-Object System.Drawing.Size(75,23) $CancelButton.Text = "Cancel" $CancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel $CancelButton.UseVisualStyleBackColor = $True $button1.TabIndex = 20 $form1.CancelButton = $CancelButton $form1.Controls.Add($CancelButton) $listBox1.FormattingEnabled = $True $System_Drawing_Size = New-Object System.Drawing.Size $System_Drawing_Size.Width = 210 $System_Drawing_Size.Height = 640 $listBox1.Size = $System_Drawing_Size $listBox1.DataBindings.DefaultDataSourceUpdateMode = 0 $listBox1.Name = "listBox1" $System_Drawing_Point = New-Object System.Drawing.Point $System_Drawing_Point.X = 220 $System_Drawing_Point.Y = 13 $listBox1.Location = $System_Drawing_Point $listBox1.TabIndex = 19 $form1.Controls.Add($listBox1) $RadioButton.UseVisualStyleBackColor = $True $RadioButton.Checked = $false $System_Drawing_Size = New-Object System.Drawing.Size $System_Drawing_Size.Width = 154 $System_Drawing_Size.Height = 30 $RadioButton.Size = $System_Drawing_Size $RadioButton.TabIndex = 0 $RadioButton.Text = "TV" $System_Drawing_Point = New-Object System.Drawing.Point $System_Drawing_Point.X = 25 $System_Drawing_Point.Y = 40 $RadioButton.Location = $System_Drawing_Point $RadioButton.DataBindings.DefaultDataSourceUpdateMode = 0 $RadioButton.Name = "RadioButton" $RadioButton.add_CheckedChanged({ if ($RadioButton.Checked){ $listBox1.Items.Add( "TV" ) } else { $listBox1.Items.Clear(); } }) $form1.Controls.Add($RadioButton) #Save the initial state of the form $InitialFormWindowState = $form1.WindowState #Init the OnLoad event to correct the initial state of the form $form1.add_Load($OnLoadForm_StateCorrection) #Show the Form $form1.ShowDialog()| Out-Null } #End Function #Call the Function GenerateForm После последней правки, код что выше выложил, автоскроллинг заработал. Правда периодически пропадает содержимое листбокса (кроме последней строки) на несколько секунд. Но это уже мелочи. Большое спасибо всем за советы! |
Последний раз редактировалось Uragan66, 16-12-2019 в 23:10. Отправлено: 21:47, 16-12-2019 | #20 |
Участник сейчас на форуме | Участник вне форума | Автор темы | Сообщение прикреплено |
| |||||
Название темы | Автор | Информация о форуме | Ответов | Последнее сообщение | |
Статья - Почему процесс System потребляет так много памяти в Windows 10? | OSZone | Microsoft Windows 10 | 1 | 19-08-2015 20:05 | |
Службы - svchost.exe потребляет слишком много памяти | GIGABAIT | Microsoft Windows 7 | 7 | 17-04-2015 11:02 | |
MSFT SQL Server - MS SQL потребляет много оперативной памяти | Tonny_Bennet | Программирование и базы данных | 22 | 23-10-2013 08:13 | |
Групповая политика сопоставление дисков не полностью отрабатывает | snioo | Windows Server 2012/2012 R2 | 5 | 16-07-2013 11:01 | |
Службы - HelpSvc.exe потребляет много оперативной памяти | Котяра | Microsoft Windows 2000/XP | 5 | 18-07-2008 14:41 |
|