Тема: AHK: Получение элемента из <a href => из IE
Здравствуйте!
В браузере на странице есть следующий элемент:
<a href="/asd-dsa">Dsaasd</a>
Мне нужно из этого извлечь "/asd-dsa", желательно, не используя RegEx.
Заранее спасибо за ответы.
Вы не вошли. Пожалуйста, войдите или зарегистрируйтесь.
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться
Здравствуйте!
В браузере на странице есть следующий элемент:
<a href="/asd-dsa">Dsaasd</a>
Мне нужно из этого извлечь "/asd-dsa", желательно, не используя RegEx.
Заранее спасибо за ответы.
Этот элемент называется «ссылка». Она там одна?
teadrinker, вроде одна.
Тогда так примерно:
linkText := "Dsaasd"
oIE := WBGet()
if !IsObject(oIE) {
MsgBox, Не удалось получить объект InternetExplorer
return
}
links := oIE.document.links, href := ""
Loop % links.length {
link := links[A_Index - 1]
if (link.innerText = linkText && href := link.href)
break
}
MsgBox, % href ? href : "Не найдено"
WBGet(WinTitle := "ahk_class IEFrame", Svr# := 1)
{
static msg := DllCall("RegisterWindowMessage", Str, "WM_HTML_GETOBJECT")
, IID_IWebBrowserApp := "{0002DF05-0000-0000-C000-000000000046}"
, IID_IHTMLDocument2 := "{332C4425-26CB-11D0-B483-00C04FD90119}"
, VT_DISPATCH := 9, F_OWNVALUE := 1
SendMessage, msg, 0, 0, Internet Explorer_Server%Svr#%, %WinTitle%
lResult := ErrorLevel
if (lResult = "FAIL")
return
VarSetCapacity(GUID, 16, 0)
DllCall("ole32\CLSIDFromString", WStr, IID_IHTMLDocument2, Ptr, &GUID)
DllCall("oleacc\ObjectFromLresult", Ptr, lResult, Ptr, &GUID, Ptr, 0, PtrP, pdoc)
oWb := ComObject(VT_DISPATCH, ComObjQuery(pdoc, IID_IWebBrowserApp, IID_IWebBrowserApp), F_OWNVALUE)
ObjRelease(pdoc)
return oWb
}
Спасибо за способ, но он не подходит для решения. Дело в том, что узнать саму ссылку мне и нужно по причине динамичного текста.
Есть страница, что время от времени обновляется, в ней появляются разные ссылки с разным текстом. Нужно проверить, нужная мне ссылка сейчас или нет, а текст всё время разный.
Если ссылка всего одна на странице, тогда так:
oIE := WBGet()
if !IsObject(oIE) {
MsgBox, Не удалось получить объект InternetExplorer
return
}
MsgBox, % oIE.document.links[0].href
WBGet(WinTitle := "ahk_class IEFrame", Svr# := 1)
{
static msg := DllCall("RegisterWindowMessage", Str, "WM_HTML_GETOBJECT")
, IID_IWebBrowserApp := "{0002DF05-0000-0000-C000-000000000046}"
, IID_IHTMLDocument2 := "{332C4425-26CB-11D0-B483-00C04FD90119}"
, VT_DISPATCH := 9, F_OWNVALUE := 1
SendMessage, msg, 0, 0, Internet Explorer_Server%Svr#%, %WinTitle%
lResult := ErrorLevel
if (lResult = "FAIL")
return
VarSetCapacity(GUID, 16, 0)
DllCall("ole32\CLSIDFromString", WStr, IID_IHTMLDocument2, Ptr, &GUID)
DllCall("oleacc\ObjectFromLresult", Ptr, lResult, Ptr, &GUID, Ptr, 0, PtrP, pdoc)
oWb := ComObject(VT_DISPATCH, ComObjQuery(pdoc, IID_IWebBrowserApp, IID_IWebBrowserApp), F_OWNVALUE)
ObjRelease(pdoc)
return oWb
}
Если не одна, а текст меняется, тогда по какому признаку искать?
teadrinker, а не нужно искать конкретную) Нужно перебрать все в надежде на соответствие с нужной.
В теории можно через innerHTML и RegEx, но просто надеялся, что есть DOM функция для извлекания ссылки, ибо так надёжнее.
А в чём должно быть соответствие?
Все можно так перебрать:
oIE := WBGet()
if !IsObject(oIE) {
MsgBox, Не удалось получить объект InternetExplorer
return
}
links := oIE.document.links
Loop % links.length {
link := links[A_Index - 1]
MsgBox, % "Link text: " . link.innerText . "`nLink href: " . link.href
}
WBGet(WinTitle := "ahk_class IEFrame", Svr# := 1)
{
static msg := DllCall("RegisterWindowMessage", Str, "WM_HTML_GETOBJECT")
, IID_IWebBrowserApp := "{0002DF05-0000-0000-C000-000000000046}"
, IID_IHTMLDocument2 := "{332C4425-26CB-11D0-B483-00C04FD90119}"
, VT_DISPATCH := 9, F_OWNVALUE := 1
SendMessage, msg, 0, 0, Internet Explorer_Server%Svr#%, %WinTitle%
lResult := ErrorLevel
if (lResult = "FAIL")
return
VarSetCapacity(GUID, 16, 0)
DllCall("ole32\CLSIDFromString", WStr, IID_IHTMLDocument2, Ptr, &GUID)
DllCall("oleacc\ObjectFromLresult", Ptr, lResult, Ptr, &GUID, Ptr, 0, PtrP, pdoc)
oWb := ComObject(VT_DISPATCH, ComObjQuery(pdoc, IID_IWebBrowserApp, IID_IWebBrowserApp), F_OWNVALUE)
ObjRelease(pdoc)
return oWb
}
Моей идеей было получить полный список всех ссылок, а позже через цикл провести на наличие соответствий с нужной для меня.
А зачем позже, проверяйте прямо во время перебора.
teadrinker, неправильно выразился, это и имел в виду)
Я и сам находил ".links" и ".href" решения, но почему-то они не определяют ничего.. Вполне возможно, что я чего-то не понимаю, или просто криворукий.. Поэтому, наверное, воспользуюсь все-таки RegEx`ом.
Но всё же большое спасибо!)
Укажите конкретный сайт и какую ссылку хотите получить.
https://www.mmorpg.com/sweepstakes
Ссылки на игры, что находятся в классе "contestopen". Справа от описания есть названия игр, что являются ссылками, ссылки на игры из класса "contestopen" и нужны.
Ссылки находятся во фрейме:
oIE := ComObjCreate("InternetExplorer.Application")
oIE.visible := True
oIE.navigate("https://www.mmorpg.com/sweepstakes")
While oIE.busy
Sleep, 20
links := oIE.document.parentWindow.frames[6].document.links
Loop % links.length {
link := links[A_Index - 1]
MsgBox, % "Link text: " . link.innerText . "`nLink href: " . link.href
}
Не работает данный способ, возможно, Вы не совсем поняли, про какие ссылки я говорю.
У меня работает:
oIE := ComObjCreate("InternetExplorer.Application")
oIE.visible := True
oIE.navigate("https://www.mmorpg.com/sweepstakes")
While oIE.busy
Sleep, 20
links := oIE.document.links
Loop % links.length {
link := links[A_Index - 1]
if (link.innerText = "Hyper Universe")
MsgBox, % link.href
}
Malcev, да, этот код действительно работает! Спасибо.
А если мне нужно вывести ссылки из getElementsByClassName, то тогда как? Ибо если пробую после класса ставить .links, то выдаёт - undefined.
А в чем проблема? Приведите код.
Malcev, при вводе этого:
document.getElementsByClassName("contestopen")[0].cells[1].links
выводит undefined
document.getElementsByClassName("contestopen")[0].getElementsByTagName("a")[0].href
Также можно через QuerySelectorAll либо XPath, почитайте информацию сами если заинтересует.
Тогда так примерно:
linkText := "Dsaasd" oIE := WBGet() if !IsObject(oIE) { MsgBox, Не удалось получить объект InternetExplorer return } links := oIE.document.links, href := "" Loop % links.length { link := links[A_Index - 1] if (link.innerText = linkText && href := link.href) break } MsgBox, % href ? href : "Не найдено" WBGet(WinTitle := "ahk_class IEFrame", Svr# := 1) { static msg := DllCall("RegisterWindowMessage", Str, "WM_HTML_GETOBJECT") , IID_IWebBrowserApp := "{0002DF05-0000-0000-C000-000000000046}" , IID_IHTMLDocument2 := "{332C4425-26CB-11D0-B483-00C04FD90119}" , VT_DISPATCH := 9, F_OWNVALUE := 1 SendMessage, msg, 0, 0, Internet Explorer_Server%Svr#%, %WinTitle% lResult := ErrorLevel if (lResult = "FAIL") return VarSetCapacity(GUID, 16, 0) DllCall("ole32\CLSIDFromString", WStr, IID_IHTMLDocument2, Ptr, &GUID) DllCall("oleacc\ObjectFromLresult", Ptr, lResult, Ptr, &GUID, Ptr, 0, PtrP, pdoc) oWb := ComObject(VT_DISPATCH, ComObjQuery(pdoc, IID_IWebBrowserApp, IID_IWebBrowserApp), F_OWNVALUE) ObjRelease(pdoc) return oWb }
Здравствуйте. Воспользовался Вашим кодом. для моих целей работает превосходно. Но не могу понять как сделать так что бы в конце не выпрыгивало окно с ссылкой. не могли бы Вы помочь разобраться? Хотелось бы что бы ссылка просто записывалась в переменную допустим activlink. Но что бы не было этого окна по завершению скрипта. Но что бы осталось окно о том что ссылка не найдена.
Замените в примере, строку:
MsgBox, % href ? href : "Не найдено"
На:
if (href)
activlink := href
else
MsgBox, Не найдено.
KusochekDobra
Спасибо. Все работает хорошо.
Доброго времени суток! Вы не могли бы подсказать на примере вашего кода, который замечательно работает, как реализовать несколько иную задачу - необходимо на основе подстроки из link.href выбирать определенные ссылки, т.е. в данном вашем коде и примере с сайта нужно находить, возьмем тот же Hyper Universe, в атрибуте href="/sweepstakes/hyper-universe-mvp-starter-pack-sweepstakes-1000000057" подстроку hyper-universe, и выводить полную ссылку с этой подстрокой в тот же MsgBox. Я пробовал использовать if Var contains MatchList - if link.href contains hyper-universe, но в этом случае выводятся все ссылки подряд. Видимо, по неопытности я чего-то еще не понимаю.
У меня работает:
oIE := ComObjCreate("InternetExplorer.Application") oIE.visible := True oIE.navigate("https://www.mmorpg.com/sweepstakes") While oIE.busy Sleep, 20 links := oIE.document.links Loop % links.length { link := links[A_Index - 1] if (link.innerText = "Hyper Universe") MsgBox, % link.href }
По условию, отображаемый текст ссылки должен быть эквивалентен "Hyper Universe" без учёта регистра. Если нужны все ссылки, отображаемый текст которых содержит "Hyper Universe", можно записать так:
oIE := ComObjCreate("InternetExplorer.Application")
oIE.visible := True
oIE.navigate("https://www.mmorpg.com/sweepstakes")
While oIE.busy
Sleep, 20
links := oIE.document.links
Loop % links.length {
link := links[A_Index - 1]
if (CheckString(link.innerText, "Hyper Universe"))
MsgBox, % link.href
}
ExitApp
CheckString(mainStr, srchStr) {
if mainStr contains %srchStr%
return true
return false
}
Если нужны ссылки только из заголовков к каждой игре, то можно сделать выборку по классу и потом проходить циклом по её результату:
oIE := ComObjCreate("InternetExplorer.Application")
oIE.visible := True
oIE.navigate("https://www.mmorpg.com/sweepstakes")
While oIE.busy
Sleep, 20
links := oIE.document.querySelectorAll(".suhlink")
Loop % links.length {
link := links[A_Index - 1]
if (CheckString(link.innerText, "Hyper Universe"))
MsgBox, % link.href
}
ExitApp
CheckString(mainStr, srchStr) {
if mainStr contains %srchStr%
return true
return false
}
Если необходимо искать вхождения "hyper-universe" в тексте ссылки, замените условие:
if (CheckString(link.innerText, "Hyper Universe"))
На:
if (CheckString(link.href, "hyper-universe"))
Доброго времени суток! Вы не могли бы подсказать на примере вашего кода, который замечательно работает, как реализовать несколько иную задачу...
Сделал через IfInString и Array.Push (мне к тому же еще нужен именно последний элемент из списка идентичных ссылок.) Если кому интересно:
Larray := []
Needle = hyper-universe-
oIE := ComObjCreate("InternetExplorer.Application")
oIE.visible := True
oIE.navigate("https://www.mmorpg.com/sweepstakes")
While oIE.busy
Sleep, 20
links := oIE.document.links
; MsgBox % links.length
Loop % links.length {
link := links[A_Index - 1]
b := link.href
IfInString, b, %Needle%
{
; MsgBox, % link.href
Larray.Push(link.href)
}
}
z := Larray.MaxIndex()
MsgBox % "Последний элемент " Larray[z]
; for index, element in Larray ; здесь можно посмотреть, что в массиве
; {
; MsgBox % "Element number " . index . " is " . element
; }
KusochekDobra
Спасибо, опробую и ваш вариант.
p.s. я опоздал на 35 секунд )
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться