Автор Тема: Простой парсер HTML кода HTMLFILE  (Прочитано 29019 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн madmasles [?]

  • Глобальный модератор
  • *
  • Сообщений: 7790
  • Репутация: 2312
  • Пол: Мужской
  • Награды За модерирование форума
    • Награды
  • Версия AutoIt: 3.3.x.x
Re: Простой парсер HTML кода
« Ответ #15, Отправлен: Февраль 07, 2015, 22:22:02 »
CreatoR,
GetElementById находит первый элемент, где id="user". Вроде, id должно быть уникальным, name может множественным.

Русское сообщество AutoIt

Re: Простой парсер HTML кода
« Ответ #15 Отправлен: Февраль 07, 2015, 22:22:02 »

Оффлайн CreatoR [?]

  • Администратор
  • *
  • Сообщений: 7759
  • Репутация: 2274
  • Пол: Мужской
  • AutoIt is simple, subtle, elegant
    • CreatoR's Lab
    • Награды
  • Версия AutoIt: 3.3.10.2
Re: Простой парсер HTML кода
« Ответ #16, Отправлен: Февраль 07, 2015, 22:56:36 »
madmasles  [?]
Цитировать
Вроде, id должно быть уникальным, name может множественным.
Не совсем понял как это относится к получению всех атрибутов?


Правила, Поиск, Супер тема


AutoIt is simple, subtle, elegant.


«Не оказываю тех. поддержку через ПМ/ICQ, и по электронной почте - для этого есть форум. (C)»
«Законы Мэрфи неоспоримы!»


Мои работы

Оффлайн madmasles [?]

  • Глобальный модератор
  • *
  • Сообщений: 7790
  • Репутация: 2312
  • Пол: Мужской
  • Награды За модерирование форума
    • Награды
  • Версия AutoIt: 3.3.x.x
Re: Простой парсер HTML кода
« Ответ #17, Отправлен: Февраль 07, 2015, 23:04:08 »
CreatoR  [?]
Цитировать
Не совсем понял как это относится к получению всех атрибутов?
ИМХО, Вы получаете все имена атрибутов, независимо от наличия их значения, только первого элемента с id="user".
(нажмите для показа/скрытия)

С вашим HTML-кодом можно примерно так сделать.
(нажмите для показа/скрытия)
ИМХО, еще можно предварительно проверять Value и не отображать его при заданных условиях, типа
Код: AutoIt [Выделить]
;~      ...
        $sValue = $oAttrib.Value
        If Not $sValue Then ContinueLoop
        If StringRegExp($sValue, '(?i)^(0|null|false)$') Then ContinueLoop
;~      ...

« Последнее редактирование: Февраль 07, 2015, 23:18:26 от madmasles »

Оффлайн CreatoR [?]

  • Администратор
  • *
  • Сообщений: 7759
  • Репутация: 2274
  • Пол: Мужской
  • AutoIt is simple, subtle, elegant
    • CreatoR's Lab
    • Награды
  • Версия AutoIt: 3.3.10.2
Re: Простой парсер HTML кода
« Ответ #18, Отправлен: Февраль 08, 2015, 01:16:44 »
madmasles  [?]
Цитировать
можно предварительно проверять Value и не отображать его при заданных условиях
Это не вариант, что если значение такое же у искомого элемента?

Значит получается что свойство Attributes возвращает всевозможные атрибуты.
Можно конечно получать OuterHtml и парсить строку тега, но это уже не то.

Вот так примерно:
Код: AutoIt [Выделить]
#include <Array.au3>

$sHTML = _
    '<body>' & @CRLF & _
    '   <span id="users">' & @CRLF & _
    '       <div id="user">User1</div>' & @CRLF & _
    '       <div id="user">User2</div>' & @CRLF & _
    '       <div id="user">User3</div>' & @CRLF & _
    '   </span>' & @CRLF & _
    '   <span id="logins" class="my logins" attrib1 attrib2>' & @CRLF & _
    '       <div id="login">login1</div>' & @CRLF & _
    '       <div id="login">login2</div>' & @CRLF & _
    '       <div id="login">login3</div>' & @CRLF & _
    '   </span>' & @CRLF & _
    '</body>'

$oHTML = ObjCreate('HtmlFile')
$oHTML.Write($sHTML)

$aAttributes = _GetNodeAttributes($oHTML.GetElementById('logins'))

For $i = 1 To $aAttributes[0][0]
    ConsoleWrite($aAttributes[$i][0] & '=' & $aAttributes[$i][1] & @LF)
Next

Func _GetNodeAttributes($oNode)
    If Not IsObj($oNode) Then
        Return SetError(1, 0, 0)
    EndIf
   
    Local $sAttributes, $aAttributes, $iUbnd
    Local $aRet[1][2] = [[0]]
   
    $sAttributes = StringRegExpReplace($oNode.OuterHtml, '(?s)^\s*<[^\h]+\h*([^>]+)>.*', '\1')
    $aAttributes = StringRegExp($sAttributes, '([^=\h]+)(?:\h*=)?(\h*["''][^"'']+["'']|[^\h]+|\h*|$)?', 3)
    $iUbnd = UBound($aAttributes)
   
    If $iUbnd = 0 Then
        Return SetError(2, 0, 0)
    EndIf
   
    For $i = 0 To $iUbnd - 1 Step 2
        $aRet[0][0] += 1
        ReDim $aRet[$aRet[0][0] + 1][2]
        $aRet[$aRet[0][0]][0] = $aAttributes[$i]
       
        If $i + 1 < $iUbnd Then
            $aRet[$aRet[0][0]][1] = StringStripWS($aAttributes[$i + 1], 3)
        EndIf
    Next
   
    Return $aRet
EndFunc

« Последнее редактирование: Февраль 08, 2015, 12:25:18 от CreatoR »

Русское сообщество AutoIt

Re: Простой парсер HTML кода
« Ответ #18 Отправлен: Февраль 08, 2015, 01:16:44 »

Оффлайн madmasles [?]

  • Глобальный модератор
  • *
  • Сообщений: 7790
  • Репутация: 2312
  • Пол: Мужской
  • Награды За модерирование форума
    • Награды
  • Версия AutoIt: 3.3.x.x
Re: Простой парсер HTML кода
« Ответ #19, Отправлен: Февраль 08, 2015, 10:08:03 »
CreatoR  [?]
Цитировать
Вот так примерно
И Name, и Value вроде могут быть с пробелами, типа
Код: (HTML5) [Выделить]
  1. <div id="user id" some_name="some value">
« Последнее редактирование: Февраль 08, 2015, 12:22:47 от madmasles »

Оффлайн CreatoR [?]

  • Администратор
  • *
  • Сообщений: 7759
  • Репутация: 2274
  • Пол: Мужской
  • AutoIt is simple, subtle, elegant
    • CreatoR's Lab
    • Награды
  • Версия AutoIt: 3.3.10.2
Re: Простой парсер HTML кода
« Ответ #20, Отправлен: Февраль 08, 2015, 10:40:47 »
madmasles  [?]
Цитировать
И Name, и Value вроде могут быть с пробелами, типа
А как тогда разделяются атрибуты? если я не ошибаюсь, только значение может иметь пробелы, и это при том, что оно обрамлено кавычками.

Оффлайн madmasles [?]

  • Глобальный модератор
  • *
  • Сообщений: 7790
  • Репутация: 2312
  • Пол: Мужской
  • Награды За модерирование форума
    • Награды
  • Версия AutoIt: 3.3.x.x
Re: Простой парсер HTML кода
« Ответ #21, Отправлен: Февраль 08, 2015, 12:24:26 »
CreatoR  [?]
Цитировать
если я не ошибаюсь, только значение может иметь пробелы, и это при том, что оно обрамлено кавычками.
Вы правы, Name с пробелами не определяется, значит, должен быть одним словом.

Оффлайн CreatoR [?]

  • Администратор
  • *
  • Сообщений: 7759
  • Репутация: 2274
  • Пол: Мужской
  • AutoIt is simple, subtle, elegant
    • CreatoR's Lab
    • Награды
  • Версия AutoIt: 3.3.10.2
Re: Простой парсер HTML кода
« Ответ #22, Отправлен: Февраль 08, 2015, 12:35:32 »
Поправил свой пример выше, теперь корректно обрабатывает атрибуты без значении.
Если значение атрибута имеет пробелы, то оно должно обрамляться кавычками, иначе всё что после пробела, будет интерпретироваться как другой атрибут (так оно работает в Html).

Русское сообщество AutoIt

Re: Простой парсер HTML кода
« Ответ #22 Отправлен: Февраль 08, 2015, 12:35:32 »

Оффлайн madmasles [?]

  • Глобальный модератор
  • *
  • Сообщений: 7790
  • Репутация: 2312
  • Пол: Мужской
  • Награды За модерирование форума
    • Награды
  • Версия AutoIt: 3.3.x.x
Re: Простой парсер HTML кода
« Ответ #23, Отправлен: Февраль 08, 2015, 12:59:50 »
CreatoR,
Пол ночи искал, как проверить через какое-нибудь свойство, отображается ли атрибут в теге или использует значение по умолчанию и не отображается, но не нашел такого свойства. Похоже, Ваш способ решает этот вопрос.

Оффлайн inververs [?]

  • AutoIt Гуру
  • *****
  • Сообщений: 1966

  • Автор темы
  • Репутация: 432
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.12.0
Re: Простой парсер HTML кода
« Ответ #24, Отправлен: Февраль 08, 2015, 13:24:43 »
Вот так аттрибуты можно получить:
Код: AutoIt [Выделить]
$tag = '<img src="http://autoit-script.ru/Themes/default/images/icons/modify_inline.gif" alt="Редактировать сообщение" title="Редактировать сообщение" class="modifybutton" id="modify_button_71833" style="cursor: pointer;" onclick="oQuickModify.modifyMsg(''71833'')">';
$document = ObjCreate('HtmlFile')
$document.write($tag)
$attributes = $document.GetElementById('modify_button_71833').Attributes
For $item = 0 To $attributes.length - 1
    ConsoleWrite($attributes.item($item).name  & '=' & $attributes.item($item).Value & @CRLF)
Next

title=Редактировать сообщение
class=modifybutton
id=modify_button_71833
style=cursor: pointer;
onclick=oQuickModify.modifyMsg('71833')
alt=Редактировать сообщение
src=http://autoit-script.ru/Themes/default/images/icons/modify_inline.gif

Оффлайн madmasles [?]

  • Глобальный модератор
  • *
  • Сообщений: 7790
  • Репутация: 2312
  • Пол: Мужской
  • Награды За модерирование форума
    • Награды
  • Версия AutoIt: 3.3.x.x
Re: Простой парсер HTML кода
« Ответ #25, Отправлен: Февраль 08, 2015, 14:07:40 »
inververs,
У меня с Вашим кодом (IE8) вот такая простыня:
(нажмите для показа/скрытия)
« Последнее редактирование: Февраль 08, 2015, 17:04:20 от madmasles »

Оффлайн Garrett [?]

  • Глобальный модератор
  • *
  • Сообщений: 3573
  • Репутация: 923
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.12.0
Re: Простой парсер HTML кода
« Ответ #26, Отправлен: Февраль 08, 2015, 16:41:17 »
CreatoR  [?]
Цитировать
но как мне получить только те что относятся к найденному (по id) элементу?
Код: AutoIt [Выделить]
$sHTML = _
    '<body>' & @CRLF & _
    '   <span id="users">' & @CRLF & _
    '       <div id="user">User1</div>' & @CRLF & _
    '       <div id="user">User2</div>' & @CRLF & _
    '       <div id="user">User3</div>' & @CRLF & _
    '   </span>' & @CRLF & _
    '   <span id="logins" class="logins">' & @CRLF & _
    '       <div id="login">login1</div>' & @CRLF & _
    '       <div id="login">login2</div>' & @CRLF & _
    '       <div id="login">login3</div>' & @CRLF & _
    '   </span>' & @CRLF & _
    '</body>'

$oHTML = ObjCreate('HtmlFile')
$oHTML.Open
$oHTML.Write($sHTML)
$oHTML.Close

$oAllCollection = $oHTML.all
$oUsersCollection = $oAllCollection.users.children
ConsoleWrite(StringFormat('--> users: [%d]\n', $oUsersCollection.length))

For $oUser In $oUsersCollection
    ConsoleWrite(StringFormat('> id: %s --> %s\n', $oUser.id, $oUser.innerText))
Next

$oLoginsCollection = $oAllCollection.logins.children
ConsoleWrite(StringFormat('--> logins: [%d]\n', $oLoginsCollection.length))

For $oLogin In $oLoginsCollection
    ConsoleWrite(StringFormat('> id: %s --> %s\n', $oLogin.id, $oLogin.innerText))
Next



Добавлено: Февраль 08, 2015, 17:13:18
CreatoR
Кстати, id индивидуален для каждого элемента.
В вашем примере, лучше использовать class="user" и class="login".


Добавлено: Февраль 08, 2015, 17:24:30
Как пример:
(нажмите для показа/скрытия)
« Последнее редактирование: Февраль 08, 2015, 17:25:08 от Garrett »

Скорблю и помню.




Оффлайн CreatoR [?]

  • Администратор
  • *
  • Сообщений: 7759
  • Репутация: 2274
  • Пол: Мужской
  • AutoIt is simple, subtle, elegant
    • CreatoR's Lab
    • Награды
  • Версия AutoIt: 3.3.10.2
Re: Простой парсер HTML кода
« Ответ #27, Отправлен: Февраль 10, 2015, 13:21:12 »
Сделал некую библиотеку псевдо XPath :laugh: (см. вложение).


Внимание: Для просмотра прикреплённых файлов необходимо Войти или Зарегистрироваться

Оффлайн CreatoR [?]

  • Администратор
  • *
  • Сообщений: 7759
  • Репутация: 2274
  • Пол: Мужской
  • AutoIt is simple, subtle, elegant
    • CreatoR's Lab
    • Награды
  • Версия AutoIt: 3.3.10.2
Re: Простой парсер HTML кода
« Ответ #28, Отправлен: Февраль 10, 2015, 13:22:42 »
И потом понял, что зря...

Код: AutoIt [Выделить]
$sHTML = _
    '<body>' & @CRLF & _
    '   <span id="users" class="users">' & @CRLF & _
    '       <div id="user">User1</div>' & @CRLF & _
    '       <div id="user" class="user">User2</div>' & @CRLF & _
    '       <div id="user" class="user">User3</div>' & @CRLF & _
    '   </span>' & @CRLF & _
    '   <span id="logins" class="logins">' & @CRLF & _
    '       <div id="login">login1</div>' & @CRLF & _
    '       <div id="login">login2</div>' & @CRLF & _
    '       <div id="login">login3</div>' & @CRLF & _
    '   </span>' & @CRLF & _
    '</body>'


$sXPath = '*/span[(@id="users" or @class="users")]/div[@id="user"][1]'
$oNode = _XHtmlXPath_SelectNode($sHTML, $sXPath)

ConsoleWrite(_XHtmlXPath_GetNodeValue($oNode) & @LF)

Func _XHtmlXPath_SelectNode($sXHTML, $sXPath)
    Local $oXMLDOM = ObjCreate('Msxml2.DOMDocument.3.0')
   
    If Not IsObj($oXMLDOM) Then
        Return SetError(1, 0, 0)
    EndIf
   
    $oXMLDOM.loadXML($sXHTML)
    Return $oXMLDOM.selectSingleNode($sXPath)
EndFunc

Func _XHtmlXPath_GetNodeValue($oNode, $sValue = 'Text')
    If Not IsObj($oNode) Then
        Return SetError(1, 0, 0)
    EndIf
   
    If $sValue = 'Text' Then
        Return $oNode.Text
    EndIf
   
    Return $oNode.Xml
EndFunc


Мораль - не изобретайте велосипед!!!

Оффлайн CreatoR [?]

  • Администратор
  • *
  • Сообщений: 7759
  • Репутация: 2274
  • Пол: Мужской
  • AutoIt is simple, subtle, elegant
    • CreatoR's Lab
    • Награды
  • Версия AutoIt: 3.3.10.2
Re: Простой парсер HTML кода
« Ответ #29, Отправлен: Февраль 10, 2015, 19:58:39 »
А нет, не зря.
Msxml2.DOMDocument не работает с реальным Html полученным с интернета (к примеру тот же autoitscript.com).

Русское сообщество AutoIt

Re: Простой парсер HTML кода
« Ответ #29 Отправлен: Февраль 10, 2015, 19:58:39 »

 

Похожие темы

  Тема / Автор Ответов Последний ответ
0 Ответов
4677 Просмотров
Последний ответ Сентябрь 12, 2010, 11:08:09
от damien2008
4 Ответов
5788 Просмотров
Последний ответ Апрель 23, 2012, 19:14:27
от ggzgamer
5 Ответов
2308 Просмотров
Последний ответ Октябрь 31, 2014, 14:07:45
от denispuh
1 Ответов
1983 Просмотров
Последний ответ Апрель 20, 2013, 21:12:41
от sngr
3 Ответов
1683 Просмотров
Последний ответ Сентябрь 28, 2013, 13:38:52
от bdkitty
0 Ответов
554 Просмотров
Последний ответ Июль 24, 2014, 19:17:23
от e.belykh
8 Ответов
2097 Просмотров
Последний ответ Март 06, 2015, 21:17:45
от Nosfer_x
30 Ответов
12593 Просмотров
Последний ответ Апрель 26, 2015, 11:54:58
от Garrett
0 Ответов
678 Просмотров
Последний ответ Апрель 22, 2015, 17:49:49
от madmasles
1 Ответов
2123 Просмотров
Последний ответ Июнь 22, 2015, 13:17:44
от madmasles