Форум » [x]Harbour » Работа с HTML(Сайты в Интернет) » Ответить

Работа с HTML(Сайты в Интернет)

Softlog86: Друзья , подскажите в каком направлении рыть ... Есть сайт в интернете . Там поле для ввода строки поиска . .... Вводим строку . Сайт выдаёт (если найдёт у себя в базе) какую-то информацию в виде HTML-странички .... Задача такая : Программа на Harbour должна делать запрос на сайт и полученную информацию отображать в своём окне . При этом нужно кой-чего из этой информации убрать или заменить некоторые слова ( сайт буржуйский ) . Хочу прилепить как-бы On-Line поиск .... но чтоб данные брать с чужого сайта .... Какие будут мысли ? Или не связываться с такой задачей ?

Ответов - 47, стр: 1 2 3 All

Andrey: Смотри тему http://clipper.borda.ru/?1-3-0-00000218-000-0-0-1342804573 AlexMyr пишет: Посмотри на harbour\examples\guestbk , может на что и натолкнет, сам не пробовал.

AlexMyr: Для Harbour вот (как раз поисковик задействован) harbour\contrib\hbtip\tests\loadhtml.prg

Andrey: AlexMyr пишет: harbour\contrib\hbtip\tests\loadhtml.prg Как хоть собрать этот пример ? Опять забыл как это делать....


PSP: Может так: hbmk2 loadhtml.prg ?

Andrey: PSP пишет: Может так: hbmk2 loadhtml.prg ? А что за файлы в папке лежат ? hbtip.hbc hbtipssl.hbc hbmk.hbm Я через них пытался собрать...

Andrey: PSP пишет: Может так: hbmk2 loadhtml.prg ? Выдает ошибку при выполнении:

AlexMyr: Проверил у себя, работает. Version: Harbour 3.2.0dev (Rev. 18385) Compiler: MinGW GNU C 4.7 (32-bit) Platform: Windows XP 5.1.2600 Service Pack 3 [pre2]C:\dev\_svn\harbour\contrib\hbtip\tests\>loadhtml.exe 56024 bytes received Search http://www.google.de/webhp?hl=en&tab=ww Translate http://translate.google.de/?hl=en&q=Harbour&um=1&ie=UTF-8&sa=N&tab=wT Books http://www.google.de/search?hl=en&q=Harbour&um=1&ie=UTF-8&tbo=u&tbm=bks&so urce=og&sa=N&tab=wp Shopping http://www.google.de/products?hl=en&q=Harbour&um=1&ie=UTF-8&sa=N&tab=wf Blogger http://www.blogger.com/?tab=wj Reader http://www.google.de/reader/view/?hl=en&tab=wy Photos http://picasaweb.google.de/lh/view?hl=en&q=Harbour&um=1&ie=UTF-8&sa=N&tab =wq Videos http://www.google.de/search?hl=en&q=Harbour&um=1&ie=UTF-8&tbo=u&tbm=vid&s ource=og&sa=N&tab=wv Even more » http://www.google.de/intl/en/options/[/pre2]

AlexMyr: да, вот результат, к-й в файле Google.html

Softlog86: Спасибо за подсказку ! Теперь осталось дело за малым - разобраться как сформировать строку запроса к "их" базе .... Полученный HTML-код разобрать тоже сложно ....но можно :)

Pasha: Можно ли подобными запросами выбирать курсы валют ЦБ/НБУ, учетные ставки, индекс инфляции и тому подобную информацию ? Если можно, то с каких сайтов ?

AlexMyr: Pasha пишет: Можно ли подобными запросами выбирать курсы валют ЦБ/НБУ, учетные ставки, индекс инфляции и тому подобную информацию ? Если можно, то с каких сайтов ? Я думаю можно. Вот код выдергивает страницу с курсами с нбу, потом только разобрать таблицу с курсами и вывести в удобной форме: [pre2]/* * $Id: loadhtml.prg 18289 2012-10-11 16:16:32Z vszakats $ */ /* * Sends a query to Google and displays the Links from the response HTML page */ #require "hbtip" PROCEDURE Main LOCAL oHttp, cHtml, aLink, oNode, oDoc oHttp := TIpClientHttp():new( "http://www.bank.gov.ua/control/uk/curmetal/detail/currency?period=daily" ) /* Connect to the HTTP server */ IF ! oHttp:open() ? "Connection error:", oHttp:lastErrorMessage() QUIT ENDIF /* download the Google response */ cHtml := oHttp:readAll() oHttp:close() ? Len( cHtml ), "bytes received " oDoc := THtmlDocument():new( cHtml ) oDoc:writeFile( "Google.html" ) /* ":a" retrieves the first <a href="url"> text </a> tag */ oNode := oDoc:body:a ? oNode:getText( "" ), oNode:href /* ":divs(5)" returns the 5th <div> tag */ oNode := oDoc:body:divs( 5 ) /* "aS" is the plural of "a" and returns all <a href="url"> tags */ aLink := oNode:aS FOR EACH oNode IN aLink ? HtmlToOem( oNode:getText( "" ) ), oNode:href NEXT RETURN [/pre2]

Pasha: Спасибо. Заодно я обратил внимание на незнакомую мне директиву hbmk2 #require.

petr707: Для получения курсов валют есть веб-сервисы (например http://www.cbr.ru/scripts/Root.asp?Prtid=DWS) и поддержка SOAP , пример в \contrib\hbwin\testole.prg Придется, правда, на комп дополнительно установить пакет SOAP ToolKit 3.0 от MS

AlexMyr: Pasha пишет: Заодно я обратил внимание на незнакомую мне директиву hbmk2 #require. Директива позволяет запускать prg как скрипт, но для этого как я понял нужно собрать hbrun c -shared.

santy: AlexMyr пишет: /* * $Id: loadhtml.prg 18289 2012-10-11 16:16:32Z vszakats $ */ /* * Sends a query to Google and displays the Links from the response HTML page */ #require "hbtip" PROCEDURE Main LOCAL oHttp, cHtml, aLink, oNode, oDoc oHttp := TIpClientHttp():new( "http://www.bank.gov.ua/control/uk/curmetal/detail/currency?period=daily" ) /* Connect to the HTTP server */ IF ! oHttp:open() ? "Connection error:", oHttp:lastErrorMessage() QUIT ENDIF /* download the Google response */ cHtml := oHttp:readAll() oHttp:close() ? Len( cHtml ), "bytes received " oDoc := THtmlDocument():new( cHtml ) oDoc:writeFile( "Google.html" ) /* ":a" retrieves the first <a href="url"> text </a> tag */ oNode := oDoc:body:a ? oNode:getText( "" ), oNode:href /* ":divs(5)" returns the 5th <div> tag */ oNode := oDoc:body:divs( 5 ) /* "aS" is the plural of "a" and returns all <a href="url"> tags */ aLink := oNode:aS FOR EACH oNode IN aLink ? HtmlToOem( oNode:getText( "" ) ), oNode:href NEXT RETURN Этот код работает только тогда когда нет ошибки 302 (перенаправление). Если ошибка 302 можно скачать другим способом: [pre2] Пример: IF oHttp:open(cUrl) cHtml := oHttp:readAll() if oHttp:nReplyCode == 302 _resGetFile := GETINETFILE(cFileURL,сFileName) else ...... endif endif ...... #PRAGMA BEGINDUMP #include <windows.h> #include <wininet.h> #include "hrbdll.h" #include "hbapi.h" #include "hbapiitm.h" #include "hbapierr.h" HB_FUNC( GETINETFILE ) { HINTERNET hSession; HINTERNET hURL; HANDLE hFile; char * sAppName= "GetPublicIpAddress"; char * FileURL; char * _FileName ; char Buffer[1024]; DWORD dwRead =0; DWORD dwWrite = 0; BOOL bFound = FALSE; FileURL = hb_parc(1); _FileName = (char *) hb_parc(2); hSession = InternetOpen(sAppName, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0 ); if (hSession) { hURL = InternetOpenUrl(hSession, FileURL, NULL, 0, 0, 0); if (hURL) { hFile = CreateFile(_FileName, GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); while (InternetReadFile(hURL, Buffer, 1024, &dwRead) == TRUE) { if ( dwRead == 0) break; WriteFile(hFile, Buffer, dwRead, &dwWrite, NULL); bFound = TRUE; } CloseHandle(hFile); InternetCloseHandle(hURL); } InternetCloseHandle(hSession); } hb_retl(bFound); } #PRAGMA ENDDUMP [/pre2]

a_sidorov: Класс TIPClientHTTP() в Наrbour 3.2 и xHarbour 1.2.1 содержит одну недоработку – указана длина буфера при чтении строки 500, а это неправильно, поскольку размер заголовка (hHeaders) часто превышает эту величину. Отсюда и все проблемы. Кроме того класс TIPClientHTTP() в Наrbour 3.0 и 3.1 содержит ошибку, которая исправлена в Наrbour 3.2, она может возникнуть при сложных запросах (например массив ХЭШ с login и password). Мои действия и как я это обошел: Работаю на xHarbour 1.2.1 (CRM и 2 сервера leto с программой синхронизации между ними) и xHarbour 1.0.0 (бухгалтерия). Решаю следующую задачу – передачу и прием данных (синхронизация ) таблиц DBF и данных на WEB по протоколу HTTP: 1. Обращение к странице авторизации программы для получения Cookie и Token из данных страницы. 2. Автоизация в WEB программе - Передача (POST) Login и Password , Cookie и Token на страницу авторизации и получения кода ответа nReplyCode : =302,cReplyDescr : "Found" и нового Cookie . 3. Обращение GET по адресу таблица.json и получение json Мои действия: 1. Беру xHarbour 1.2.1, класс TIPClientHTTP(). Получаю – что класс нерабочий, а именно – для чтения данных в классе используется метод ::InetRecvLine из класса tIPClientHTTP (соответственно INETRECVLINE в inet.c), а он работает некорректно. Вставляет пустую строку в середине заголовка (:hHeaders), теряя часть заголовка (в моем случае Cookie) и кидая остаток заголовка в данные. Беру копию метода POST и меняю ::InetRecvLine на ::InetRecvALL – вытягиваю Cookie. После этого ставлю :hFields["X-Requested-With"]:="XMLHttpRequest" :setCookie(sess_Cookies) Даю GET() и получаю json 2. Беру Наrbour 3.0 и Наrbour 3.1 , класс TIPClientHTTP() – получаю ошибку Error BASE/1123 Argument error: HB_HKEYAT Смотрю ChangeLog – ошибка исправлена 2012-07-30 (то есть в 3.2) 3. Беру Наrbour 3.2 последней сборки – ошибка Наrbour 3.1 действительно исправлена, но json получить не могу. Оказалось, что работающий код в xHarbour 1.2.1 oxml:=THtmlDocument():new(Cdata) oNode := oxml:findFirst( 'input', 'name','authenticity_token') a_token :=onode:getattribute('value') в Наrbour 3.2 почему-то не работает. Достаю 'authenticity_token' руками и получаю ту же проблему что и Наrbour 3.1 - ::InetRecvLine режет заголовок пополам и теряет Cookie. После разбора текстов все-таки догадался изменить везде при вызове - ::InetRecvLine в классе TIPClientHTTP() размер буфера с 500 на 1000 cLine := ::inetRecvLine( ::SocketCon, @nPos, 1000 ) После этого получил json. Заголовки (:hHeaders) тоже нормально разбираются. Необходимо исправить размер буфера при вызове :inetRecvLine в дистрибутиве Наrbour с 500 на 1000.

Softlog86: Возвращаясь к старой теме , в примере LoadHTML.PRG есть код по поиску и доступу к тегам .... там расписано как брать ссылки ... Подскажите синтаксис и аогоритм по выуживанию данных из таблицы внутри HTML-страницы : <table и соответственно строк с данными из жтой таблицы . Вот такой примерно кусок текста из такой страницы : ...... <table class="list"> <tr class="alternating"> <td>0001124005 <---- Эти данные нужно считывать </td> </tr> <tr class="alternating"> <td>0001124006 <---- Эти данные нужно считывать </td> </tr> <tr class="alternating"> <td>02B911023D <---- Эти данные нужно считывать </td> </tr> ........ <---- и так далее по таблице </table> ......... То есть вопрос в том , как добратьться до объекта <table ? , и соответственно считать в массив все строки с нужными данными ? Буду благодарен за хоть какую-то информацию . Таблиц <tablе в тексте несколько , но добраться нужно к определенной (она по порядку всегда на одном и том-же месте ) число строк может быть разным ...

santy: Приблизительно будет так: oHtmlDoc:readFile( "HTML\\test.html") aTableNodes := oHtmlDoc:body:tableS // Возвращает все ноди для tags table FOR EACH oNodeTable IN aTableNodes // пробегаем по всем таблицам IF 'class="list"' IN ALLTRIM(oNodeTable:attrToString()) // наша таблица FOR EACH otdNode1 IN oNodeTable:tdS // считываем tags td cAllData:=ALLTRIM(HtmlToAnsi(otdNode1:getText(""))) // считываем наш текст ........ // что-то с ними делаем NEXT ENDIF NEXT можна вместо attrToString() использовать :getAttribute( "class" ) если есть tr c разными классами тогда нужно считать сначала tr, найти ссответсвующий класс (атрибут) а потом уже считывать td и соответсвенно данные.

Softlog86: Есть ошибки и недостаточность кода : oHtmlDoc:readFile( "HTML\\test.html") aTableNodes := oHtmlDoc:body:tableS // Возвращает все ноди для tags table // oNodeTable - откуда взялось ? FOR EACH oNodeTable IN aTableNodes // пробегаем по всем таблицам IF 'class="list"' IN ALLTRIM(oNodeTable:attrToString()) // наша таблица // otdNode1 -откуда взялось ? FOR EACH otdNode1 IN oNodeTable:tdS // считываем tags td cAllData:=ALLTRIM(HtmlToAnsi(otdNode1:getText(""))) // считываем наш текст ........ // что-то с ними делаем NEXT ENDIF NEXT

santy: Ошибок думаю нету так как приблизительный код работает. Код для xHarbour. Для Harbour IN -> $. Всё остальное работало в Harbour. в начале объявите LOCAL aTableNodes:={}, oNodeTable, otdNode1 Посмотрите описание класса THtmlNode() в доке по xHarbour. Он должен быть аналогичный Harbour.



полная версия страницы