Dimas216 |
Отправлено: 21.06.2006, 01:13 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 11
|
Появилась проблема с реализацией программы, которая находит ссылки в html документе и копирует их в отдельный текстовый документ. |
|
BreakPointMAN |
Отправлено: 21.06.2006, 02:12 |
|
Станционный диспетчер
Группа: Участник
Сообщений: 86
|
В чем конкретно проблема?
|
|
Aptem |
Отправлено: 21.06.2006, 05:36 |
|
Мастер участка
Группа: Участник
Сообщений: 349
|
Попробуйте функции Pos и SubStr класса AnsiString.
|
|
Valdemar |
Отправлено: 21.06.2006, 07:41 |
|
Мастер участка
Группа: Участник
Сообщений: 433
|
А еще можно воспользоваться регулярными выражениями. |
|
Dimas216 |
Отправлено: 21.06.2006, 12:59 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 11
|
Всем привет!Проблема в том что я никак нимогу догадаться как это реализовать.Т.е. чтобы она находила в тексте ссылку. |
|
Guest |
Отправлено: 21.06.2006, 13:38 |
|
Не зарегистрирован
|
Поручить анализ броузеру и пробежаться по коллекции Anchors'ов. Было на форуме. |
|
Dimas216 |
Отправлено: 21.06.2006, 13:51 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 11
|
Что то я непонял.У меня программа открывает html файл в html коде и внем должна находить ссылки и сохранять их в текстовом файле.Вот. |
|
__Cheat3r |
Отправлено: 21.06.2006, 15:11 |
|
Станционный диспетчер
Группа: Участник
Сообщений: 110
|
CODE |
//--------------------
String SubStringEx(String mStr, int Start,int End)
{
return mStr.SubString(Start,End-Start+1);
}
//--------------------
//--------------------
TStringList *lst = new TStringList,*links = new TStringList;
lst->LoadFromFile("html.html");
String txt=lst->Text;
while(int pos=txt.Pos("http://"))
{
txt = SubStringEx(txt, pos, txt.Length());
links->Add(SubStringEx(txt,1,txt.Pos("\""));
}
//в links — ссылки.
//-------------------- |
код на работоспособность не проверял.
Отредактировано __Cheat3r — 22/06/2006, 01:15 |
|
Dimas216 |
Отправлено: 21.06.2006, 15:23 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 11
|
Не работает.Куча ошибок. |
|
__Cheat3r |
Отправлено: 21.06.2006, 15:35 |
|
Станционный диспетчер
Группа: Участник
Сообщений: 110
|
Где ошибки!? |
|
Dimas216 |
Отправлено: 21.06.2006, 15:39 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 11
|
Undefined symbol 'mStr'
'_fastcall TForm1::FindBtnClick(TObject *)' cannot return a value
'lst' is assigned a value that is never used |
|
Dimas216 |
Отправлено: 21.06.2006, 15:44 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 11
|
CODE
[AnsiString text = RichEdit1->Lines->Text;
AnsiString subString = text.SubString( LastFind+1, text.Length() );]
Вот у меня тут написано начало а как дальше немогу понять.
|
|
__Cheat3r |
Отправлено: 21.06.2006, 15:48 |
|
Станционный диспетчер
Группа: Участник
Сообщений: 110
|
Ты вообще знаком с программированием?
Это вставь гденить в начале юнита
//--------------------
String SubStringEx(String mStr, int Start,int End)
{
return mStr.SubString(Start,End-Start+1);
}
//--------------------
а это повесь на какуюнибудь кнопку.
TStringList *lst = new TStringList,*links = new TStringList;
lst->LoadFromFile("html.html");
String txt=lst->Text;
delete lst;
while(int pos=txt.Pos("http://"))
{
txt = SubStringEx(txt, pos, txt.Length());
links->Add(SubStringEx(txt,1,txt.Pos("\""));
}
links->SaveToFile("Links.htm");
//в links — ссылки. |
|
Dimas216 |
Отправлено: 21.06.2006, 16:07 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 11
|
программа не находит в файле ссылки.В html коде начало ссылки начинается с href= а заканчивается . |
|
Guest |
Отправлено: 21.06.2006, 16:17 |
|
Не зарегистрирован
|
Бросьте заниматся самодельным анализом текста. WebBrowser зделает это за вас значительно лучше. А вам останется только собирать плоды.
Парсинг HTML в древовидную структуру
Извлечение из Интернет-страницы..., ...всех ссылок на другие сайты. |
|
Dimas216 |
Отправлено: 21.06.2006, 17:48 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 11
|
Нет, такое мне не нужно.Мне нужно чтобы это было с помощью вытаскивания из html кода. |
|
Valdemar |
Отправлено: 22.06.2006, 07:26 |
|
Мастер участка
Группа: Участник
Сообщений: 433
|
Ну если вам ничего не подошло, то еще раз советую воспользоваться регулярными выражениями. Здесь http://regexpstudio.com есть библиотека для работы с регулярными выражениями с описанием на русском языке. |
|
AVC |
Отправлено: 22.06.2006, 09:03 |
|
Ветеран
Группа: Модератор
Сообщений: 1583
|
QUOTE (Dimas216 @ 21/06/2006, 16:48) | Нет, такое мне не нужно.Мне нужно чтобы это было с помощью вытаскивания из html кода. |
Ну тогда, для начала, определите что такое ссылка. После этого станет понятно что искать.
Можно попробовать так:
ссылка это текст принадлежажий link'у не стоящему внутри закомментированного участка и расположенному после символов href (в любом сочетании регистров) за которыми может следовать любое число (в том числе и 0) и в любой комбинации символов пробел, табуляция и новая строка, затем знак равенства, затем снова sp,tab \n,
затем символ начала строкового литерала (которого может и не быть)
затем, наконец, сама ссылка либо до парного с началом открывающего символа либо при отсутствии оного до первого пробела. И все это при условии, что мы не выходим за пределы одного тэга.
После этого придется отсеивать ссылки переходов внутри документа (ну это, кажется, легко) и разбирать ссылки, представляющие собой код на js или bas (как это сделать мне пока не ясно).
Ну вот, в первом приближении, то что предстоит сделать.
Отредактировано AVC — 22/06/2006, 08:05 |
|
** Sl@Sh |
Отправлено: 23.06.2006, 06:23 |
|
Не зарегистрирован
|
Хотелось бы добавить, что в html допускается отступы между href, = и адресом. А еще нет гарантии что после href будет именно " или '. В html можно сразу адрес.
Так что вам наверное придется искать сперва href, потом =, а дальше запоминать для анализа строку от первого символа после = и до символа>.
В этой строке сперва поищите другие параметры тега (target например). Причем очевидно, что все эти варианты будут после href, значит действуйте так : нашли например target и удаляйте часть строки от начала target и до конца строки.
Конечно если у вас есть гарантия, что ссылка не содержит пробелов (а пробелы могут быть,смотря где вы html-файл применяете), то достаточно вырезать только текст от символа после = и до первого пробела.
P.S.: Я тут что-то намудрил. Извините если что неясно, сонный я |
|
AVC |
Отправлено: 23.06.2006, 08:42 |
|
Ветеран
Группа: Модератор
Сообщений: 1583
|
QUOTE (** Sl@Sh @ 23/06/2006, 05:23) | Хотелось бы добавить, что в html допускается отступы между href, = и адресом. А еще нет гарантии что после href будет именно " или '. В html можно сразу адрес.
Так что вам наверное придется искать сперва href, потом =, а дальше запоминать для анализа строку от первого символа после = и до символа>.
В этой строке сперва поищите другие параметры тега (target например). Причем очевидно, что все эти варианты будут после href, значит действуйте так : нашли например target и удаляйте часть строки от начала target и до конца строки.
Конечно если у вас есть гарантия, что ссылка не содержит пробелов (а пробелы могут быть,смотря где вы html-файл применяете), то достаточно вырезать только текст от символа после = и до первого пробела.
P.S.: Я тут что-то намудрил. Извините если что неясно, сонный я
|
Действительно сонный , прочтите внимательно мой пост.
Кроме того полагаться на порядок параметров в тэге ни в коем случае нельзя.
Кстати, кроме
a
base
area
link
form.action
где еще могут стоять явные ссылки ? |
|
Aptem |
Отправлено: 23.06.2006, 10:07 |
|
Мастер участка
Группа: Участник
Сообщений: 349
|
Я вообще не понимаю чо вы тут паритесь. Ну вот есть у вас html-код в строке. С помощью функции Pos находим первое вхождение . Вот вам и все, теперь уже в этой строке находим href и выдергиваем ссылку. Пробелы на концах строки можно обработать Trim'ом.
Тут конечно упоминалось обо всяких регулярных выражениях и т.д., это конечно же быстрее и удобнее, но я люблю сам во всем разобраться и понять как это работает. По-моему все тут прозрачно.
Писать кому то за вас совсем не интересно, попробуйте разобраться сами!
Про функции Pos и SubStr можно почитать в обычной помощи C++ Builder.
Удачи!
Отредактировано Aptem — 23/06/2006, 10:09
|
|
AVC |
Отправлено: 23.06.2006, 13:43 |
|
Ветеран
Группа: Модератор
Сообщений: 1583
|
Вот набросал примерчик, правда для его функционирования требуется мой PageProduser (прилагается, офомлен как визуальный компонент, но можно использовать и просто как lib)
Собственно сам пример
CODE |
//---------------------------------------------------------------------------
void __fastcall TF_SeekLinks::Bt_SeekClick(TObject *Sender)
{
Memo1->Lines->LoadFromFile("F:\Temp\b.htm");
AnsiString text = Memo1->Text;
// Оказалось, что мой Producer плохо анализирует текст с разрывами между именем, = и значением
// в теге они должны стоять без разрывов (типа href=значение)
// ну и попутно выкину комментарии, так как Producer писался не для этого
char *buf = new char[text.Length()+1];
char *bp = buf;
bool incmnt = false;
int i = 0;
for (char *cp=text.c_str(); *cp; cp++, i++)
{ if (*cp < ' ') continue;
if (i > 3)
{ if (*(cp-0) == '-' && *(cp-1) == '-' && (*cp-2) == '<') { incmnt = true; bp-=2; } // <--
else if (*(cp-0) == '>' && *(cp-1) == '-' && (*cp-2) == '-') { incmnt = false; bp-=2; } // -->
}
if (incmnt) break;
*bp++ = *cp;
}
*bp = 0x00;
AnsiString htmltext(buf);
delete [] buf;
Memo1->Text = htmltext;
TAxPageProducer *pgprod = new TAxPageProducer(this);
try {
Aborted = false;
pgprod->AxTagBeg = "<";
pgprod->AxTagEnd = ">";
pgprod->OnAxTag = PgProd_Tag;
Memo1->Lines->Add(AnsiString::StringOfChar('=', 40));
pgprod->Execute(htmltext);
Memo1->Lines->Add(AnsiString::StringOfChar('=', 40));
}
__finally { delete pgprod; pgprod = NULL; }
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
void __fastcall TF_SeekLinks::PgProd_Tag (TObject *Sender
,const AnsiString &TagName
,TStrings *TagParams
,AnsiString &RetText
,int &RetState
)
{
if (Aborted)
{ RetText = "";
RetState = trsABORT;
return;
}
AnsiString text = "";
AnsiString tagname = TagName.UpperCase();
RetState = trsNONE;
try { // проанализировать только нужные тэги
if (tagname == "ABORT" ) { RetState = trsABORT; Aborted = true; }
else if (tagname == "A" ) Memo1->Lines->Add(tagname + ": [" + GetLink(TagParams) + "]");
else if (tagname == "LINK" ) Memo1->Lines->Add(tagname + ": [" + GetLink(TagParams) + "]");
else if (tagname == "AREA" ) Memo1->Lines->Add(tagname + ": [" + GetLink(TagParams) + "]");
else if (tagname == "BASE" ) Memo1->Lines->Add(tagname + ": [" + GetLink(TagParams) + "]");
else if (tagname == "FORM" ) Memo1->Lines->Add(tagname + ": [" + GetLink(TagParams, "action") + "]");
else if (tagname == "FRAME" ) Memo1->Lines->Add(tagname + ": [" + GetLink(TagParams, "src" ) + "]");
} // try
catch (Exception &xcp)
{ text = "Exception: " + xcp.Message;
RetState = trsNONE;
}
RetText = text;
}
//---------------------------------------------------------------------------
// Найти href в параметрах тэга
//---------------------------------------------------------------------------
AnsiString __fastcall TF_SeekLinks::GetLink (TStrings *params
,const AnsiString& pPName
)
{
AnsiString pname = pPName.UpperCase();
AnsiString name;
AnsiString value = "";
int idx;
char c1, c2;
for (int i=0; i < params->Count; i++)
{ name = params->Names[i].UpperCase();
if (name != pname) continue;
value = params->Strings[i];
idx = value.Pos("=");
if (idx > 0) value = value.SubString(idx+1,100);
else value = "";
}
return value;
}
//---------------------------------------------------------------------------
|
Пример работы
CODE |
Вход
<html>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=windows-1251'>
<link rel='stylesheet' href='file:///E:/Aster/php/afish/style1.css' type='text/css'>
</head>
<body>
<form name='frm_afish' method='post' action='http://localhost/afish/afish.php?cmd=main1'>
<map name="aaa">
<--<area alt="asdfg" shape="poly" coords="1,45,120,118,158,161,1,165" href="qwer">
--><area alt="123" shape="circle" coords="119,57,51" href="zxcv">
</map>
<img src="E:\HHC\Images\Troll3.gif" width="211" height="166" border="0" usemap="#aaa">
<select name='afish_city'
onChange='javascript: afish_mall.value = 1; submit(); return false;'
>
<option value='12' >Актау</option>
<option value='278' >Актюбинск</option>
</select>
<a href='#' onClick='javascript: afish_mall.value = 1; submit(); return false;'>Все</a>
<input type=hidden name='afish_mall' id='afish_mall' value='0'>
</form>
<hr>
<a class='odtmnu' href='?cmd=main1'>Афиша, 1-й вариант</a>
<a class='odtmnu' href=?cmd=debugshow name=iii>Массивы</a>
<a class='odtmnu'
href
=
'?cmd=anysql'
>SQL</a>
</body></html>
Выход
LINK: [file:///E:/Aster/php/afish/style1.css]
FORM: [http://localhost/afish/afish.php?cmd=main1]
AREA: [zxcv]
A: [#]
A: [?cmd=main1]
A: [?cmd=debugshow]
A: [?cmd=anysql]
|
|
|
Dimas216 |
Отправлено: 23.06.2006, 15:26 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 11
|
А как подключить AxPgProd к программе? |
|
Guest |
Отправлено: 23.06.2006, 17:19 |
|
Не зарегистрирован
|
добавить строку #include "AxPgProd.h"
Установить как пакет: Component->Install Pakages
или
подключить как lib: #pragma link AxPgProd.lib
PS. Это для 5-й стройки. Если вас не 5-я в понедельник вышлю исходники (куда ?). |
|
Dimas216 |
Отправлено: 23.06.2006, 18:09 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 11
|
Dimas216@mail.ru |
|
** Sl@Sh |
Отправлено: 25.06.2006, 06:45 |
|
Не зарегистрирован
|
QUOTE (AVC @ 23/06/2006, 08:42) | Кроме того полагаться на порядок параметров в тэге ни в коем случае нельзя. |
Я и не полагаюсь. Ведь я предложил только находить например href, а после него (содержимого) ожидать либо еще тег, либо> |
|
Dimas216 |
Отправлено: 26.06.2006, 19:56 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 11
|
Есть кто — нибудь кто может выслать исходники этой программы? |
|
AVC |
Отправлено: 27.06.2006, 11:46 |
|
Ветеран
Группа: Модератор
Сообщений: 1583
|
Высылаю. |
|