Что нового

[Сеть, интернет] Поиск текста на странице через IE.au3, WinHTTP и InetGet

zlo-kazan

Скриптер
Сообщения
374
Репутация
100
Провел маленький тест функций поиска текста на HTML-странице.

Текст страницы получаем через:
IE.au3
WinHTTP
InetGet (в фоновом режиме используя мультипоточность)

Код:
#include <IE.au3>
#include <Inet.au3>
#include <Array.au3>
Global $status="запуск скрипта"
Global $text_search="123" ;текст который ищем
AdlibRegister("TT",100)
DirCreate(@ScriptDir & "\temp")
$all= 100
dim $DW[$all+1]
dim $text[$all+1]
dim $oIE3[$all+1]
$timerInetGet=0
$timerWinHTTP=0
$timerIE1=0
$timerIE2=0
Search_inet($all)
Search_WinHTTP($all)
Search_IE1($all)
Search_IE2($all)
msgbox(64,"Скорость обработки", _ 
"Через IE= " & $timerIE1 & "сек" & @CRLF & _
"Через IE в скрытом режиме= " & $timerIE2 & "сек" & @CRLF & _
"Через WinHTTP= " & $timerWinHTTP & "сек" & @CRLF & _
"Через InetGet в фоновом режиме используя мультипоточность= " & $timerInetGet & "сек" & @CRLF)


; Сбор страниц через IE.au3 в открытом виде
Func Search_IE1($all)
	$Timer=TimerInit()
	for $i=1 to $all
	$status="сбор текста через IE = " & $i &"/"&$all
	$link="http://yandex.ru/yandsearch?p="&$i-1&"&text="&$text_search&"&lr=43"
	$oIE = _IECreate($link)
	_IELoadWait($oIE)
	$text[$i]=_IEDocReadHTML($oIE)
	_IEQuit($oIE)
	Next
	$test3=_text_Search($all, $text)
	$timerIE1=round(TimerDiff($timer)/1000, 2)
;~ 	msgbox(0,"Search_IE1", "Потрачено: " & round(TimerDiff($timer)/1000, 2) & " сек")
;~ 	_ArrayDisplay($test3)
EndFunc

; Сбор страниц через IE.au3 в скрытом виде
Func Search_IE2($all)
	$Timer=TimerInit()
	for $i=1 to $all
	$status="сбор текста через IE = " & $i &"/"&$all
	$link="http://yandex.ru/yandsearch?p="&$i-1&"&text="&$text_search&"&lr=43"
	$oIE2 = _IECreate($link,0,0)
	_IELoadWait($oIE2)
	$text[$i]=_IEDocReadHTML($oIE2)
	_IEQuit($oIE2)
	Next
	$test3=_text_Search($all, $text)
	$timerIE2=round(TimerDiff($timer)/1000, 2)
;~ 	msgbox(0,"Search_IE2", "Потрачено: " & round(TimerDiff($timer)/1000, 2) & " сек")
;~ 	_ArrayDisplay($test3)
EndFunc

; Сбор страниц через WinHTTP
Func Search_WinHTTP($all)
$Timer=TimerInit()
For $i=1 to $all
	$status="сбор текста через WinHTTP = " & $i &"/"&$all
	$link="http://yandex.ru/yandsearch?p="&$i-1&"&text="&$text_search&"&lr=43"
	$oHTTP = ObjCreate('WinHttp.WinHttpRequest.5.1')
	$oHTTP.Open('GET', $link, False)
	$oHTTP.Send('')
	$oHTTP.WaitForResponse
	$text[$i] = $oHTTP.ResponseText
	$oHTTP=0
;~ 	msgbox(0,"",$sHTML[$i])
Next
$test2=_text_Search($all, $text)
$timerWinHTTP=round(TimerDiff($timer)/1000, 2)
;~ msgbox(0,"Search_WinHTTP", "Потрачено: " & round(TimerDiff($timer)/1000, 2) & " сек")
;~ _ArrayDisplay($test2)
EndFunc

; Сбор страниц через InetGet
Func Search_inet($all)
$Timer=TimerInit()
For $i=1 to $all
$status="загрузка " & $i & "/" & $all
$link="http://yandex.ru/yandsearch?p="&$i-1&"&text="&$text_search&"&lr=43"
$DW[$i]=InetGet($link, @ScriptDir & "\temp\" & $i &".txt", 1, 1)
Next
Do
    Sleep(250)
	If TimerDiff($Timer)>60*1000 Then ExitLoop
Until chek_inetgetinfo($all)
For $i=1 to $all
	InetClose($DW[$i])
Next
$text=_txt_read($all)
$test1=_text_Search($all, $text)
$timerInetGet=round(TimerDiff($timer)/1000, 2)
;~ msgbox(0,"Search_inet", "Потрачено: " & round(TimerDiff($timer)/1000, 2) & " сек")
;~ _ArrayDisplay($test1)
EndFunc

;обработка массив страниц.
Func _text_Search($all, $text)
	local $k=0
	dim $test_all[1]
	For $i=1 to $all
		$status="сверка " & $i & "/" & $all 
		if StringRegExp($text[$i], '(?si)href=".+?(http.+?)".+?>')=0 then ContinueLoop
		$test=StringRegExp($text[$i], '(?si)href=".+?(http.+?)".+?>', 3)
		ReDim $test_all[$k+Ubound($test)+1]
		For $j=0 to UBound($test)-1
			$k+=1
			$test_all[$k]=$test[$j]
		Next
	Next
	return $test_all
EndFunc

; чтение txt-файлов из temp
Func _txt_read($all)
		dim $text[$all+1]
		For $i=1 to $all
		$status="читаем " & $i & "/" & $all
		$text[$i]=FileRead(@scriptdir & "\temp\" & $i & ".txt")
		Next
		return $text
EndFunc

; в этой функции проверяются все закачки и ждем пока все докачается.
Func chek_inetgetinfo($all)
local $k=0
for $i=1 to $all
if InetGetInfo($DW[$i], 2)=True then $k+=1
Next
$status="загруженно " & $k & "из" & $all
if $k=$all then 
;~ 	msgbox(0,"",$k)
	Return True
Else
	Return False
EndIf
EndFunc

; отдельно вынес ToolTip со статусом
Func TT()
	ToolTip("Статус: " & $status,0,0)	
EndFunc

Результаты для 100 страниц:
IE = 238 сек
IE скрытый = 174 сек
WinHTTP = 65 сек
InetGet мультипоток = 20 сек :laugh:

Компьютер:
C2D E4300
DDR2 667Mhz

Канал связи:
8Мбит/с

OS:
WinXP 86x SP3 (через http://half-open.com/ поменял количество одновременных подключений на 1000)
IE8
 

vcomp71

Осваивающий
Сообщения
431
Репутация
25
OS:
WinXP 86x SP3 (через http://half-open.com/ поменял количество одновременных подключений на 1000)
IE8
А вот здесь поподробней - что это за параметр и почему именно в 1000 надо устанавливать? И нет ли где в реестре этого значения, чтобы поменять переменную в реестре?
Просто интересно.
 
Автор
zlo-kazan

zlo-kazan

Скриптер
Сообщения
374
Репутация
100
По умолчанию в Windows XP стоит ограничение на количество одновременных подключений в размере 10 шт. т.е. если при включенном торренте не грузятся страницы и т.д. то это скорее всего не из-за ширины канала, а из-за того что есть 10 активных подключений... в Win7 по умолчанию уже 100 стоит. 100 обычно хватает с головой.. но тут хотел скачать 100 одновременно, а пару каналов используются все равно музыка из контакта и т.д. web-сервер поднят... по локалке, что-то качают... поэтому на всякий случай поставил избыточное число... :smile:

P.S. Скорее всего это значение хранится в реестре, но специально не искал... потому, что изменить его нужно 1 раз в жизни операционки... :smile:

P.S.S. Менять на 1000 тоже кстати не всегда рекомендуется... :smile: Например у провайдеров часто стоят простые дешевые узловые маршрутизаторы в домах... и при 500 и более одновременных подключениях они дружно зависают (даже с относительно небольшим потоком трафика)... :smile:
 

vcomp71

Осваивающий
Сообщения
431
Репутация
25
Дело в том, что у некоторых особо умных юзеров дома стоит Linux, которому эти windows ограничения глубоко пофигу, поэтому может случится, следуя вашей логике, что парочка линуксоидов, может повесить сеть провайдера.

Я почему справшиваю - данные ограничения не связаны как-то с лицензионной политикой Microsoft? Просто интересно...
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
zlo-kazan
ту путаешь понятия установившихся и полуоткрытых соединений. 100 - это, как говорится, за глаза. установленных соединений может быть сколько угодно, пока позволяет канал или софтина которая это соединение инициирует. полуоткрытые же, это когда нарушена синхронность авторизации, или в следствие лагов. но TCP/IP имеет возможность самодиагностики, и много подобных соединений не копится. может быть больше 10, но больше 100 я еще не встречал. может вирус какой запущенный.

zlo-kazan [?]
Скорее всего это значение хранится в реестре
если бы. это хранится в самом системном файле tcpip.sys, которую программа по ссылке которую ты дал патчит.
Vlasssov [?]
данные ограничения не связаны как-то с лицензионной политикой Microsoft?
они связаны. но не с лицензионной политикой, а просто с Microsoft. сделано это было давно. от предотвращения сетевых атак. но потом появились другие, более умные решения. а костыли остались, вплоть до Vista, или даже 7-ки. уже не помню.
 
Автор
zlo-kazan

zlo-kazan

Скриптер
Сообщения
374
Репутация
100
Спасибо за разъяснения. Действительно перепутал. :wacko:

Протестировал InetGet на 100Мбит/c.
ping ya.ru 20ms

Средний результат: ~3-4 сек... :shok:

Это быстрее поиска через IE почти в 60-80 раз... :IL_AutoIt_1:
 

focus

Осваивающий
Сообщения
69
Репутация
20
В связи с тем,что в этой теме показано тестирование протоколов, хотелось бы узнать - в чём принципиальная разница между WinHTTP и InetGet ?
 
Автор
zlo-kazan

zlo-kazan

Скриптер
Сообщения
374
Репутация
100
WinHTTP предназначена для использования преимущественно в серверных сценариев на сервере приложений, которые взаимодействуют с серверами HTTP.
http://msdn.microsoft.com/en-us/library/aa382925
А InetGet это функция которая используется для скачивания файла.
http://www.autoitscript.com/autoit3/docs/functions/InetGet.htm

Для 1-й странички WinHTTP и InetGet работают с одинаковой скоростью. Но с большим количеством WinHTTP каждый раз ждет пока загрузится страница, а InetGet может сохранять параллельно хоть 100 Шт. забивая весь канал связи... и из-за того что канал используется во 2-м случае на 100%, то и работает в разы быстрее. :smile:
 

focus

Осваивающий
Сообщения
69
Репутация
20
Немного расширю свой вопрос. (Я в "начале пути")... Шаг = 0. Открываем ИЕ и вводим адрес сайта. Жмём ентер. Через определённое время имеем в окне браузера открытый сайт. Шаг 1. Броузер отправляет адрес сайта в программу (названия не знаю, подскажите). Шаг = 2. Эта программа полученый адрес преобразовывает в HTTP запрос и отправляет в следующюю программу. Шаг 3.Эта программа преобразует HTTP запрос в бинарный вид ( TCP запрос) и отправляет на сайт. Сайт откликнулся (дал ответ). Далее в обратном порядке и картинка в окне браузера. (Могу шоибаться - поправте...) На каком этапе может присутствовать InetGet ?
 

Redline

AutoIT Гуру
Сообщения
506
Репутация
375
zlo-kazan
Попробуй заменить InetGet на
Код:
BinaryToString(InetRead($sUrl))

так можно обойтись без работы с файлами

Правда для youtube.com InetGet/Read выдают другой результат в отличии от WinHTTP :wacko: именно в ссылках на видео для скачки - ссылки получаются нерабочими (в них появляется параметр "oc", а другие параметры изменены)
Вот, например для этой ссылки:
http://www.youtube.com/watch?v=mC_u9ZwlIUc
нерабочая ссылка (InetGet):
Код:
http://v13.lscache5.c.youtube.com/videoplayback?sparams=id,expire,ip,ipbits,itag,ratebypass,oc:U0hPSVFRVl9FSkNOOV9JS1pF&itag=22&ipbits=0&signature=A0780AC85B63F31F680CE2DD81FC02670C0FF994.0EECED6DC6058F565D54A647B4E5A03CE0AC59&sver=3&ratebypass=yes&expire=1304168400&key=yt1&ip=0.0.0.0&id=982feef59c252147
рабочая ссылка (WinHTTP):
Код:
http://v13.lscache5.c.youtube.com/videoplayback?sparams=id,expire,ip,ipbits,itag,ratebypass&itag=22&ipbits=8&signature=091D08B8467D3A17AE3BCCD87756800286C80AEF.585CCF0FFD03CAAF1A4CACEA0D9CCA038DEE9221&sver=3&ratebypass=yes&expire=1304164800&key=yt1&ip=92.0.0.0&id=982feef59c252147
и непонятно в чем дело, ведь первый раз InetGet выдал рабочий результат, а все последующие кривые, может дело в куках для youtube?
 
Автор
zlo-kazan

zlo-kazan

Скриптер
Сообщения
374
Репутация
100
А разве можно запустить параллельно 100
Код:
BinaryToString(InetRead($sUrl))
???
 

Redline

AutoIT Гуру
Сообщения
506
Репутация
375
zlo-kazan
Про многопоточность забыл, каюсь (мозг плохо соображает когда болеешь)
Пойду есть таблетки...
 
Верх