пятница, 11 декабря 2009 г.

Фотографии от Panoramio на своем сайте

Случайно наткнулся на cайт компании Panoramio. Разработчики этого сайта создали сервис привязывания фотографий к географическим координатам. Т.е. сделал прекрасный снимок, зашел к ним на сайт и опубликовал его, не забыв привязать к географическим координатам. Так же есть API, которое позволяет получать информацию о фотографиях, относящихся к географическим объектам, находящимися в заданном квадрате.
Сейчас я работаю над вторым сайтом созданным для самостоятельного бронирвоания путешествий - БукТрип.ру. Для предоставления возможности бронирования отелей собрал достаточно большую базу географических названий. Но вот для взаимодействия с API от Panoramio нужны координаты этих объектов. И эти координаты можно получить, воспользовавшись сервисом Google Geocoding. Чтобы определить координаты, надо сделать запрос к сайту maps.google.com следующего вида:
http://maps.google.com/maps/geo?q=Paris,fr&output=csv&key=ABQIAAAALkH7z-
7Yg6rN5Wgtte6WQxRhFePxzidMXG8dHw849BemzMV9YxRakAkV291BmrgJ5R_LgrNfgigIOQ

где q — адрес искомого объекта, output — формат ответа, key — ключ для работы с Google Maps, который можно получить на сайте регистрации ключа к API Карт Google. Ответом на запрос в примере будет строка
200,4,48.8566667,2.3509871
200 — код ответа (200 — успешно, 403, 602 и прочие — нет), 4 — точность определения (страна, город, улица, дом и т.п.), 48.8566667,2.3509871 — искомые широта и долгота.
Получив координаты объекта остается определить только «диаметр» зоны, фотографии объектов в которой и будут показываться. Для получения крайних точек можно просто вычесть и прибавить к координатам центра какие-то константы. Но Земля-то круглая, и точка, находящаяся на расстоянии 10 км от заданной должна вычисляться по более сложной формуле, которую я и нашёл.
Получив от Panoramio список фотографий, путем несложных манипуляций с данными, я их вывел в виде слайд-шоу (скрипт для создания слайд-шоу можно посмотреть на http://www.phatfusion.net/slideshow/).

пятница, 27 ноября 2009 г.

Аналитические функции в MySQL

Всем хорош язык MySQL, но вот в некоторых случаях надо делать запросы, которые, благодаря наличию аналитических функций, в Oracle делаются весьма просто.
Рассмотрим на примере. Скажем, есть у нас 2 таблицы: товары с полями goods_id — идентификатор, grp — группа, name — наименование, и обобщенная таблица с продажами sales с полями goods_id — идентификатор товара, period — период, summa — суммарная стоимость проданных товаров за указанный период.
И вот требуется вывести по 10 самых продаваемых товаров из каждой группы за заданный период. В Oracle запрос бы выглядел вот так:

SELECT grp, name, summa
FROM (
SELECT g.grp
,g.name
,s.summa
,row_number()
OVER (PARTITION BY g.group
ORDER BY s.summa) as rn
FROM goods g
,sales s
WHERE g.goods_id = s.sales_id
AND s.period = 2009101
)
WHERE rn <= 10
ORDER BY grp, name
А в MySQL вот так:

SET @rows_count = 0;
SET @grp = NULL;
SELECT grp, name, summa
FROM (
SELECT g.grp
,g.name
,s.summa
,CASE WHEN IFNULL(@grp, '#') != grp THEN
@rows_count := 0
END q1
,CASE WHEN IFNULL(@grp, '#') != grp THEN
@tp := tp
END q2
,@rows_count := IFNULL(@rows_count, 0) + 1 as rn
FROM goods g
,sales s
WHERE g.goods_id = s.sales_id
AND s.period = 2009101
)
WHERE rn <= 10
ORDER BY grp, name

среда, 22 апреля 2009 г.

1000 меньше чем за 3

Я уже писал я 300 уникальных посетителях в сутки по самому консервативному счетчику LiveInternet. Вчера уникальных посетителей было 1031.

Еще в начале апреля количество посетителей подбиралась к 1000 (6 апреля - 977, 7-го - 971), но "рубеж" был взят только вчера, хотя я надеялся, что это произойдет немного раньше. Но, почему-то, количество посетителей с 8-го апреля начало падать, сначала не очень быстро, потом падение ускорилось. Я это связываю с изменением алгоритмов выдачи Yandex'а, сайта, который "поставляет" большую часть посетителей. Самое дно было достигнуто в эту субботу 18 апреля - 502 посетителя, а в воскресенье начался стремительный рост.

Я уже получил больше 10 статей с момента опубликования формы для ввода новых отзывов, причем 5 из них от постоянного автора, который, точнее которая, помимо интересных текстов публикует изумительные фотографии.

Так же не обошлось без неинтересных статей рекламного характера, которые я публиковать не стал. Хотя ничего не имею против рекламы, которая должна органично включаться в статью, т.е. статья должна быть именно статьей, а не рекламным объявлением. И если автор пишет, что ему понравился отель, или экскурсия, и оставляет координаты экскурсовода, то я оставляю эту информацию, т.к. она может быть полезной для моих читателей, для которых, собственно, все и создавалось.

В общем, "рубеж" в 1000 посетителей достигнут менее чем за 3 месяца. Для привлечения большей аудитории надо добавлять новые разделы, например, новости или что-то в этом роде. Может быть у кого-нибудь будут интересные предложения, которые я смогу реализовать?

пятница, 10 апреля 2009 г.

Ajax как способ показа информации из БД на статических html-страницах

Страницы моего сайта - статический html, который создается на основе информации, хранящейся в БД на моем компьютере. Затем специальными скриптами я делаю html-страницы и выкладываю их на сервере. При таком способе нельзя оперативно показывать комментарии, которые посетители оставляют, после ознакомления со статьями.

Для отображения комментариев к статьям я решил воспользоваться технологией Ajax. А именно, в каждом html-документе создать div, и javascript-программой выводить в этом div'е комментарии, которые хранятся в БД на сервере, где и находится сайт.

Сначала я ознакомился с документацией по Ajax, сделал простейший скрипт, который работал только в IE, а ведь есть еще Opera, Firefox и т.д. И у всех браузеров свои особенности. Конечно, можно покопаться в интернете, изучить варианты для всех браузеров, установить у себя каждый из браузеров для отладки и т.д. Но мне нужно всего лишь добавить возможность отображения комментариев, а не изучать особенности интерпретации javascript браузерами!

Решение было найдено случайно, на каком-то из форумов кто-то писал про JsHttpRequest-библиотеку. Библиотека - это громко сказано, но решение, действительно стоящее.
Итак, что же из себя представляет JsHttpRequest - это 2 файла JsHttpRequest.js и JsHttpRequest.php, соответственно первый включаем в каждый html-документ, второй - в скрипт, который на сервере обрабатывает запросы.

Покажу на примере, как несложно пользоваться этим. Есть форма, состоящая из 2-х полей, при нажатии на Submit надо показать сумму значений в этих полях.

В text.html:
<html>
<script src="JsHttpRequest.js"></script>
<script type="text/javascript">
function cmnt(frm)
{
JsHttpRequest.query('/test.php',
{
'a1': document.getElementById('a1').value,
'a2': document.getElementById('a2').value,
},
function(result, errors)
{
if(result)
{
str = result["str"];
alert('Сумма: ' + str);
}
else
{
alert('Не удалось получить данные: ' + errors);
}
}
,false // do not disable caching
);
return true;
}
</script>
<form>
<input name="a1" id="a1" value="" type="text">
<input name="a2" id="a2" value="" type="text">
<input value="Отправить" type="button" onclick="cmnt();">
</form>
</html>

И test.php:
<?php
require_once "JsHttpRequest.php";
$JsHttpRequest =& new JsHttpRequest("windows-1251");

if($_REQUEST[a1] && $_REQUEST[a2])
{
$GLOBALS['_RESULT'] = array(
"str" => $_REQUEST[a1] + $_REQUEST[a2]
);
}
?>

Разумеется, с сервера получать сколь угодно много параметров, просто добавьте их в массив $GLOBALS['_RESULT'] в php-файле и обработку этих параметров в javascript.

воскресенье, 5 апреля 2009 г.

Добавление RSS

Для ускорения индексации сайта поисковиками мне порекомендовали добавить rss.
Для начала я попробовал воспользоваться библиотеками perl, предназначенными для этого. Но ни XML::Atom::SimpleFeed ни XML::RSS стабильно работать не желали. Да и инталляция через cpan для camelbox perl не проходила. Пришлось исходные тексты библиотек просто переписывать в директорию site/lib.
И тогда я решил написать все сам, знал бы насколько это окажется быстрее, по сравнению с возней с указанными выше библиотеками, вообще бы с теми библиотеками не связывался.
Ознакомившись со статьей "Как сделать RSS ленту за пять минут", я действительно за 5 минут сделал rss-ленту.
Осталась сущая малость - преобразовать текущую дату в нужный формат. Т.е. в формат Tue, 31 Mar 2009 23:29:48 +0300. Сделать стандартными средствами в Windows это не получается. В Unix-е без проблем, а в Windows - нельзя. Даже гуру из xpoint.ru не смогли помочь мне в этом. Решение пришлось находить самому, а именно, в запрос на получение данных из MySQL я добавил еще одно поле date_format(now(), "%a, %d %b %Y %H:%i:%S") dt_cur.
Теперь поисковые боты могут пользоваться моей rss-лентой.

вторник, 17 марта 2009 г.

300 за 1.5

Вчера впервые счетчик liveinternet перешел за отметку 300, точнее было 302 уникальных посетителя, вычтем из них 2 своих посещения из дома и с работы, как раз получится 300. Вообще-то я планировал выйти на такое количество «уников» за 3 месяца, получилось за 1.5. Причем, среднее количество просмотров на посетителя больше 3-х, т.е. сайт заслуживает внимания. Самой большой популярностью пользуются статьи с отзывами о путешествиях по России, следом с полуторным отставанием идут Греция, потом с заметным отставанием Египет, Испания, Турция.

Что нужно делать для раскрутки сайта лучше прочесть на специализированных блогах. От себя только добавлю, что title и description для страниц за эти 1.5 месяца я менял 2 раза. Т.е. уже стоит 3-й вариант, на мой взгляд самый удачный. Хотя поисковики еще и показывают страницы со 2-м вариантом, который больше похож на набор ключевых слов, а не на осмысленный текст.

Все никак не отважусь «открыть» для посетителей страницу для добавления своих отзывов, хотя сам ею пользуюсь больше 2-х недель. Не знаю как лучше на нее сделать ссылки внутри сайта. Может кто-нибудь подкинет идею?

понедельник, 2 марта 2009 г.

Антиспам-фильтр для русских людей

Наткнулся на забавную историю, которой спешу поделиться.
Включил антиспам-бота, написал в качестве вопроса следующее:
«Вас приветствует Анти-спам бот! Меня люто и бешено затрахали предложения увеличить член, купить айфон за 50 рублей, посмотреть „клёвые фотки студенток“ и многие другие, исходящие от спам-роботов. Докажи, что ты живой РУССКИЙ человек. Ответь на простой вопрос: Сколько будет десять раз по сто грамм? (буквами ответ пиши)»

Вот ты бы что ответила? А ко мне человек пробиться не мог, аж позвонил, он долго, в разных вариациях со всеми возможными ошибками писал в ответ «килограмм».

Смех-смехом, а идея-то интересная. Не думаю, что бот сможет сообразить что надо написать «литр» :)

среда, 25 февраля 2009 г.

Про perl, или применение на работе полученных знаний в процессе разработки сайта

На работе возникла задача - "вытащить" запросом из базы информацию о сотрудниках нашей организации. Причем вытащить из системы, разработанной подрядчиками, правда по системе есть документация. Нашел в документации обзор который показывает нужную информацию, выполнил запрос, посмотрел что получилось. Оказалось, что запрос показывал не все записи, но вот как понять, по каким полям фильтрует данные подрядчик, в документации этого нет, на "рытье" в исходниках времени нет. Попробовал открыть на портале страницу, возвращающую все доступные записи в виде таблицы. Скопировал эту таблицу в буфер обмена, отрыл Excel, нажал Paste и ... Процессор ушел в 100% загрузку, Excel минут 10 пытался вставить информацию из буфера обмена, но безрезультатно. Мне надоела ждать, "срубил" Excel. Открыл исходник страницы с этой таблицей, вырезал из него только таблицу, попробовал открыть получившийся документ в Word'е. Результат аналогичный Excel'ю. Вот незадача, но надо же понять почему на портале отображается на 10 записей больше чем в запросе. Перебирать все 1500 фамилий сотрудников в поисках несовпадений глазами весьма затруднительно. Как же выбрать из портальной страницы только фамилии, чтобы их сопоставить с найденными запросом.
Задача была решена меньше чем за 5 минут. Я написал маленький скрипт на perl, который "вырезал" из html-ой таблицы фамилии сотрудников. Еще через 5 минут, после использования функции ВПР в Excel я нашел недостающие в запросе фамилии и понял, что всего-то надо было поставить NVL(value, 0) на одно из фильтруемых полей.
Кстати, perl-овый обрабатывал html-ную таблицу размером примерно 3.5 мегабайта около 3-х секунд. Word и Excel отдыхают. Вот этот код:
require HTML::TokeParser;
my $p = HTML::TokeParser->new('c:\qqq.html');
while (my $token = $p->get_tag("a"))
{
print $p->get_trimmed_text . "\n"
if($token -> [1] -> {onclick} eq 'showEmployee(); return false;');
}
Небольшой оффтопик. Случайно набрел на блог праздного небогача, в котором наткнулся на превосходную идею тиражирования блога. Скоро появятся http://nobyru.blog.ru, http://nobyru.ya.ru, http://nobyru.livejournal.com. Ссылки на сайт Отзывы о путешествиях никогда не будут лишними.

вторник, 17 февраля 2009 г.

Склонение русских слов

Посещаемость моего сайта пока не высока. Не более 100 человек в день. Просматривая статистику посещения наткнулся на рекламу организации, предлагающей услуги по продвижению сайта. Эти услуги я пока не готов заказывать, но полезную информацию о раскрутке сайта я нашел.
Для автоматической генерации ключевых слов, по которым пользователи производят поиск информации, требовалось проспрягать названия стран и курортов. Найти подходящие классы или пакеты для perl или php не удалось. Но зато один опытный программист прислал ссылку на Russian ispell. Скачав оттуда последнюю версию словарей, обнаружил файл с географическими названиями (жаль, что не со всеми, имеющимися в моем каталоге) и правила для склонения слов. Через несколько часов я смог автоматически проскланять большинство стран и курортов, жаль что не все.
Большое спасибо Александру Лебедеву за предоставленный специальным образом закодированный орфографический словарь русского языка. Кстати, в общем словаре примерно 130 тысяч русских слов, и, теперь, у меня есть код, которых может их склонять.

вторник, 10 февраля 2009 г.

Добавление на поисковые сервера и в каталоги

Сайт готов. По крайней мере информацию можно смотреть. Возможность вносить статьи постараюсь сделать в ближайшее время.
Надо сообщить о своем существовании. Самым первым сообщением была первая публикация на этом блоге. Но блог-то мало кто пока читает.
Добавить о себе информацию я решил в гулг и в яндекс. Да, есть еще русскоязычные поисковики, но эти самые распространенные.
Прочел на гугле о рекомендации для вебмастеров, создал у себя страницу 404, т.е. страницу, которая отображается, когда запрашиваемая пользователем страница не найдена. Затем добавил свой сайт в список сайтов, создал файл для ботов - robots.txt, а так же файл sitemap.xml, точнее sitemap.xml.gz. Кстати, генерация и сжатие этого файла у меня занимает всего 1.11 секунды, причем в файл добавляется 9065 ссылки на страницы со статьями, индексные файлы я решил не включать. Эти файлы постоянно меняются, да и служат только для показа ссылок на статьи.
Затем проделал аналогичную регистрацию на яндексе. Интересно, что на в описании не сказано, что можно указывать заархивированые файлы sitemap.xml.gz, но яндекс их легко понимает и разбирает. Правда, гугл намного оперативнее яндекса обрабатывает файлы sitemap.
На следующий день гугл в поиске выводил 2 мои страницы, причем те, на которые были ссылки в этом блоге, яндекс молчал. Через неделю гугл показывал 10 страниц, а яндекс почти все!!! Ура. Я появился в поисковых системах.
Правда узнал об этом с 3-х дневным опозданием, мой провайдер трое суток не мог устранить проблему, из-за которой несколько домов нашего района остались без интернета.
И у меня начали появляться посетители. В воскресенье 37 уникальных сайтов, в понедельник уже 52! Интересно, когда их количество добежит до сотни. Надеюсь к концу февраля.
Один из приятелей посетовал, что нет возможности поиска внутри сайта. Свой поиск в силу ограничений, описанных в предыдущих статьях, я сделать не могу. Значит надо воспользоваться решениями, предоставляемыми профессионалами. Поиск от гугл делается за несколько минут. Получаемый код встраивается в готовую страницу и сразу же начинает работать. Но только одна проблема, гугл пока что показывает на этой странице поиска всего 18 страниц, т.е. менее 0.2%. Поиск от яндекс сделать не сложно, только вот результаты поиска не совсем меня устроили. Во-первых, окно с результатами открывается уже на сайте яндекса, а во-вторых, если результат на сайте не найден, то выдается информация с других сайтов, что тоже не привлекает. По-этому буду ждать когда же гугл захочет показать в своем поисковике большинство моих страниц, потому что проиндексировал он их очень давно. Причем, первая индексация была сразу после публикации первой статьи на блоге. Жаль, что я не знал о такой его прыти, потому что при первой индексации было обнаружено больше 1000 ошибочных ссылок. Ну да, я же при отладке делал только первые 20 страниц, а не все 10900 (статьи + индесные файлы).

понедельник, 2 февраля 2009 г.

Оптимизация запроса в MySQL

У сервера, любезно предоставленного мне для размещения сайта, были довольно средние характеристики. Поэтому было решено все страницы, за исключением feedback, делать статическими. Для генерации страниц был разработан скрипт на perl. После отладки скрипта оказалось, что на генерацию 24 отзывов вместе с индексными файлами уходит примерно 120 секунд. На мой взгляд, непростительно много. После анализа времени функцией, которое тратится на производство одной страницы, выяснилось, что построение ссылок на страны, курорты, отели, относящиеся к опубликованному отзыву занимает больше всего времени.
Но почему? Вот запрос, получающий эту информацию:
SELECT MIN(p.name) name, count(*) cnt, p.id
FROM props p
,article_props ap
,articles a
WHERE p.up_id = 171
AND p.tp = 'P'
AND p.id = ap.prop_id
AND ap.art_id = a.id
AND a.is_can_show = 'Y'
GROUP BY p.id
Для таблицы props (в дальнейшем p) есть индекс по полям up_id и tp, для таблицы article_props (в дальнейшем ap) — индекс по полю prop_id, ну а у таблицы articles (a) — первичный ключ по id. Но запрос сначала шел по таблице a (по индексу по полю is_can_show), затем по ap и по p. В таблице ap записей примерно в 5 раз меньше, чем в p, может быть по-этому анализатор выбирал сначала эту таблицу.
Знаток MySQL рекомендовал мне:
  1. переписываем с оракловского синтаксиса на общечеловеческий, расставляя таблицы в желаемом порядке
    SELECT MIN(p.name) name, count(*) cnt, p.id
    FROM props p
    INNER JOIN article_props ap ON p.id = ap.prop_id
    INNER JOIN articles a ON (ap.art_id = a.id AND a.is_can_show = 'Y')
    WHERE p.up_id = 171
    AND p.tp = 'P'
    GROUP BY p.id
  2. Применить хинт
    SELECT /*+ORDERED*/ ...
  3. А лучше переделать все на LEFT JOIN
    SELECT /*+ORDERED*/
    MIN(p.name) name, count(*) cnt, p.id
    FROM props p
    LEFT JOIN article_props ap ON p.id = ap.prop_id
    LEFT JOIN articles a ON (ap.art_id = a.id AND a.is_can_show = 'Y')
    WHERE p.up_id = 171
    AND p.tp = 'P'
    AND a.id IS NOT NULL
    GROUP BY p.id
И добавил: «вообще я INNER JOIN стараюсь не применять вообще никогда.
Потому что LEFT JOIN как раз диктует порядок построения запроса и не даёт оптимизатору умничать. ВСЕГДА ставьте LEFT JOIN. Почувствуйте себя хозяином положения».
И действительно, после этих манипуляций запрос «пошёл» по нужным индексам, и стал отрабатывать за 0.6 секунды, вместо 9.6.
Я создал все страницы, на что ушло около 15 минут, начал проверять что получилось, и заметил, что запрос-то ошибочный. При его выполнении выдаются все записи из таблицы p, даже те, для которых нет ссылок в ap. При замене первого LEFT JOIN article_props ap ON p.id = ap.prop_id на INNER JOIN и эта проблема была решена. Но все же, использование LEFT JOIN меня сильно коробило. Не красиво это.
И элегантное решение было найдено. Оказывается, в MySQL есть возможность указания индексов в хинтах. В результате запрос стал
SELECT MIN(p.name) name, count(*) cnt, p.id
FROM props p,
article_props ap,
articles a IGNORE INDEX(art_is_can_show_i)
WHERE p.up_id = 171
AND p.tp = 'P'
AND p.id = ap.prop_id
AND ap.art_id = a.id
AND a.is_can_show = 'Y'
GROUP BY p.id
24 отзыва вместе с индексными файлами созданы менее чем за 12 секунд (сравните со 120 секундами до оптимизации).

четверг, 29 января 2009 г.

Выбор шаблона для сайта

Информации я набрал, данные привел в порядок, настало время самой творческой, по крайней мере, для меня, работы — рисовании сайта. Оказалось, что в интернет много ресурсов с бесплатными шаблонами сайтов. Мне посоветовали www.oswd.org. Просмотрев более 200 различных вариантов, я выбрал около 20 и отправил ссылки на них своей жене. На мой взгляд, лучше девушки никто не определит дизайн, а за мной останется самая малость — воплотить выбранный дизайн в жизнь. Жене больше всего приглянулся MultiFlex-2. Действительно, баннер с пальмами и морем у кого угодно ассоциируется с отдыхом. Но как-то не трогала меня эта картинка. Прошлым летом мы отдыхали в Черногории в деревушке Прчань, расположенной в Которском заливе. Замечательное место, великолепная погода, теплое море, простая и вкусная еда, а самое главное — потрясающие виды. Один из них на моем рабочем столе, бывает, что все сильно достанет, так свернешь все окна, посмотришь на картинку, и дальше за дело.
Почему бы не сделать из этой картинки основной баннер. Склеил из 4-х фотографий одну панорамную, обрезал крыши домов и побережье снизу, облака и небо сверху получил основное — море и горы. Глядя на баннер слоган сайта родился сам собой — «Побывал — поделись впечатлениями».
Бесплатный шаблон был для разрешения 800×600. Попробовав сгенерить на нем начальные страницы увидел, что почти половина экрана пустая, и, из-за маленькой ширины страницы очень длинные по вертикали. К сожалению, у автора шаблона не оказалось версии для большего разрешения. Но ничего, немного покопавшись с css-файлом, я сделал это самостоятельно. По-моему, получилось неплохо!

среда, 28 января 2009 г.

Связывание информации из разных сайтов

Как сделать так, чтобы мой сайт стал лучше, чем тот, с которого я забирал первоначальную информацию? Скачивать информацию еще с одного сайта. Тогда у меня будет информации больше, глядишь, и пользователям будет интереснее у меня, т. к. теперь не надо посещать 2 сайта, а все есть на одном.
Я даже не предполагал, насколько много в интернете ресурсов с отзывами. Причем большинство из них на низах рейтинга. Выбрав новую «жертву», я довольно быстро подготовил скрипты для «выкачивания» информации из нее (всего несколько часов, по сравнению с днями, потраченными на первый источник, правда и опыт у меня уже был), запустил, выкачал. И началось самое геморройное... Надо как-то связать классификаторы статей из первого источника с классификаторами статей из второго источника, чтобы на моем сайте статьи про одинаковые места отдыха, полученные из разных источников, «лежали» в одном разделе. Т. е. курорт Варадеро на острове Куба с первого сайта, это тот же курорт Варадеро с острова Куба со второго сайта. А что делать, если на одном сайте Куба пишется «Куба», а на втором — «Cuba»? И какая Куба правильнее? В общем, надо создавать свой справочник курортов, содержащий как можно больше информации по странам, курортам, отелям, и привязывать к нему все ссылки на эти страны-курорты-отели. Опять же, откуда взять все это, чтобы информации было много, и чтобы она более менее была нормально упорядочена. Потому что меня не устраивает ссылка на Вьетнам — Вся страна — Отель супер-пупер, а надо Вьетнамкурорт — отель.
Побродив по интернету, нашел 3-й сайт, на котором больше есть информация о 35 тысячах отелей, причем отели упорядочены именно по странам и городам. Закачал. К сожалению, в этих 35 тысячах не обошлось без задвоений как городов, так и отелей. Но сильно на эту тему я заморачиваться не стал. Будут статьи, ссылающиеся на эти города-отели — вычищу.
Из информации, полученной с 3-го сайта, сделал «идеальный» справочник. К которому попробовал привязать классификаторы из первых двух сайтов. Примерно 70% информации удалось связать запросами к базе данных, для оставшихся 30% сделал форму и вручную прокрыжил. Долго, конечно, но что делать. Не хочется, чтобы у меня был мусор.
Заодно обратил внимание, что для многих статей есть ссылка только на страну, без привязки к городам и отелям. Непорядок. Несложным INSERT'ом попробовал исправить эту несправедливость, т. е. если статья ссылается только на страну Великобритания, а в тексте встречается слово Лондон, то надо добавить еще и ссылку на Лондон, чтобы пользователь не просматривал все статьи о Великобритании, когда ему интересны впечатления только о Лондона. И натолкнулся на особенность MySQL, в Oracle такого рода ошибки не было. Оказывается, если в MySQL запрос
SELECT instr('Москва — столица нашей Родины', 'МОСКВА')
выдает 1, а в Oracle — 0. Но «МОСКВА» и «Москва» — это ведь 2 разных слова, по крайней мере по написанию, а MySQL оптимизирован для поиска без учета case sensitive. Но проблема, как оказалось, решается просто. Если в запросе
SELECT 1
FROM articles a, cities c
WHERE a.text LIKE CONCAT('%', c.name, '%')
после LIKE поставить BINARY, то все ищется отлично. Таким образом, мне удалось не наделать лишних ссылок из статей на города, которые в этих статьях не упоминаются.

вторник, 27 января 2009 г.

Как все начиналось

Идея создания сайта с отзывами обо всем возникла еще в мае, я даже удосужился сделать первую страницу содержащую слова, о том, как круто здесь все когда-то будет. Но дальше первой страницы дело не пошло...
А осенью начался кризис. Хотя с работы пока что не гонят, но вылететь можно в любой момент, никто же не может гарантировать тебе рабочее место вечно. Поэтому, надо искать какие-нибудь дополнительные источники заработка. Мой друг предложил поискать подработку на сайте http://www.rentacoder.com. Я зарегистрировался и обнаружил, что по спрос на кодеров, которые работают только с БД Oracle не очень-то и велик. Зато работы с php, perl и MySQL хватает. Осталась самая малость — более-менее освоить эти средства. Предварительный опыт был только с php.
Читая умные книжки и выполняя примеры из них, не сильно продвинешься в изучении новых средств разработки. На реальной задаче новый материал усваивается гораздо лучше. Тут-то сайт с отзывами и пережил свое второе рождение.
Сайт, конечно, дело хорошее. Но на нем должна быть какая-то информация. Причем информация должна быть полезной, чтобы кому-то было это интересно. А пока народ «прочухает», что надо именно на моем сайте оставлять отзывы пройдет не один месяц. Если у меня информации нет, а у кого-то другого она есть, надо ее позаимствовать. Заодно, научусь как на perl’е «качать» страницы и разбирать информацию в них содержащуюся.
Первой жертвой для заимствований выбрал большой туристический портал, на котором было полно информации. Не меньше недели ушло на то, чтобы научится нормально «забирать и разбирать» с него страницы.
Следующим шагом стала загрузка информации в базу данных. Т.к. на сайте, любезно предоставленном мне моим другом, была только MySQL, то и информацию надо хранить в ней. Я-то по наивности думал, что коль с Oracle более 10 лет работал, то и с этим зверем справлюсь одной левой... Счаз!!! Непонятки начались с момента инсталляции. Оказалось, что на винде (ноутбук, который у меня дома, с windows, вести разработку я предпочитаю на локальном компьютере, перекладывая отлаженный код на конечный сайт) сначала надо установить драйвер к этой базе, потом саму базу. Если создаешь базу в кодировке, отличной от latin1, предлагаемой по умолчанию (а зачем мне latin1, если информацию храню в cp1251), то надо еще и внести правки в my.ini... В общем, базу установил, под root’ом даже удалось зайти. Но не будешь же под root’ом создавать таблицы и т.п., нужен свой пользователь. Честно создал пользователя в MySQL Administrator, создал для него схему. А вот зайти под ним не могу. Пароль правильный, а не пускает... Долго бился я с этим змеем, пока мне не посоветовали забить на все администраторы и создать пользователя в командной строке. Причем создать именно такой командой
create user ’qqq’@’localhost’ identified by ’qqq’;
Я бы в жизни не допер, что пользователи qqq и qqq@localhost — это два разных человека. Зато со вторым проблем вообще никаких.
Теперь надо виндовым perl’ом залезть в базу. У меня на тот момент стоял Strawberry Perl — первый из перлов для windows, которые я увидел на www.perl.com. Надо-то всего ничего, доустановить библиотеку DBD::mysql. Только вот командой
cpan install DBD::mysql
результата не добьешься. Вылезает куча ошибок... Бился я с установкой этой библиотеки не один день. Победить не удалось. В инете нашел информацию про другую версию perl для windows — ActivePerl. И действительно, в этой версии perl’а установка новых модулей — милое дело. Выбрал в окне модулей нужный, кликнул мышкой, он и установился. Но вот DBD::mysql там не было, была библиотека DBD::mysqlPP, посредством которой отлично можно работать с базой MySQL, только вот разработку-то я веду на компьютере с windows, а на сайте — linux. Как-то не хочется делать по 2 версии каждого скрипта, меняя в нем только название библиотеки. Хорошо, что нашелся Camelbox, включающий в себя эту библиотеку. У Camelbox, правда нашелся другой грешок, я так и не смог для него установить DBD::Oracle, которая понадобилась на работе, пришлось на работе ставить ActivePerl.
Итог первого месяца: научился скачивать и разбирать страницы, получил опыт работы с регулярными выражениями, с которыми до этого не сталкивался, классная штука, однако, научился помещать найденную информацию в БД MySQL.