Получаем скриншоты сайтов с помощью Google Thumbnail
Думаю все знают что в поиске Google можно предварительно просмотреть сайт открыв его превью.
Сегодня поделюсь с вами одним из методов получения данного изображения.
Не так давно писал одну вещь(вскоре с вами поделюсь), для себя, и мне требовалось получить превью сайта, любого.
Было несколько вариантов:
- писать свой генератор превьюшек, для себя понимаю это как — скрипт должен открывать страницу, фотографировать ее, и сохранять изображение, а нужно ведь всю страницу с отработанными javascript, как я понял нужно неплохо расширить сервер дополнительными модулями и прочим, данный метод меня не устраивает.
- далее взгляд пал на готовые решения, разнообразные ресурсы предлагающие api для получения превью сайтов, но отдаваться на волю неизвестному ресурсу, та и не везде получаешь свободу, решено было отложить, а в дальнейшем и отказаться, от этого подхода
- далее пришел на помощь wordpress, а точнее сервис mShots, но сервис в любом случае возвращает изображение, что не дает проверить его отсутствие(кому потребуется могу поделится моим решением проверки отсутствия изображения), а так же требуется некоторое время для создания превью, и сервис никак об этом не оповещает, кроме как возвращает в любом случае gif prelo
ader.
На последнем методе было решено остановится, и продолжить поиски метода более стабильного. Поиски проходили в Google Seach и трудно было не обратить внимания на то что он предоставляет скриншот сайта(как выяснилось, получает он их из своего кеша), и тут пришла мысль — «А почему бы и нет».
Так начался поиск способа получить изображения от google.
Мне захотелось сделать скриншот сайта, на котором есть робота Львів, а так же много другой полезной информации и я первым делам посмотрел запрос:
Как видите ничего радостного, куча непонятных параметров.
Не буду описывать каждый параметр, притом не все знаю, скажу лишь что «j» и «b» можно смело удалить, а «а» — это у нас уникальный трехзначный хэш, который, как выяснилось, встраивается в html разметку страницы, откуда его и можно получить, распарсив ее.
Решил опробовать я данный подход, логика была следующая:
- осуществляем поиск, в нашей задаче требуется найти сайт, поэтому ищем по запросу site:http://example.com
- парсим полученное и находим наши хеш и 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)
- Данный подход быстрее, и короче по коду, чем делать запросы к поисковику и парсить страницы
- И тут я могу еще получить короткий адрес что для моей задачи является положительным дополнением
К сожалению тестовую страницу не сделал, боюсь хостинг не выдержит, если кто то может предложить где можно разместить страницу, с радостью последую совету.
На этом все, надеюсь многим будет полезна информации, догадываюсь где сразу найдут многие применении.