Копирование блоков страницы(или целиком)
У меня возникла задача копирования всей страницы, или отдельных блоков ее.
Т.е. мне нужно сохранить(через скрипт страницу) и отправить ее на файл php для обработки ( по идее в переменную ее занести не получится). А скрипт в свою очередь, сохранит ее в файл... Т.е. получится, как бы копирование страницы и сохранение в определенной папке. У меня есть встраиваемый скрипт, который берет со страницы ее юрл и титл. (на JS написаны). А вот как быть со страницей не знаю. Как это можно реализовать? Может, конечно, неправильно выбрал тему. Но я если честно, даже не знаю с чего начать. |
Странно, что это требуется именно на клиенте брать вывод. 0_о
Не очень тривиальная задача. На ум приходит только брать "document.body.innerHTML", а из шапки брать и генерировать на основе свойств document... Потом ajax'ом отправлять это всё через POST на php скрипт... |
Не обязательно на клиенте. Мой php скрипт хранит юрл данной страницы. Если можно подобное реализовать, используя PHP, то так даже лучше. Но, насколько я знаю, то страницы защищены от инклуда(если не с данного сайта он происходит).
|
Нет, с этим нету проблем, если на сервере разрешено сокетное подключение.
На всех платных хостингах оно разрешено. Делается это примерно так:
$fp = fsockopen("www.site.ru", 80, $errno, $errstr, 30);
if ($fp) {
// Генерируем шапку запроса к странице:
$out = "GET /path_to_page.php HTTP/1.1\r\n"
."Host: www.site.ru\r\n"
."Connection: Close\r\n"
."\r\n";
// Посылаем запрос на сайт:
fwrite($fp, $out);
// Получаем ответ:
while (!feof($fp)) {
$result = fgets($fp, 128);
}
fclose($fp);
// Результатом будет ответ сервера: шапка http + тело ответа,
// оно будет разделено двумя переносами "\r\n" так что нужно
// будет найти первое вхождение "\r\n\r\n" и отрезать шапку от тела.
echo $result;
}
Подробнее об этом можно почитать тут. Кроме того, тебе понадобятся базовые знания протокола http. |
В принципе можно не заморачиваться с сокетами и просто использовать функцию file_get_contents.
А через JavaScript все равно исходный код страницы не восстановить, т.к. каждый браузер приводит html-код к своему виду. Если у вас установлен плагин к файерфоксу Web Developer Toolbar, то сравните "View source" и "View generated source". В частности, firefox удаляет все xhtml-ные закрытия тегов, а-ля <img />. ИЕ еще больше мудрит: у некоторых значений аттрибутов удаляет кавычки, у некоторых нет. |
Ну да, можно в принципе и через file_get_contents(). Но всё-таки везде есть fsockopen, но кое-где нету fopen wrappers, так что использовать fsockopen тут более рационально. Тем более, для расширения (+cookie, +POST, ...) да и для общего развития полезно использовать fsockopen. Это ИМХО, конечно... :)
|
маленькое замечание: file_get_contents (если параметр - url) внутри себя использует сокетное соединение, так что - без разницы =)
|
Ну да, по сути любое соединение, использующее URL fopen wrappers является сокетным соединением, т.е fopen, file_get_contents, include (раньше) если им передать url в качестве пути, откроют сокетное подключение, т.к это вообще механизм коммуникации между клиентом и сервером.
Всё таки по мне, лучше использовать сделанную именно для таких задач функцию fsockopen, чем функции работы с локальными файлами с параметром url. Да и если приложение нужно будет расширить, например получить страницу, сгенерированную POST запросом, или с определёнными куками, или получить через https, то тут уже легче самому запрос генерировать, чем писать неудобный (имхо) контекст для file_get_contents. В любом случае, решать автору :) |
Цитата:
Вот, подправил немного код. Исправил ошибку, и сделал более универсальным:
function par_str($str,$start,$end){
$res = substr($str,strpos($str,$start)+strlen($start),strlen($str));
if ($end!=null) $res = substr($res,0,strpos($res,$end));
echo($res);
return $res;
}
function get_contents($url){
$url_host = par_str($url,"http://","/");
$url_get = par_str($url,$url_host,null);
$fp = fsockopen($url_host, 80, $errno, $errstr, 30);
if ($fp) {
$out = "GET ".$url_get." HTTP/1.1\r\n"
."Host: ".$url_host."\r\n"
."Connection: Close\r\n"
."\r\n";
fwrite($fp, $out);
$result="";
while (!feof($fp)) {
$result .= fgets($fp, 128);
}
$result=substr($result,strpos($result,"\r\n\r\n")+4,strlen($result));
$result=substr($result,strpos($result,"\r\n")+2,strlen($result));
fclose($fp);
return $result;
}
}
а ошибка была у тебя, точку надо поставить, что бы объединить все:
while (!feof($fp)) {
$result .= fgets($fp, 128);
}
|
Возникла проблема с кодировкой... При отображении в браузере, все нормально. если я пытаюсь отправить эту страницу на мыло. То некоторые приходят нормально, а некоторые в непонятной кодировке...
Пример: "µРїРѕСЃС‚СЊ - Главная страница". Как этого можно избежать? и перекодировать(или другие способы) что бы на мыло приходил нормальный текст. |
Phoenix, а на мыле у каждого своя кодировка (к тому же почти все сервисы и почтовые клиенты имеют возможность перекодировки). Если интересует текст в конкретной кодировке, можно преобразовать ее (например, функцией iconv(...) (или даже свою написать)) + в дополнении указать кодировку в header'e письма.
|
Цитата:
|
про "iconv(...)" я знаю... но вот задача.. определить в какой кодировке страница(строка). Нашел функции. но многие некорректно работают. ищу дальше...
|
Phoenix, да, поищи, у меня только на памяти mb_detect_encoding(...), да и то для ее работы должен быть модуль php_mbstring включен.
|
Цитата:
На сколько я понял, обмен данными возможен только между родительским и дочерними окнами :( Следовательно, все же придется использовать AJAX. Или есть способы взаимодействия двух(не связаных окон между собой)? |
Phoenix,
Цитата:
Цитата:
Цитата:
|
Цитата:
|
В общем, чтоб не парится, попробуй поработать с классом Snoopy, там очень просто сделать и поддержание сессии, и установку cookies. JavaScriptом тут делать не рационально.
Стоит ли в твоей задаче получить содержание страницы, которую открыл авторизированный пользователь (логин и пароль которого ты не знаешь), и которая не видна без авторизации? Тут такой парсинг (через сокеты) будет невозможен. Да и кстати, через ajax разве можно сделать кроссайтовую передачу данных? Вообще, опиши полностью задачу, тебе надо проверять есть ли в странице определённый элемент, или нужно сохранить документ в его определённом состоянии? Если расскажешь суть задачи, может тогда сможем помочь тебе определиться с выбором алгоритма "забирания" страницы. |
Цитата:
|
Kolyaj,
Хм, а тут написано что через традиционный ajax - нет :) Цитата:
|
Андрей Параничев, через "традиционный" нет конечно - это противоречит политике безопасности. Но я говорил о том, что аякс вызовет свой скрипт (в пределах своего домена), который в свою очередь уже отправит сокет-запрос на другой домен.
|
Андрей Параничев,
я кстати вообще не использую аббревиатуру ajax, т.к. она только путает. В частности я не говорил, что нужно использовать XMLHttpRequest. Допустим, нам нужно передать данные на другой домен и получить ответ. Мы создаем элемент script, в get-параметрах передаем данные, а нам возвращается ответ в виде js-кода, который, допустим, вызывает callback-функцию. |
Цитата:
Сейчас склоняюсь к идее отправлять GET параметром document.body.innerHTML(уже работает, но криво). Но столкнулся с новой проблемой. Как быть с символами #,?,&... Ведь мой скрипт, когда парсит GET параметры неправильно будет определять тогда document.body.innerHTML. П.С. у меня есть полный доступ к странице со стороны JS, данные совему скрипту я отправляю через GET параметры... |
Если я правильно понимаю.. то через rawurlencode() надо пройти весь document.body.innerHTML. для замены символов их кодами.... и отправлять втаком виде в GET параметре...
Надюесь поможет. |
маленькое замечание: Phoenix, GET имеет ограниченную длину, так что большой документ не передашь.
|
Phoenix,
создай динамически форму с методом post, и в ней содержимое отправляй в скрытый iframe (если ответ конечно не нужен). |
Хм... так получается отправлять надо со скрытово iframe( что бы не обновлять страницу и к AJAX не прибегать)...
Вот, сделал функцию.. которая отсылает данные о странице на мыло... Но одна две проблемы: 1. Т.к. форма встраивается в страицу, то при субмите, страница обновляется. Как это можно избежать? если добавить фрейм? и только его обновлять(отправлять). 2. Не так значательно... Возможно ли с письмом отправить css файл? п.с. у меня страница идет как тело документа, но хеадер Content-Type: text/html. Возможно ли, через mail() отправлять письма с прикрепленными файлами? Вот сама функция:
<a href='javascript:(function(){
var s=document.createElement("script");
s.charset="windows-1251";
s.language="javascript";
s.type="text/javascript";
var form=document.createElement("form");
form.id=form.name="page";
form.method="post";
form.action="test.php";
var tit=document.createElement("input");
tit.type="text";
tit.id=tit.name="stitle";
form.appendChild(tit);
var area=document.createElement("textarea");
area.id=area.name="sbody";
form.appendChild(area);
var inf=prompt("Введите описание ссылки", "");
if (inf!=null) {
tit.value=inf+"-"+document.title;
alert("test");
document.body.appendChild(form);
alert("test2");
area.value=document.body.innerHTML;
document.body.appendChild(s);
form.submit();
}else{alert("Не определен");}
alert("test3");})();' return false>[Добавить URL в базу]</a>
|
Цитата:
Код-то в соответствующие теги запихните, как это читать-то? |
Я чуть чуть изменил, открываю в отдельном окне. форму и отправляю. получилось даже лучше. Вот одна проблема....
document.body.innerHTML - полностью игнорирует CSS файл... и заголовок. Как это можно обойти? и добавить к document.body.innerHTML И еще одна проблема... Когда отправляется форма, то все символы " и ' переделываются в \" и \' как это можно убрать? парсить весь текст не хочется... думаю эт можно проще сделать. Но не знаю как |
с обратными слешами разобрался... Осталось только получения мета данных и линки на сss. На JS это можно сдлеать?
|
alert(document.getElementsByTagName('HTML')[0].innerHTML);
В FF работает. |
| Часовой пояс GMT +3, время: 06:34. |