Думаю все знают что в поиске Google можно предварительно просмотреть сайт открыв его превью.
Сегодня поделюсь с вами одним из методов получения данного изображения.
Не так давно писал одну вещь(вскоре с вами поделюсь), для себя, и мне требовалось получить превью сайта, любого.
Было несколько вариантов:
— писать свой генератор превьюшек, для себя понимаю это как — скрипт должен открывать страницу, фотографировать ее, и сохранять изображение, а нужно ведь всю страницу с отработанными javascript, как я понял нужно неплохо расширить сервер дополнительными модулями и прочим, данный метод меня не устраивает.
— далее взгляд пал на готовые решения, разнообразные ресурсы предлагающие api для получения превью сайтов, но отдаваться на волю неизвестному ресурсу, та и не везде получаешь свободу, решено было отложить, а в дальнейшем и отказаться, от этого подхода
— далее пришел на помощь wordpress, а точнее сервис mShots(можно прочесть к примеру здесь), но сервис в любом случае возвращает изображение, что не дает проверить его отсутствие(кому потребуется могу поделится моим решением проверки отсутствия изображения), а так же требуется некоторое время для создания превью, и сервис никак об этом не оповещает, кроме как возвращает в любом случае gif preloader.
На последнем методе было решено остановится, и продолжить поиски метода более стабильного. Поиски проходили в Google Seach и трудно было не обратить внимания на то что он предоставляет скриншот сайта(как выяснилось, получает он их из своего кеша), и тут пришла мысль — «А почему бы и нет».
Так начался поиск способа получить изображения от google.
Первым делам посмотрел запрос:
Как видите ничего радостного, куча непонятных параметров.
Не буду описывать каждый параметр, притом не все знаю, скажу лишь что «j» и «b» можно смело удалить, а «а» — это у нас уникальный трехзначный хэш, который, как выяснилось, встраивается в html разметку страницы, откуда его и можно получить, распарсив ее.
Решил опробовать я данный подход, логика была следующая:
— осуществляем поиск, в нашей задаче требуется найти сайт, поэтому ищем по запросу site:http://domain.zone
— парсим полученное и находим наши хеш и url
— формируем нужный запрос и получаем искомое
Все вроде бы логично, поэтому приступил к работе.
Волей судьбы и недостатком времени отложил данную работу и забыл про нее до сегодняшнего вечера,
а напомнило про нее мне ресурс goo.gl, а точнее новый дизайн, и новые функции, в том числе превью страницы к которой мы хотим получить короткий url. Да, для тех кто не знает goo.gl предоставляет возможность получить короткий url.
Решил поискать информацию по запросу «clients1.google.com/webpagethumbnail», на данный адрес ссылается google seach для получения скриншотов сайтов, и наткнулся на вот эту статью, здесь уже описан реализованный метод, который хотел, изначально, воплотить я.
Немного расстроенный, и в то же время рад что есть уже готовое для моей плюшки, вернулся с интересом к goo.gl, здесь заглянуть в отправляемые запросы, и что же я вижу:
Тут уже нет страшных параметров, есть url api нашей сокращалки, и есть два параметра:
— security_token — как я понял необязательный параметр (исправьте меня если я не прав)
— url — и адрес по которому хотим получить информацию
Все предельно ясно и понятно, ограничений не замечено, пробуем получить желаемое. Написал небольшой тестовый скрипт, на котором и экспериментировал, вышла вот что:
header('Content-Type: text/html; charset=utf-8');//устанавливаем кодировку
define('URL_API', 'http://goo.gl/api/shorten');//определяем константу с адрессом откуда будем получать данные
/*
* Функция служит для отправки запроса на нужный адресс
*
* @param string $wab_page
* url страницы, привью которой хотим получить
* @param string $url
* url отправки запроса
* @param boolean $header
* определяет получить возвращаемые значения или только заголовки
*
* @return boolean or decode json
* возвращает либо true, при $header=TRUE и существовании файла,
* или ответ сервера в формате decode json
*/
function http_request($wab_page, $url=URL_API, $header=FALSE) {
$ch = curl_init();//инициализируем сеанс
curl_setopt($ch, CURLOPT_HEADER, $header);//включаем/выключаем вывод заголовков
curl_setopt($ch, CURLOPT_NOBODY, $header);//включаем/выключаем вывод тела ответа
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);//следуем всем заголовкам "Location: "
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);//теперь curl вернет нам ответ, а не выведет
if(!$header){//проверяем хотим мы получить только заголовки или нет, если нет то
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.77 Safari/535.7');//прикидываемся браузером
curl_setopt($ch, CURLOPT_POST, TRUE);//говорим что хотим передать данные методом POST
curl_setopt($ch, CURLOPT_POSTFIELDS, 'url='.urlencode($wab_page).'&security_token=');//устанавливаем переменные, которые будут переданные по методу post
}else{//если да то
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);//останавливаем curl от проверки сертификата
}
curl_setopt($ch, CURLOPT_URL, $url);//уcтанавливаем урл, к которому обратимся
$response = curl_exec($ch);//выполняем запрос curl
curl_close($ch);//завершает сеанс curl и освобождает все ресурсы
if($header){//если получаем только заголовки, то
if(strpos($response, "200 OK")!==false)//проверяем код статуса, если 200 то все ок
return true;//возвращаем положительный ответ
}else//если хотим ответ, то
return json_decode($response);//возвращаем decode json строку с ответом
}
$wab_page='http://b-d.com.ua/';//картинку какого сайта хотим получить
$request=http_request($wab_page);//делаем запрос к гуглу
if($request){//если что то пришло, то
$img=$request->preview_url;//получаем url картинки
$short_url=$request->short_url;//получаем короткий линк сайта
if(http_request(null,$img,true)){//проверяем наличие изображения, если есть
echo $wab_page.' - <a href="'.$short_url.'">'.$short_url.'</a>
<img src="'.$img.'">';//выводим данные
}else{//если нет изображения
echo $wab_page.' - <a href="'.$short_url.'">'.$short_url.'</a>
что то нет желанной картинки у гугла';//выводим данные
}
}else{
echo 'Ошибка запроса =(';
}
Откомментировал весь код, что бы было понятно что я здесь творю. Файлом скачать можно здесь.
Коротко опишу:
— первым делом делаем запрос по адресу api «goo.gl/api/shorten», в ответ получаем json строку с информацией: «short_url», «long_url»,«creation_time»,«preview_url»
— далее проверяю существование изображения(т.к., на сколько я понял, возвращается путь к изображению всегда), проверяя заголовки на статус 200
— если все хорошо то отдаем картинку, не все хорошо сообщаем об этом
Чем мне нравится такой подход больше всех остальных:
— Я завишу только от гугла, вряд ли он просто закроется, или перестанет работать, как сторонний ресурс, с другой стороны он может прикрыть такую возможность получения превью(но на этот случай у меня есть mShots)
— Данный подход быстрее, и короче по коду, чем делать запросы к поисковику и парсить страницы
— И тут я могу еще получить короткий адресс что для моей задачи является положительным дополнением
К сожалению тестовую страницу не сделал, боюсь
На этом все, надеюсь многим будет полезна информации, догадываюсь где сразу найдут многие применении.
P.S. Жду любых исправлений и дополнений, в особенности интересует как можно улучшить мой существующий код, заранее прошу прощение за возможные неточности и особенно орфографию, время суток сказывается.
Автор: Bookin