Total Commander Forum Index Total Commander
Форум поддержки пользователей Total Commander
Сайты: Все о Total Commander | Totalcmd.net | Ghisler.com | RU.TCKB
 
 RulesRules   SearchSearch   FAQFAQ   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Авторедактирование списка url-ов на основе HTTP статус кодов
Goto page 1, 2  Next
 
Post new topic   Reply to topic    Total Commander Forum Index -> Программное обеспечение printer-friendly view
View previous topic :: View next topic  
Author Message
Hjkma



Joined: 18 Apr 2015
Posts: 135

Post (Separately) Posted: Thu Jan 26, 2017 22:11    Post subject: Авторедактирование списка url-ов на основе HTTP статус кодов Reply with quote

Хочется иметь скрипт, который будет брать список url-ов из буфера обмена, проверять их на http статус коды, отсеивать url-ы, возвращающие статусы 404, и помещать отредактированный список url-ов обратно в буфер обмена. Нужно чтобы очистить список веб-адресов от неработающих сайтов и веб-страниц. И делать это нужно будет регулярно, поэтому требуется кнопка.
Буду очень признателен за скрипт, если кто-то из скриптописателей это сможет реализовать. Спасибо.
Back to top
View user's profile Send private message
MVV



Joined: 15 Oct 2009
Posts: 4445
Location: Ростов-Дон

Post (Separately) Posted: Thu Jan 26, 2017 23:03    Post subject: Reply with quote

Батник (внутри вызывает повершелл) фильтрует урлы в буфере по валидным кодам возврата (2хх, 3хх - другие коды вызывают исключение внутри GetResponse):
Code:
@echo off
set "ARG_0=%~dpnx0"
powershell.exe -NoProfile -STA "iex (([IO.File]::ReadAllText($Env:ARG_0)) -replace '^(.*\n)*?.*<::::>.*\n', '')" & goto :EOF


Add-Type -Assembly System.Windows.Forms;


function testUrl($url, $timeout) {
   try {
      $webReq = [Net.WebRequest]::Create($url);
      $webReq.Method = 'HEAD';
      $webReq.Timeout = $timeout;
      $webRsp = $webReq.GetResponse();
      $webRsp.Close();
      Write-Host "``$url``: $([int]$webRsp.StatusCode)";
      $true;
   }
   catch {
      Write-Host "``$url``: $_";
   }
}


$urls = [Windows.Forms.Clipboard]::GetText() -split '\r?\n';
$goodUrls = @($urls | ? { $_ -match '^\w+://' -and (testUrl $_ $timeout) });
if ([Windows.Forms.MessageBox]::Show("Please click OK to copy $($goodUrls.Length) of $($urls.Length) urls to clipboard.", 'Url Filter', 1) -eq 1) {
   [Windows.Forms.Clipboard]::SetText(($goodUrls -join "`n") + "`n");
}


(добавлены установка метода HEAD и окошко сообщения в конце)
_________________
TCFS2 + TCFS2Tools: Полноэкранный режим и многое другое (обсуждение)
WINCMD.RU: AskParam, CopyTree, NTLinks, Sudo, VirtualPanel…


Last edited by MVV on Fri Jan 27, 2017 00:09; edited 2 times in total
Back to top
View user's profile Send private message
Hjkma



Joined: 18 Apr 2015
Posts: 135

Post (Separately) Posted: Thu Jan 26, 2017 23:21    Post subject: Reply with quote

MVV
Спасибо за скрипт. А есть ли возможность как-то оптимизировать или ускорить скрипт? Просто нужно обрабатывать тысячи ссылок, а скрипт обрабатывает их со скоростью 1 url за 1-2 секунды. За 1000 ссылок выйдет работы примерно на 16 минут, так что это долго.
Back to top
View user's profile Send private message
MVV



Joined: 15 Oct 2009
Posts: 4445
Location: Ростов-Дон

Post (Separately) Posted: Thu Jan 26, 2017 23:30    Post subject: Reply with quote

Попробуй использовать метод HEAD, чтобы не грузить данные:
Code:
      $webReq = [Net.WebRequest]::Create($url);
      $webReq.Method = 'HEAD';
      ...

Также можно уменьшить значение $timeout, чтобы меньше ждать ответа от мертвых серверов, но при маленьком значении живые адреса могут тоже быть отсеяны.
_________________
TCFS2 + TCFS2Tools: Полноэкранный режим и многое другое (обсуждение)
WINCMD.RU: AskParam, CopyTree, NTLinks, Sudo, VirtualPanel…


Last edited by MVV on Thu Jan 26, 2017 23:42; edited 1 time in total
Back to top
View user's profile Send private message
Hjkma



Joined: 18 Apr 2015
Posts: 135

Post (Separately) Posted: Thu Jan 26, 2017 23:35    Post subject: Reply with quote

MVV
А где это в скрипте прописать?
Вставить нужно выше или ниже этого куска кода?
Code:
      $webReq = [Net.WebRequest]::Create($url);
      $webReq.Timeout = $timeout;
      $webRsp = $webReq.GetResponse();
      $webRsp.Close();
      Write-Host "``$url``: $([int]$webRsp.StatusCode)";
      $true;
Back to top
View user's profile Send private message
MVV



Joined: 15 Oct 2009
Posts: 4445
Location: Ростов-Дон

Post (Separately) Posted: Thu Jan 26, 2017 23:44    Post subject: Reply with quote

Вставить нужно 1 новую строку (установка метода) после 1 уже имеющейся (создание объекта).

Ещё можно перед последней строкой (копирование в буфер) добавить отображение окошка, чтобы забивать буфер после долгой операции только по команде (писать можно и по-русски, но тогда необходимо сохранить файл в кодировке UTF-8 без BOM):
Code:
$null = [Windows.Forms.MessageBox]::Show("Please click OK to copy $($goodUrls.Length) good urls to clipboard.", 'Url Filter');


В общем, отредактировал скрипт в своём посте.
_________________
TCFS2 + TCFS2Tools: Полноэкранный режим и многое другое (обсуждение)
WINCMD.RU: AskParam, CopyTree, NTLinks, Sudo, VirtualPanel…
Back to top
View user's profile Send private message
Hjkma



Joined: 18 Apr 2015
Posts: 135

Post (Separately) Posted: Fri Jan 27, 2017 00:03    Post subject: Reply with quote

MVV
Сделал все это, скорость теперь примерно 1 url за одну секунду.
С таймаутом можно поэкспериментировать, но в принципе большая часть ссылок - и так живые, так что они отвечают в пределах 1-2 секунд, так что уменьшение таймаута не особо поможет.
А можно ли сделать так, чтобы батник обрабатывал ссылки в несколько проходов, то есть не по одной ссылке за один раз, а чтобы было 10 процессов и соединений, которые обрабатывают ссылки? Я не программист и не знаю как корректно это описать. Приведу пример. Есть downloader manager-ы, которым можно скормить тонну url-ов и можно там в настройках прописать количество соединений, например 10, тогда они скачивают по 10 файлов за один раз. Так и здесь нельзя применить тот же принцип?
Back to top
View user's profile Send private message
Flasher



Joined: 06 Nov 2009
Posts: 11579
Location: Москва

Post (Separately) Posted: Fri Jan 27, 2017 00:16    Post subject: Reply with quote

Hjkma
Этот способ пингования называется асинхронным.
Темповый файл стоит на дозаписи, по достижению лимита счётчика содержимое выбрасывается в буфер.
_________________
Автору сборки TC Image (Andrey_A) настоятельно рекомендуется не распространять на иных ресурсах любую предоставленную мной где-либо техническую информацию по автоматизации и оптимизации в работе с ТС и системой.
Back to top
View user's profile Send private message
Hjkma



Joined: 18 Apr 2015
Posts: 135

Post (Separately) Posted: Fri Jan 27, 2017 01:47    Post subject: Reply with quote

От MVV что-то нету ответа.
Может ли кто-нибудь ввести в скрипт метод асинхронного пингования с потоками от 10 раз? Чтобы скорость получилась на 10 раз быстрее.
Back to top
View user's profile Send private message
MVV



Joined: 15 Oct 2009
Posts: 4445
Location: Ростов-Дон

Post (Separately) Posted: Fri Jan 27, 2017 01:57    Post subject: Reply with quote

Может, MVV устал и ушел спать? Rolling Eyes

С асинхронностью будет как-то так:
Code:
@echo off
set "ARG_0=%~dpnx0"
powershell.exe -NoProfile -STA "iex (([IO.File]::ReadAllText($Env:ARG_0)) -replace '^(.*\n)*?.*<::::>.*\n', '')" & goto :EOF


Add-Type -Assembly System.Windows.Forms;


function testUrls($urls, $timeout, $workerCount = 2) {
   $job = @{
      queue = [Collections.Queue]::Synchronized((New-Object Collections.Queue (, $urls)));
      list = [Collections.ArrayList]::Synchronized((New-Object Collections.ArrayList));
      timeout = $timeout;
   };
   Write-Host "Checking $($urls.Length) urls using $workerCount workers...";
   $workerScript = {
      $job = $args[0];
      try {
         while (1) {
            $url = $job.queue.Dequeue();
            try {
               $webReq = [Net.WebRequest]::Create($url);
               $webReq.Method = 'HEAD';
               $webReq.Timeout = $job.timeout;
               $webRsp = $webReq.GetResponse();
               $webRsp.Close();
               $null = $job.list.Add($url);
               "$url`: $($webRsp.StatusCode)";
            }
            catch {
               "$url`: $_";
            }
         }
      }
      catch {}
   };
   $workers = @((1 .. $workerCount) | % { $w = [PowerShell]::Create().AddScript($workerScript).AddArgument($job); @{ w = $w; r = $w.BeginInvoke() } });
   $workers | % { Write-Host ($_.w.EndInvoke($_.r) -join "`n") };
   $job.list;
}

$timeout = 10000;
$workerCount = 10;
$urls = @([Windows.Forms.Clipboard]::GetText() -split '\r?\n' | ? { $_ -match '^\w+://' });
$startTime = [DateTime]::Now;
$goodUrls = @(testUrls $urls $timeout $workerCount);
$workTime = [int]([DateTime]::Now - $startTime).TotalSeconds;
if ([Windows.Forms.MessageBox]::Show("Approved $($goodUrls.Length) of $($urls.Length) urls in $workTime seconds.`nPlease click OK to copy urls to clipboard.", 'Url Filter', 1) -eq 1) {
   [Windows.Forms.Clipboard]::SetText(($goodUrls -join "`n") + "`n");
}


Таймаут и число потоков можно поменять, но если скрипт исчерпает лимит полуоткрытых соединений, могут быть проблемы.
_________________
TCFS2 + TCFS2Tools: Полноэкранный режим и многое другое (обсуждение)
WINCMD.RU: AskParam, CopyTree, NTLinks, Sudo, VirtualPanel…
Back to top
View user's profile Send private message
Hjkma



Joined: 18 Apr 2015
Posts: 135

Post (Separately) Posted: Fri Jan 27, 2017 02:28    Post subject: Reply with quote

MVV
Новый скрипт обработал 1925 ссылок за 6 минут. То есть, скорость получилась 1 секунда = 5 ссылок. В принципе, приемлемо.
Но есть проблема: старый вариант из тех 1925 ссылок возвращал 1217 работающих ссылок. Новый вариант вернул 1160 ссылок. Я нашел ссылки, которых вернул старый скрипт и не вернул новый скрипт, они все работающие, которые возвращают статус 200 и которые открываются в браузере. Еще раз запустил скрипт, на этот раз из тех же 1925 ссылок он вернул 1124. Что-то не так в скрипте. Могу прислать в ЛС список ссылок для тестирования.
Замечу, что и во время работы старого скрипта, и во время работы нового скрипта у меня все время работает торрент, который на полную скорость качает сериал. Может это влияет?
Upd. В третий раз запустил скрипт, на этот раз поставив число потоков на 5. Вернуло 1205 ссылок. Нормальное значение должно быть - 1217 ссылок. В четвертый раз, на 3 потоков вернуло уже 1217 ссылок. В пятый раз, на 3 потоков выдало цифру в 1215 ссылок. Как-то напрягает в работе скрипта, что не до конца уверен в конечном результате, т.к. скрипт выдает разные цифры. Может есть возможность встроить в работу скрипта какой-то механизм, который бы предотвращал такие ситуации, например в конце повторно бы перепроверял те ссылки, которых скрипт отсеял?
Back to top
View user's profile Send private message
MVV



Joined: 15 Oct 2009
Posts: 4445
Location: Ростов-Дон

Post (Separately) Posted: Fri Jan 27, 2017 11:24    Post subject: Reply with quote

Естественно, если возникает ошибка или таймаут, ссылка отсеивается. А что в консоль выдается по тем ссылкам, которые рабочие, но были отсеяны скриптом?

Если в фоне работает торрент, то это может влиять - особенно если он качает на скорости, близкой к тарифному лимиту.

Чтобы детект работал стабильнее, надо увеличивать таймаут, а также следить, чтобы лимит полуоткрытых соединений не превышался (иначе повершелл просто не сможет открывать новые соединения) - например, можно смотреть открытые соединения в Process Hacker.
_________________
TCFS2 + TCFS2Tools: Полноэкранный режим и многое другое (обсуждение)
WINCMD.RU: AskParam, CopyTree, NTLinks, Sudo, VirtualPanel…
Back to top
View user's profile Send private message
Hjkma



Joined: 18 Apr 2015
Posts: 135

Post (Separately) Posted: Fri Jan 27, 2017 16:24    Post subject: Reply with quote

MVV
Так я не могу отследить процессы в консоле, в начале долго стоит надпись "Checking 1925 url using 10 workers", а потом как время работы скрипта подходит к концу, то в консоле очень быстро скопом пролистывается список урлов и их коды состояния и затем консоль завершается.
Попробую увеличить таймаут до 100000 с числом потоков на 10.
Вот про лимит полуоткрытых соединений не понял - у меня же Windows 7, вроде там нет ограничения?
Back to top
View user's profile Send private message
Avada



Joined: 01 Aug 2008
Posts: 8501
Location: Россия, Саратов

Post (Separately) Posted: Fri Jan 27, 2017 19:37    Post subject: Reply with quote

C учётом специфики поставленного вопроса и обсуждения тема переносится в "Программное обеспечение".
_________________
Даже самая богатая фантазия
Не представит себе наши безобразия.
Back to top
View user's profile Send private message
Hjkma



Joined: 18 Apr 2015
Posts: 135

Post (Separately) Posted: Fri Jan 27, 2017 20:16    Post subject: Reply with quote

По итогам тестирования.
Второй вариант скрипта все время выдает разные результаты, то 1165 ссылок, то 1190, то 1203, сколько бы не увеличивал время таймаута и не уменьшал число потоков. Первый вариант скрипта всегда из тех 1925 ссылок выдает те же 1217 ссылок и все они рабочие. Может что-то в работе второго скрипта не так? Кстати, по консоли ошибся, это окно не исчезает, если не нажимать кнопку "ок", когда предлагают скопировать список ссылок в буфер. Но в консоли показываются не все ссылки, только 300 строк и больше ничего. Правда из тех 300 строк нашлись ссылки, которых скрипт отсеял и они рабочие. Вот их коды состояния
Quote:
(ссылка): Исключение при вызове "GetResponse" с "0" арг
ументами: "Невозможно разрешить удаленное имя: '(ссылка)"


Можно ли что-нибудь прописать в работе скрипта, чтобы сделать его как можно стабильнее? К примеру сделать так, чтобы в конце работы скрипт еще раз обрабатывал ссылки, которые возвращают приведенный выше код ошибки. С одним потоком и увеличенным таймаутом.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Total Commander Forum Index -> Программное обеспечение All times are GMT + 4 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group