|
Ясное дело, что попавший в подобную ситуацию вебмастер сразу же попытается связаться с хостером (либо с администратором сервера) и выяснить, что же всё-таки произошло, утеряна ли информация и если это так, возможно ли её восстановить. Если на сервере регулярно производился backup и у вебмастера хорошие/легальные отношения с хостером, то первому волноваться не стоит - всё будет востановлено (читать - ОК). В противном случае, когда поставленный вопрос остаётся без ответа, либо на него даётся отрицательный ответ, либо «да», но частично (к примеру, имеется «не самая свежая» резервная копия), то возможно вам поможет описанный в этой статье приём.
Такая ситуация, когда-то имела место быть и с сайтом нашего доблестного ABC-IT. Когда в то время я хотел зайти на сайт и вместо ожидаемого «контента» увидил сообщение, что ресурс заблокирован, моя учётная запись на сервере тоже была заблокирована, так что пришлось заходить под чужой : )) (шутка) Звоню хостеру - вначале он сказал, что обязательно посмотрит в чём дело, но позже. «Позже» (прошло 3 дня!!!) он наконец сказал, что в тот злосчастный день админ запустил сценарий, который удаляет все данные пользователей, незарегистрированных у них в регистре клиентов (в числе которых оказался я), но он может «поднять» резервную копию, правда, сначала надо будет составить и подписать новый договор (с условием хостинг за счёт денег и рекламных баннеров). Далее мы договарились, что сделаем это в ближайшие дни. Но не через день, не через два, ни даже через неделю хостер договор подписывать не хотел, а просто тянул время (зачем-то). С его стороны было много отговорок, но особенно мне запомнилась та, когда я в очередной раз звонил в офис (звонил раз в 2, 3 дня - чтобы особо не надоедать), который ,кстати, находится в Риге, менеджер ответственный за договора на хостинг говорит мне, «Я сейчас не могу ничем помочь, т.к. нахожусь далеко от Риги. ...», хотя конечно, может быть у них там телефон на переадресации (в чём я очень сомневаюсь)... Вообщем закончилась эта история сменой хостинга. Я всё-таки нашёл backup БД месячной давности, а все новые материалы решил возобновить посредством поисковых машин. Как вы наверное догадались, далее речь пойдёт именно об этом методе.
Всё дело в том, что некоторые из поисковых систем сохраняют у себя полную копию найденных HTML страниц. На случай, если пользователь решит ознакомиться с содержимым найденой страницы, а её оригинал по каким-то причинам окажется недоступным. Этим обстоятельством я и воспользовался. Всё что мне оставалось сделать - зайти на какой-нибудь поисковик, осуществляющий вышеназванную операцию и на котором хорошо индексировался бы мой сайт(например Google), воспользоваться расширенным поиском, указав в качестве параметра адрес недостающей в backup’е страницы (например www.abc-it.lv/index.php/id/1322), начать поиск, и сохранить найденную копию страницы на жёсткий диск. Повторить эти действия для всех недостающих страниц.
К счастью на тот момент у меня было (а точнее не было), всего лишь, чуть менее 20 таких страниц. И всю операцию востановления я проделовал вручную (имеется в виду - не используя ничего кроме browser’а) потеряв около 10 минут времени. Естественно небезуспешно, иначе, данная статья не была бы написана.
А что делать если утеренных страниц гораздо больше? Именно для таких случаев командой ABC Information Technologies был написан небольшой сценарий на Perl.
О сценарии g_cachesaver.pl v. 0.2 (beta)
Данный сценарий предназначен для загрузки («скачивания») всех доступных закэшированных в поисковой системе Google страниц указанного в качестве параметра сайта. Найденные страницы сохраняются в отдельные HTML файлы, которые затем могут быть, соответствующим образом (для вашего случая) обработаны и снова помещены на сайт.
Как вы наверное заметили, в данной статье описывается бэта версия сценария. Она была проверена на кэшах нескольких десятков сайтов (было сохранено, в общей сложности около 2000 HTML страниц). В процессе тестирования было выявлено, что проблемы с сохранением кэшей могут возникнуть, если скрипт запустить во время так называемого Google дэнса (пляски в стиле робот =). Ну а также работоспособность сценария в очень большой степени зависит от качества вашего интернет подключения. Такчто если Google в данный момент не танцует и сетка работает как надо, можете смело использовать g_cachesaver.pl
Скажу вам по секрету, что в будущих версиях данного ПО будет предусмотрено значительно большее количество полезных функций. Таких например как: работа через прокси, возможность возобновлять сохранение с той страницы на которой процесс был прерван... Ну а также в наших планах значится разработка аналогичных сценариев для работы с другими поисковыми системами.
Самую свежую версию данного сценария, а также другого программного обеспечения и материалов, написанных нами, вы можете найти на сайте www.abc-it.lv.
Ну и в заключении привожу исходные коды сценария. Те, кого «детали» не интересуют, могут скачать готовый продукт отсюда и пропустить следующую часть статьи, всем остальным читать обязательно! ;)
P.S.: Так как сценарий написан на Perl. Чтобы его запустить вам потребуется установить на компьютер интерпритатор Perl. Для Windows советую скачать и установить ActiveState Perl.
Собственно сценарий (исходники)
#!perl
## g_cachesaver v. 0.2(beta) by ABC-IT.lv
## -------------------------------------
## This script loads contents of HTML pages of the
## specified site from Google* cache and saves them to separate files.
## It can be useful for webmasters in emergency cases =)
## -------------------------------------
## Installation:
## ^^^^^^^^^^^^^
## 1. In the first line of the script specify a correct way to Perl on your computer
## (e.q. "#!/usr/bin/perl");
## 2. Create the destination folder;
## 3. Set coresponding rights to file and destination folder.
## -------------------------------------
## Usage:
## ^^^^^^
## g_cachesaver.pl <path to destionation folder> <site url>
## Where:
## <path to destination folder> - path to folder where pages will be stored
## <site url> - your site URL.
## e.q.
## g_cachesaver.pl abc_cache www.abc-it.lv
## // all pages will be copied in "abc_cache" folder
## -------------------------------------
## Authors (C) Mihail Chernov & ABC-IT.lv team
## Greetings to deMarche, InCube and all who was on CC`2005 party!
## Special thanks to RST/GHC team! ;)
##-------------------------------------
## You can download newest version from
## www.abc-it.lv/releases/g_cachesaver.html
##
##
## *Google is a trademark of Google Inc.
use IO::Socket;
$g_site = 'www.google.ru'; #URL сайта Google
print "\n";
# При недостаточном кол-ве переданных программе параметров
# выводим соотв. сообщение и завершаем работу сценария.
if ($#ARGV<1) {
print "Usage:\n";
print "g_cachesaver.pl <path to destionation folder> <site url>\n\n";
print " Where:\n";
print " <path to destination folder> - path to folder where pages will be stored\n";
print " <site url> - your site URL.\n";
print " E.q.: g_cachesaver.pl abc_cache_copy www.abc-it.lv\n";
exit;
}
$dest_path = @ARGV[0]; #1-й параметр - путь к каталогу куда будем сохранять
$s_site = @ARGV[1]; #2-й пареметр - URL сайта/раздела/страницы
# Проверяем наличие директории, а также возможность создания в нём
# файлов. Для этого пытаемся создать в этой директории файл test.txt...
if (!(-e $dest_path)) {
print "Folder '$dest_path' not exists!\n";
exit;
}
if (!open(FH,">$dest_path/test.txt")) {
print "Can't open for writing '$dest_path/test.txt'!\n";
exit;
} else {
close(FH);
unlink("$dest_path/test.txt");
}
## Подпрограмма загружающая(по протоколу HTTP)
## и выдающая содержимое
## страницы с заданым в качестве 1-го параметра URL.
##
## В качестве 2-го параметра передаётся указатель
## на переменную куда следует поместить
## текст загруженной страницы.
##
## 3-й параметр - указатель на ассоцативный массив
## содержащий HTTP COOKIES (теневые посылки).
## Данные из этого массива будут не только
## считываться, но и модифицироваться в процессе
## загрузки заголовка посылаемого сервером.
##
## 4-й параметр (необязательный) - адрес страницы откуда произошёл
## переход.
##
## ВНИМАНИЕ!!! Данная версия подпрограммы была модифицирована
## специально для работы с поисковой системой Google
## Она подключается ТОЛЬКО к серверу доменое имя которого
## хранится в переменной $g_site ("www.google.com"),
## но в поле "Host" запроса указывает реальное доменое имя.
##
## Таким образом, сайт www.google.com выдаёт не только ссылки на кэши,
## но и сами кэши, если его об этом хорошо попросить ;) Причём выдаёт
## странички он гораздо быстрее и стабильнее чем "вспомогательные" сайты
## Google (проверенно опытным путём), куда ведут ссылки на сохранённые копии
## страниц.
sub wwwget {
local($url,$content,$cookies,$referer)=($_[0],$_[1],$_[2],$_[3]);
# записываем значения параметров в переменные с соотв. именами
local($crlf)="\r\n";
# присваиваем переменной значение символа конца строки (код HEX: 0D 0A)
if (substr($url,0,7) eq 'http://') {
substr($url,0,7,'');
}
# если строка (адрес загружаемой страницы) начинается с "http://",
# убираем эту часть строки (7 первых символов)
# Далее выделяем части адреса на:
# адрес сервера(сайт);
# порт;
# собственно адрес страницы на этом сайте.
local(@mas)=split /\//,$url;
local($server)=shift(@mas);
local($page)=substr($url,length($server),length($url)-length($server));
@mas=split(':',$server);
local($port)=@mas[1];
$server=substr($server,0,length($server)-length($port));
if ($page eq '') {
$page='/';
}
# адрес страницы по умолчанию = "/"
if ($port eq '') {
$port=80;
}
# номер порта по умолчанию = 80
local($sock);
$sock =
IO::Socket::INET->new( Proto => "tcp",
PeerAddr => "$g_site",
PeerPort => "$port",
Type => SOCK_STREAM)||return 0;
# пытаемся подключиться к заданому порту заданого сервера (в нашем случае к $g_site)
# по протоколу TCP через socket.
if (!$sock) {
return 0;
}
# если не удаётся возвращаем 0 (неудача)
# и выходим из подрограммы
$sock->autoflush(1);
# отключаем буфферизацию сокета
binmode($sock);
# на всякий случай устанавливаем "двоичный" (бинарный) режим
# работы с данными сокета (только для Windows, в Unix игнорируется)
# Посылаем запрос HTTP GET вида:
#
# GET <страница> HTTP/1.0
# Host: <сайт>
# User-Agent: Visit abc-it.lv ;)
# Accept: */*
# Referer: <referer>
# Cookie: <cookie1_name>=<cookie1_val>
# Cookie: <cookie2_name>=<cookie2_val>
# Cookie: ...
# Connection: close
print $sock ("GET $page HTTP/1.0$crlf".
"Host: $server$crlf".
"User-Agent: Visit abc-it.lv ;)$crlf".
"Accept: */*$crlf");
print $sock ("Referer: $referer$crlf");
local($cookie,$str);
# Отсылаем COOKIE'S
foreach $cookie (keys %$cookies) {
$str=$$cookies{$cookie};
print $sock "Cookie: $cookie=$str$crlf";
}
print $sock ("Connection: close$crlf$crlf");
# Очищаем значение переменной на которую указывает $content
$$content='';
local($header);
# читаем из сокета пока читается ;)
HR:while (<$sock>) {
if ($_ =~ /Connection: /i) {
last HR;
}
$header .= $_;
@mas=split/Set-Cookie: /i,$_;
if (@mas[1] ne '') {
@mas=split/=/,@mas[1];
$str=shift(@mas);
@mas[0]=join('=',@mas);
@mas=split/;/,@mas[0];
$$cookies{$str}=@mas[0];
}
}
# читаем заголовок HTTP
# попутно добавляя/редактируя значения массива
# с HTTP COOKIE на который указывает значение $cookies
<$sock>;
<$sock>;
# заголовок и содержимое страницы должны разделять
# 2 пустые строки, считываем их.
# А далее читаем собственно содержимое
# запрашиваемой страницы и добавляем его
# в переменную на которую указывает $content
while (<$sock>) {
$$content .=$_;
}
# закрываем соединение
close($sock);
return 1;
}
## Конец подпрограммы
## Попрограмма загружает и сохраняет в
## виде отдельных файлов страницы кэшированные в Google.
##
## параметр 1 - адрес google кэша
## параметр 2 - реальный адрес страницы
sub savecachetofile {
local($cache,$page)=($_[0], $_[1]);
# устанавливаем значения локальных переменных
# равные значениям передаваемых параметров.
local($res,%CO2);
# объявляем локальные переменные
$page =~ s/[^a-z0-9]/_/ig;
# все символы в $page не явл. латинскими буквами
# или цифрами заменяем на прочерк (_).
if (!&wwwget($cache, \$res, \%CO2, $g_site)) {
return 0;
}
# С помощью подрограммы wwwget
# пытаемся загрузить копию страницы с
# Google. Содержимое страницы будет помещено в $res.
# В случае неудачи возвращаем 0 и выходим из попрограммы.
$res =~ /<hr>\n/g;
# Находим первый встретившийся в значении $res "<hr>" + перевод строки.
# П.С.: Им заканчивается часть HTML автоматически добавляемая Google
# (она нам не к чему)
# Пытаемся открыть файл для записи
if (!open(FH,">$dest_path/$page.html")) {
return 0;
}
binmode(FH);
# переводим дескриптор в бинарный режим
print FH $';
# сохраняем то, что нашли после "<hr>\n" в $res
close(FH);
# закрываем файл
# возвращаем единицу (признак, что всё прошло OK)
return 1;
}
### Конец подпрограммы
$cu =0;
# обнуляем переменную-счётчик удачно загруженных страниц
$page = $g_site.'/search?q=+site:'.$s_site.'&hl=ru&lr=&start=0&sa=N&filter=0';
# устанавливаем URL первого запроса к Google
$referer = 'http://'.$g_site;
# присваиваем referer = "http://www.google.com"
# НАЧАЛО ОСНОВНОГО ЦИКЛА
# ЗАГРУЗКА РЕЗУЛЬТАТОВ С Google
while ($page ne '') {
print "Loading page from Google\n";
# пытаемся загрузить содержимое страницы с результатами
# в $content, запоминаем/передаём
# теневые посылки в асоц. массиве %COOKIES
# , а также передаём $referer (URL страницы с которой переходим)
if (&wwwget($page, \$content, \%COOKIES, $referer)) {
print "Done!\n";
print "Searching links to cached pages...\n\n";
# НАЧАЛО ЦИКЛА ПОИСКА КЭШЕЙ НА СТР. С РЕЗУЛЬТАТАМИ
# начинаем цикл если в $content находим подходящие
# ссылки на кэши
while ($content =~ /<a class=fl href="(http\:\/\/.*?search\?q=cache\:.*?\:(.*?)\+\+site.*?)"/g) {
print " Found page $2 cache!\n";
print " Loading and saving page...\n";
# передаём функции savecachetofile первое и второе
# совпадение с шаблоном поиска (URL кэша, оригинальный URL страницы соответственно)
if (!&savecachetofile($1,$2)) {
print " Failed to load/save '$2' Google cache!\n\n";
} else {
print "Done!\n\n";
++$cu;
}
# присваиваем $content текст после совпадения
$content = $';
}
# КОНЕЦ ЦИКЛА ПОИСКА КЭШЕЙ
} else {
print "Failed to load page from Google!\n\n";
$content = '';
}
$referer = $page;
# referer = текущей странице Google с результатами
# далее, на странице с результатами ищем ссылку "Next"
# и "запоминаем" её URL.
if ($content =~ /<a href=(\/search\?q=[^>]*?)><img src=\/intl\/[a-z]*?\/nav_next.gif/g) {
$page = 'http://'.$g_site.$1;
# в $page - полный адрес страницы
} else {
$page = '';
# признак того, что в Google больше нет страниц с результатами
}
}
# КОНЕЦ ОСНОВНОГО ЦИКЛА
print "$cu pages where saved to '$dest_path'\n\n";
print "Visit www.abc-it.lv ;)\n";
Перейти к рубрике --> Perl |