Добро пожаловать в форум, Guest >> Войти | Регистрация | Поиск | Правила | | В избранное | Подписаться | ||
Все форумы / Delphi |
![]() ![]() |
Топик располагается на нескольких страницах: ←Ctrl назад 1 2 [3] 4 5 6 вперед Ctrl→ все |
ziv-2014 Member Откуда: Сообщений: 589 |
X11, Сформулируй задачу! |
28 авг 19, 16:01 [21959207] Ответить | Цитировать Сообщить модератору |
X11 Member Откуда: Kharkiv, Ukraine Сообщений: 15044 |
Парсинг сайта в отдельном потоке с использованием Cef4Delphi без дополнительного окна. По ходу действа искать не только нужный текст, который можно сохранить в базу, но и нужный текст ссылок, по которым нужно кликать, например, чтобы открыть объявление, контакты или вернуться назад и перейти не следующую страницу. |
28 авг 19, 16:11 [21959222] Ответить | Цитировать Сообщить модератору |
ziv-2014 Member Откуда: Сообщений: 589 |
Зачем парсить сайт в отдельном потоке? Chromium создает несколько процессов для парсинга, тебе этого мало? Может сделать со скрытым окном? |
||
28 авг 19, 16:21 [21959234] Ответить | Цитировать Сообщить модератору |
X11 Member Откуда: Kharkiv, Ukraine Сообщений: 15044 |
сейчас это вопрос изучаю 21959107 |
||
28 авг 19, 16:27 [21959245] Ответить | Цитировать Сообщить модератору |
X11 Member Откуда: Kharkiv, Ukraine Сообщений: 15044 |
потому что не хочется создавать новый проект и новую программу, в которой уже есть несколько других работающих парсеров, так сказать оболочка есть и к ней нужно прикрутить ещё один с браузером и чтобы не машать работе пользователя. |
||
28 авг 19, 16:29 [21959248] Ответить | Цитировать Сообщить модератору |
ziv-2014 Member Откуда: Сообщений: 589 |
X11, Разве примера из DOMVisitor не достаточно? |
28 авг 19, 16:35 [21959254] Ответить | Цитировать Сообщить модератору |
X11 Member Откуда: Kharkiv, Ukraine Сообщений: 15044 |
получилось без окон и панелей загрузить страницу в фоне и выполнить JS constJS = 'var links = document.querySelectorAll("a.link-ajax.j-v-contacts-expand-link"); ' + 'if (links) { ' + ' for (var x = 0; x <= links.length; x++) { ' + ' if (links[x]) { ' + ' if (links[x].innerHTML.trim().indexOf("показать контакты") != -1) { ' + ' links[x].click(); ' + ' console.log("my click"); ' + ' } ' + ' } ' + ' }' + '}'; В итоге в консоль в DevTools попало сообщение "my click" |
||||
28 авг 19, 16:36 [21959256] Ответить | Цитировать Сообщить модератору |
ziv-2014 Member Откуда: Сообщений: 589 |
Вы не понимаете, как работает chromium. Там есть очередь обработки сообщений. Все операции выполняются в отдельных потоках. Результат выводится в главный поток для отображения. Все операции, которые происходят внутри, chromium уже распределяет по нужным ему потокам. Если вам надо сделать в отдельном потоке, то вам надо делать окно в отдельном потоке и обрабатывать сообщения этого окна. Но по-моему это большие грабельки. |
||||
28 авг 19, 16:40 [21959262] Ответить | Цитировать Сообщить модератору |
X11 Member Откуда: Kharkiv, Ukraine Сообщений: 15044 |
Изучаю три примера. На данный момент волнует вопрос, можно ли управлять общаться с браузером не из главного потока программы, а из дополнительного. Пока не пробовал. Пока изучаю ... |
||
28 авг 19, 16:42 [21959265] Ответить | Цитировать Сообщить модератору |
X11 Member Откуда: Kharkiv, Ukraine Сообщений: 15044 |
не спорю, поэтому и пытаюсь изучать и понять. К сожалению инфы на русском мало. |
||
28 авг 19, 16:42 [21959266] Ответить | Цитировать Сообщить модератору |
X11 Member Откуда: Kharkiv, Ukraine Сообщений: 15044 |
Подскажите, а что нужно указывать в качестве NodeID?procedure SimpleNodeSearch(const aDocument: ICefDomDocument; const frame: ICefFrame; const NodeID: string); var TempNode: ICefDomNode; msg: ICefProcessMessage; begin try if aDocument <> nil then begin TempNode := aDocument.GetElementById(NodeID); msg := TCefProcessMessageRef.New(msg_for_chromium); if TempNode <> nil then begin msg.ArgumentList.SetString(0, 'Node found: ' + NodeID); msg.ArgumentList.SetString(1, 'Node name: ' + TempNode.Name); msg.ArgumentList.SetString(2, 'ElementInnerText: ' + TempNode.ElementInnerText); msg.ArgumentList.SetString(3, 'ElementTagName: ' + TempNode.ElementTagName); end else msg.ArgumentList.SetString(0, 'ERROR. Node not found: ' + NodeID); frame.SendProcessMessage(PID_BROWSER, msg); end; except on e : exception do if CustomExceptionHandler('SimpleNodeSearch', e) then raise; end; end; передаю "ad-author-contact-row-content" или "ad-author-contact-row-content j-c-phones" и процедура его не находит. К сообщению приложен файл. Размер - 13Kb |
29 авг 19, 13:52 [21959833] Ответить | Цитировать Сообщить модератору |
asviridenkov Member Откуда: Сообщений: 4028 |
X11, Это классы а не id |
29 авг 19, 13:58 [21959839] Ответить | Цитировать Сообщить модератору |
X11 Member Откуда: Kharkiv, Ukraine Сообщений: 15044 |
Ну т.е. с помощью GetElementById не получится? |
29 авг 19, 14:04 [21959847] Ответить | Цитировать Сообщить модератору |
asviridenkov Member Откуда: Сообщений: 4028 |
X11, нет |
29 авг 19, 14:29 [21959870] Ответить | Цитировать Сообщить модератору |
X11 Member Откуда: Kharkiv, Ukraine Сообщений: 15044 |
ок, тогда с помощью чего найти телефон или признак телефона во время итерации по DOM?procedure SimpleDOMIteration(const aDocument: ICefDomDocument; const frame: ICefFrame); var TempHead, TempChild : ICefDomNode; msg: ICefProcessMessage; begin try if aDocument <> nil then begin TempHead := aDocument.Body; if TempHead <> nil then begin TempChild := TempHead.FirstChild; while TempChild <> nil do begin Msg := TCefProcessMessageRef.New(msg_for_chromium); if TempChild.ElementInnerText = '' then begin TempChild := TempChild.NextSibling; Continue; end; msg.ArgumentList.SetString(0, 'name: ' + Trim(TempChild.Name)); msg.ArgumentList.SetString(1, 'TagName: ' + Trim(TempChild.ElementTagName)); msg.ArgumentList.SetString(2, 'InnerText: ' + Trim(TempChild.ElementInnerText)); frame.SendProcessMessage(PID_BROWSER, msg); TempChild := TempChild.NextSibling; end; end; end; except on e : exception do if CustomExceptionHandler('SimpleDOMIteration', e) then raise; end; end; |
29 авг 19, 15:07 [21959915] Ответить | Цитировать Сообщить модератору |
asviridenkov Member Откуда: Сообщений: 4028 |
X11, Ну например использовать префикс tel в href |
29 авг 19, 15:09 [21959916] Ответить | Цитировать Сообщить модератору |
X11 Member Откуда: Kharkiv, Ukraine Сообщений: 15044 |
не понял |
||
29 авг 19, 15:13 [21959921] Ответить | Цитировать Сообщить модератору |
X11 Member Откуда: Kharkiv, Ukraine Сообщений: 15044 |
Если на примере цикла итерации по DOM, то как?procedure SimpleDOMIteration(const aDocument: ICefDomDocument; const frame: ICefFrame); var TempHead, TempChild : ICefDomNode; msg: ICefProcessMessage; attrList: TStrings; begin try if aDocument <> nil then begin TempHead := aDocument.Body; if TempHead <> nil then begin TempChild := TempHead.FirstChild; while TempChild <> nil do begin Msg := TCefProcessMessageRef.New(msg_for_chromium); if TempChild.ElementInnerText = '' then begin TempChild := TempChild.NextSibling; Continue; end; msg.ArgumentList.SetString(0, 'name: ' + Trim(TempChild.Name)); msg.ArgumentList.SetString(1, 'TagName: ' + Trim(TempChild.ElementTagName)); attrList := TStringList.Create; try TempChild.GetElementAttributes(attrList); msg.ArgumentList.SetString(2, 'attrList: ' + attrList.Text); finally attrList.DisposeOf; end; msg.ArgumentList.SetString(3, 'InnerText: ' + Trim(TempChild.ElementInnerText)); msg.ArgumentList.SetString(4, '**********************'); frame.SendProcessMessage(PID_BROWSER, msg); TempChild := TempChild.NextSibling; end; end; end; except on e : exception do if CustomExceptionHandler('SimpleDOMIteration', e) then raise; end; end; |
29 авг 19, 15:19 [21959930] Ответить | Цитировать Сообщить модератору |
X11 Member Откуда: Kharkiv, Ukraine Сообщений: 15044 |
Я ещё не могу понять/найти: в каком свойстве, где живёт то, что на картинке подчеркнуто в программе в ICefDomNode? Т.е. как выловить, в каком свойстве вот то название класса "ad-author-contact-row-content j-c-phones", чтобы как можно ближе подобраться к телефону. Т.е. когда я в Firefox выбираю "копировать/внутренний HTML", то копируется:
К сообщению приложен файл. Размер - 4Kb |
||
29 авг 19, 15:24 [21959935] Ответить | Цитировать Сообщить модератору |
X11 Member Откуда: Kharkiv, Ukraine Сообщений: 15044 |
я забыл про рекурсию |
29 авг 19, 15:59 [21959966] Ответить | Цитировать Сообщить модератору |
X11 Member Откуда: Kharkiv, Ukraine Сообщений: 15044 |
в общем, там ещё есть "TempChild.AsMarkup", т.е. можно использолвать вместо "TempChild.ElementInnerText" |
||
30 авг 19, 12:04 [21960433] Ответить | Цитировать Сообщить модератору |
X11 Member Откуда: Kharkiv, Ukraine Сообщений: 15044 |
извините за такой вопрос, но сегодня пятница, так что можно ![]() Я не могу понять, обходит ли SimpleDOMIteration() ВСЕ узлы и все уровни дерева DOM или только узлы верхнего уровня? Процедура не является рекурсивной, но вижу заход (TempChild := TempHead.FirstChild) на дочерние узлы. |
||
30 авг 19, 13:20 [21960514] Ответить | Цитировать Сообщить модератору |
X11 Member Откуда: Kharkiv, Ukraine Сообщений: 15044 |
В общем, вот такая конструкция у меня получилась, может кому пригодится.
|
|
30 авг 19, 15:48 [21960672] Ответить | Цитировать Сообщить модератору |
JayDi Member Откуда: Сызрань, Россия Сообщений: 4144 |
Это же жесть -- вручную перебирать всю структуру DOM. Есть всякие css-селекторы, которые простыми командами могут найти и вывести любое количество элементов. Судя по вот этому -- CEF полностью поддерживает querySelectorAll. |
31 авг 19, 22:43 [21961333] Ответить | Цитировать Сообщить модератору |
X11 Member Откуда: Kharkiv, Ukraine Сообщений: 15044 |
Это просто один из способов. Тем более, не надо изучать JS. |
1 сен 19, 09:50 [21961400] Ответить | Цитировать Сообщить модератору |
Топик располагается на нескольких страницах: ←Ctrl назад 1 2 [3] 4 5 6 вперед Ctrl→ все |
Все форумы / Delphi | ![]() |