Что нового

Рекурсивный поиск тега по названию класса

kzru_hunter

Осваивающий
Сообщения
144
Репутация
49
Здравствуйте. Необходимо найти тег в html-коде, пройдясь по всем указанным тегам, зная их классы.

Нужно функцию примерно такого вида:
Код:
Dim $tags[4][2] = [ ["div", "mddl"], ["div", "c"], ["div", "grad purse"], ["p", "top_text"] ]
$oObj = _GetRecursiveObject($oIE, $tags)
 
Автор
K

kzru_hunter

Осваивающий
Сообщения
144
Репутация
49
А как по-другому?
В первом посте я указал пример, в котором показал, что хочу добраться до тега "p" с названием класса "top_text", при этом добраться нужно так, чтобы пройти сначала через тег "div" с className "mddl", а потом через тег "div" с className "grad purse".
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
kzru_hunter,
Ссылку дайте.
 

DarWiM

Продвинутый
Сообщения
527
Репутация
90
Тут пожалуй рекурсия будет лишней.. Просто проверка по объектам..
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
Какая проверка???
Я беру
Код:
Dim $tags[4][2] = [ ["div", "mddl"], ["div", "c"], ["div", "grad purse"], ["p", "top_text"] ]
	$oTags = _IETagNameGetCollection ($oIE, $tags[0][0])
	For $oTag In $oTags
		If $oTag.classname = $tags[0][1] Then
			MsgBox(0, "Info", "Tag: " & $oTag.tagname & @CR & "class: " & $oTag.classname)
		EndIf
	Next


И он рисует все окна с "class : 0".
Я вообще в шоке!
1. Как посмотреть класс тега?
2. Как он заходит в If, если пишет что classname = 0
?????
 
Автор
K

kzru_hunter

Осваивающий
Сообщения
144
Репутация
49
C2H5OH [?]
2. Как он заходит в If, если пишет что classname = 0
тоже не устраивает такая штука в автоите.
в нем переменная с числом 0 всегда будет равна любой строке.
надо проверять переменную функцией IsString.

Вот функция, но не совсем рабочая.
Код:
Func _GetRecursiveObject($rootObj, ByRef $array)
	Local $objs[20]
	Local $counts[20]
	Local $pos[20]
	Local $obj_num = 0
	$objs[0] = $rootObj

	Local $ubound = UBound($array)
	Local $class = "", $obj = -1, $j

	_IETagNameGetCollection($objs[0], $array[0][0])
	$counts[0] = @extended

	While $obj_num > -1
		If $counts[$obj_num] <= 0 Then
			$obj_num -= 1
		Else
			For $j=$pos[$obj_num] To $counts[$obj_num]-1
				$obj = _IETagNameGetCollection($objs[$obj_num], $array[$obj_num][0], $j)
				$class = $obj.className
				;MsgBox(0,"","obj_num = " & $obj_num & ", $counts[$obj_num] = " & $counts[$obj_num] & ", class = " & $class & ", $array[$obj_num][1] = " & $array[$obj_num][1])

				If IsString($class) AND String($class) = $array[$obj_num][1] OR StringInStr(String($class), $array[$obj_num][1] & " ")  Then
					$pos[$obj_num] = $j+1

					$obj_num += 1

					If $obj_num = $ubound Then
						ExitLoop 2
					Else
						$pos[$obj_num] = 0
						$objs[$obj_num] = $obj

						_IETagNameGetCollection($objs[$obj_num], $array[$obj_num][0])
						$counts[$obj_num] = @extended

						ExitLoop
					EndIf
				EndIf
			Next
		EndIf
	WEnd

	If $obj <> -1 Then
		Return $obj
	Else
		SetError(1,0,-1)
	EndIf
EndFunc

Не совсем рабочая из-за того, что в html-коде может быть, например, записано '<div class = "grad purse', а при обращении к объекту c целью получения названия класса, вернется , например, 'grad purse first-child'. Можно конечно дополнительно проверять пробел (так и сделано в этой функции), но из-за этого появляется другая проблема, т.е. может быть такая ситуация, что на странице есть два объекта:
1. <div class = sub disabled>
2. <div class = sub>
Нужно получить хендл для второго объекта, а функция вернет хендл для первого объекта.
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
Зато рекурсия ;D
Код:
#include <IE.au3>
#Include <Array.au3>

Dim $tags[4][2] = [ ["div", "mddl"], ["div", "c"], ["div", "grad purse"], ["p", "top_text"] ]

$oIE = _IECreate ("http://autoit-script.ru")
_IELoadWait ($oIE)

$oObj = _GetRecursiveObject($oIE, $tags)

If $oObj = 0 Then
	MsgBox(0, "Результат", "Ничего нет")
Else
	MsgBox(0, "Результат", "Tagname: " & $oObj.tagname & @CR & "class: " & $oObj.classname & @CR & "text: " & $oObj.innertext)
EndIf

Func _GetRecursiveObject($ooo, $ttt)

	If UBound($ttt) = 0 Then Return $ooo
	
	Local $ttt1 = $ttt
	_ArrayDelete($ttt1, 0)

	Local $oTag
	Local $oTags = _IETagNameGetCollection ($ooo, $ttt[0][0])
	For $oTag In $oTags
		If $oTag.classname = 0 Then ContinueLoop
		If $oTag.classname = "mddl" Then
			If _GetRecursiveObject($oTag, $ttt1) <> 0 Then Return $oTag
		EndIf
	Next

	Return 0
EndFunc
 
Верх