Поиск по блогу

четверг, 16 апреля 2009 г.

Особое внимание к кодам символов

Я уже писала о том, что изучать код страницы для парсинга надо очень внимательно. Приведу еще один пример из жизни.

Парсинг сайта с предложениями о работе. Заказчику парсера надо было, чтобы все "было визуально": загрузка страницы поиска, заполнение полей, сабмит формы. Что ж, без проблем.

Заполнила все поля, перехожу к выбору региона по названию из комбобокса (по value — не катит, надо по тексту). Картинка следующая:


На первый взгляд, все просто. Кажется, что можно значение текста в option-зе select-а обработать trim-ом, — и все будет хорошо. Итак, пишу процедурку выбора из селекта по тексту. На входе: текст итема, который надо выбрать и селект, в котором надо выбрать (поиск селекта осуществляется в другой процедуре, по нейму). На всякий случай еще привожу к верхнему регистру, чтобы уж наверняка.

procedure TMainF.SelectItemByTextFromSelectEl(TextStr: string;
SelectEl: IHTMLSelectElement);
var
i : integer;
iDisp : IDispatch;
iColl : IHTMLElementCollection;
iOption : IHTMLOptionElement;
sCity : string;
begin
iDisp := SelectEl.tags('OPTION');
iDisp.QueryInterface(IHTMLElementCollection, iColl);
if not Assigned(iColl) then
begin
ShowMessage('Not assigned!'); exit;
end;

i := 0;
while i <= iColl.length-1 do
begin
iDisp := iColl.item(i,0);
iDisp.QueryInterface(IHTMLOptionElement, iOption);
if Assigned(iOption) then
begin
sCity := AnsiUpperCase(trim(iOption.text));
if sCity = AnsiUpperCase(TextStr) then
begin
iOption.selected := true;
break;
end;
end;
inc(i);
end;
end;


Тестирую — не работает. Тестирую по шагам. Оказывается, что после trim-а строка не обрезается. Смотрим строку посимвольно: она в начале дополнена символами с кодом 160. Смотрим исходник trim-а: в нем обрезаются все символы с кодом до 32 включительно. В итоге — переписываем trim для себя:


function Trim2(const S: string): string;
var
I, L: Integer;
v : set of char;
begin
v:=[#0..#32];
include(v,#160);
L := Length(S);
I := 1;
while (I <= L) and (S[I] in v) do Inc(I);
if I > L then Result := '' else
begin
while S[L] in v do Dec(L);
Result := Copy(S, I, L - I + 1);
end;
end;


В итоге, если обнаружатся еще какие-нибудь символы, смахивающие на пробел и нуждающиеся в обрезке, — просто добавим их потом инклюдом в набор.

Чтобы быть в курсе обновлений блога, можно подписаться на RSS.

Статьи схожей тематики:



3 комментария:

  1. А зачем усложнять? Переписывать трим и т.д. Не проще было бы просто проверить вхождение одной строки в другую функцией pos() и тем самым проводить что-то наподобие нечеткого сравнения строк? Тем самым в проге можно было б организовать дополнительную фичу - выбор в SELECT'е наиболее подходящей строки, если точное соответствие не найдено.

    ОтветитьУдалить
  2. Да, конечно, можно и через pos. :) Но раз уж я начала сравнивать - то разобралась и доделала :) Просто бывает, что иногда сталкиваюсь с какими-то ситуациями, в которых "с налету" оказывается не все так просто, как кажется. А потом уже хочется во что бы то ни стало разобраться, что и почему. ) Статья была посвящена именно вниманию к символам, а пример приведен для наглядности :)

    Спасибо за комментарий) И за ссылки на мой блог - тоже огромное спасибо!

    ОтветитьУдалить
  3. Понятно. А ссылки - это мелочь :) Я Ваш блог ещё себе в RSS-трубу кинул, так что подписчиков должно немного поприбавиться

    ОтветитьУдалить

Комментарии модерируются, вопросы не по теме удаляются, троллинг тоже.

К сожалению, у меня нет столько свободного времени, чтобы отвечать на все частные вопросы, так что, может, свой вопрос лучше задать на каком-нибудь форуме?

Поделиться