Особенности копирования текста страницы в CppWebBrowser на C++ Builder
автор evteev, Янв.02, 2010, рубрики C/C++/C#
В интернете выложено несколько похожих способов копирования текста (ну или html-текста, не суть) с компоненты CppWebBrowser.
Я использовал следующий рабочий вариант копирования html-текста в Memo:
IHTMLDocument2 *HTMLDocument = NULL;
IPersistFile *PersistFile = NULL;
LONG ilFramesCount = 0;
AnsiString slTmpFileExtension = ".html";
// Falls eine Seite geladen:
if(!Form1->CppWebBrowser1->Busy && Form1->CppWebBrowser1->Document &&
AnsiString(Form1->CppWebBrowser1->LocationURL) != "about:blank" &&
SUCCEEDED(Form1->CppWebBrowser1->Document->QueryInterface(IID_IHTMLDocument2, (LPVOID*)&HTMLDocument)))
{
// HTML-Code des Hauptdokuments speichern:
if(SUCCEEDED(HTMLDocument->QueryInterface(IID_IPersistFile,(LPVOID*)&PersistFile)))
{
// HTML-Code des Hauptdokuments speichern:
PersistFile->Save(WideString(String(ExtractFilePath(ParamStr(0))+"0"+slTmpFileExtension)), false);
PersistFile->Release();
// ggf. auch Frames-Code extrahieren:
IHTMLFramesCollection2 *pFrames = NULL;
if(SUCCEEDED(HTMLDocument->get_frames(&pFrames)))
{
// Anzahl der Frames bestimmen:
pFrames->get_length(&ilFramesCount);
if(ilFramesCount < 2) ilFramesCount= 0;
VARIANT vFrame;
VARIANT ret;
vFrame.vt = VT_UINT;
// f?r jedes Frame:
for(LONG ilFrameIndex = 0; ilFrameIndex < ilFramesCount; ilFrameIndex++)
{
vFrame.lVal = ilFrameIndex;
if(SUCCEEDED(pFrames->item(&vFrame, &ret)))
{
// Zeiger auf IHTMLWindow2 des Frames besorgen:
IHTMLWindow2 *pWindow = NULL;
if(SUCCEEDED(ret.pdispVal->QueryInterface(IID_IHTMLWindow2,
(LPVOID*)&pWindow)))
{
// Zeiger auf IHTMLDocument2 des Frames besorgen:
IHTMLDocument2 *pDoc = NULL;
if(SUCCEEDED(pWindow->get_document(&pDoc)))
{
// Frame in der Datei "Framenummer.html" speichern:
IPersistFile *PersistFile = NULL;
if(SUCCEEDED(pDoc->QueryInterface(IID_IPersistFile,
(LPVOID*)&PersistFile)))
{
PersistFile->Save(WideString(String(ExtractFilePath(ParamStr(0))+
IntToStr(ilFrameIndex+1) + slTmpFileExtension)), false);
PersistFile->Release();
}
pDoc->Release();
}
pWindow->Release();
}
}
}
pFrames->Release();
}
}
HTMLDocument->Release();
TStringList* pFileStrings = new TStringList;
if(pFileStrings)
{
// Die gepufferten Dateien mit dem HTML-Code der
// Seite in die RichEdit einlesen und die Dateien l?schen:
if(FileExists(ExtractFilePath(ParamStr(0))+"0"+slTmpFileExtension))
{
Form1->Memo1->Lines->LoadFromFile(ExtractFilePath(
ParamStr(0))+"0"+slTmpFileExtension);
DeleteFile(ExtractFilePath(ParamStr(0))+"0"+slTmpFileExtension);
}
if(ilFramesCount > 0)
{
for(LONG ilFrameIndex = 0; ilFrameIndex < ilFramesCount; ilFrameIndex++)
{
if(FileExists(ExtractFilePath(ParamStr(0))+IntToStr(
ilFrameIndex+1) + slTmpFileExtension))
{
pFileStrings->LoadFromFile(ExtractFilePath(ParamStr(0))+
IntToStr(ilFrameIndex+1) + slTmpFileExtension);
Form1->Memo1->Lines->Add("\n- - - Frame " +
IntToStr(ilFrameIndex+1) + " - - -");
Form1->Memo1->Lines->Add(pFileStrings->Text);
DeleteFile(ExtractFilePath(ParamStr(0))+IntToStr(
ilFrameIndex+1) + slTmpFileExtension);
}
}
}
delete pFileStrings;
}
}
else Form1->Memo1->Lines->Clear();
Проблема в следующем... Текст извлекаю из известного сайта vkontakte.ru. Предположим, захожу в поиск людей.. мне выводится несколько страниц, к примеру по 10 человек. Копирую текст для первых 10 - всё Ок. А вот если хочу скопировать текст для следущих 10 найденных, то копируется текст снова для первых 10 В код копирования страницы не вникал ибо не особо в этих приёмах разбираюсь, а если начну разбираться то уйдёт на это много времени...
Вопрос в следующем: можно как-нибудь подправить этот код или может, кто в работе с html страницами хоро�?о разбирается, предложит свой вариант для ре�?ения проблемы?
AnsiString GetAllTextFromWebPage(TCppWebBrowser *wb)
{
AnsiString s = wb->OleObject.OlePropertyGet("Document").OlePropertyGet("Body").OlePropertyGet("InnerText");
return s;
}
Сам на днях перерыл много инфы, ни чего толком не на�?ел, но при�?ел к такому изяществу, через COM-объект получае�?ь весь текст на странице
Если нужен HTML код странице, меняе�?ь только значение переменной, кажется так, пробуй:
AnsiString GetHTMLTextFromWebPage(TCppWebBrowser *wb)
{
AnsiString s = wb->OleObject.OlePropertyGet("Document").OlePropertyGet("Body").OlePropertyGet("InnerHtml");
return s;
}
Проблема в том, что в цикле браузер не успевает загрузить содержимое страницы и на этом этапе возникает о�?ибка доступа. Все ре�?иться если знать как дождаться определенного события = загрузки страницы, и только после этого запускать остальные фунциии цикла, стоит вопрос, как это сделать?
Проблема ре�?ается следущим образом, в теле цикла где происходит обработка страницы пи�?ем сразу после того как браузер получает адрес страницы CppWebBrowser->Navigate2(URL)
while (CppWebBrowser->ReadyState != 4)
{
Application->ProcessMessages();;
}
Похожая статья:
Особенности копирования текста страницы в CppWebBrowser на C++ Builder
Мой блог о программировании находят по следующим фразам