- Поисковые системы
- Практика оптимизации
- Трафик для сайтов
- Монетизация сайтов
- Сайтостроение
- Социальный Маркетинг
- Общение профессионалов
- Биржа и продажа
- Финансовые объявления
- Работа на постоянной основе
- Сайты - покупка, продажа
- Соцсети: страницы, группы, приложения
- Сайты без доменов
- Трафик, тизерная и баннерная реклама
- Продажа, оценка, регистрация доменов
- Ссылки - обмен, покупка, продажа
- Программы и скрипты
- Размещение статей
- Инфопродукты
- Прочие цифровые товары
- Работа и услуги для вебмастера
- Оптимизация, продвижение и аудит
- Ведение рекламных кампаний
- Услуги в области SMM
- Программирование
- Администрирование серверов и сайтов
- Прокси, ВПН, анонимайзеры, IP
- Платное обучение, вебинары
- Регистрация в каталогах
- Копирайтинг, переводы
- Дизайн
- Usability: консультации и аудит
- Изготовление сайтов
- Наполнение сайтов
- Прочие услуги
- Не про работу
Как снизить ДРР до 4,38% и повысить продажи с помощью VK Рекламы
Для интернет-магазина инженерных систем
Мария Лосева
Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий
dkameleon, как я понял из контекта, стандартный параметр followlocation обрабатывает относительные ссылки вполне нормально. А вот функция-костыль - это уже неизвестно. Я ещё грешу на реферер, который возможно, не верно подставляется. Я бы даже сразу так сделал:
function curl_flollow_exec($ch, $redirects = 0) {
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
$data = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (($http_code == 301 || $http_code == 302) && ++$redirects < 10) {
preg_match('/(Location:|URI:)(.*?)\n/', $data, $matches);
if (isset($matches[2])) {
$redirect_url = trim($matches[2]);
if ($redirect_url !== '') {
$download_url = curl_getinfo ($ch, CURLINFO_EFFECTIVE_URL);
$redirect_url = abs_url ($redirect_url, $download_url);
curl_setopt($ch, CURLOPT_REFERER, $download_url);
curl_setopt($ch, CURLOPT_URL, $redirect_url);
return curl_flollow_exec($ch, $redirects);
}
}
}
return $data;
}
function abs_url ($link, $base_url) {
if (!$link) return $base_url;
$parse_url = parse_url($link);
$base = parse_url($base_url);
$host_url = $base['scheme'] . "://" . $base['host'];
if ($parse_url['scheme']) {
$abs_url = $link;
} elseif ($parse_url['host']) {
$abs_url = "http://" . $link;
} else { // ссылка относительная
if (preg_match("!^/!", $link)) {
$abs_url = $host_url . $link;
} elseif (preg_match("!^(\.\./)+!", $link, $tt0)) {
$num = preg_match_all("!\.\./!", $tt0['0'], $tt1);
preg_match("!(.*)/(?:.+?/){{$num}}$!", dirname($base['path']) . "/", $tt2);
$abs_url = $host_url . $tt2['1'] . "/" . preg_replace("!^(\.\./){{$num}}!", "", $link);
} elseif (preg_match("!^\./!", $link)) {
$abs_url = $host_url . dirname($base['path']) . substr($link, 1);
} else {
$abs_url = $base_url . ((preg_match("!/$!", $base_url))?"":"/") . $link;
}
}
return $abs_url;
}
Подставляем реферер загрузившейся страницы, и преобразовываем ссылку редиректа в абсолютную.
И я проспал :)
Подхватывайте куки руками, и в заговоке потом передавайте.
Пробовал, не помогает, т.к. самый первый же редирект идет на 404 и куки передавать тупа некуда.
А ну опоздал, оказывается все просто было:D
Я бы не сказал, что опоздали. То, что я сделал, это через попу. Т.е. я сначала передаю логин и пароль эмулятору через POST. Он создает куку, но редиректит на 404. Потом я повторно дергаю страницу через эмулятор, но передаю логин и пароль уже через GET. И только так я получаю то, что хотел.
Согласитесь, что это очень криво. Хотелось бы нормального решения. Т.е. чтобы эмулятор работал как и cURL с FOLLOWLOCATION - сразу, за один проход.
Этого, сожалению, у меня пока не получилось.
---------- Добавлено 04.11.2013 в 21:17 ----------
1) в хидере "Location" внутренний адрес, пробуйте добавить к нему хост и правельно передать через CURLOPT_URL.
Я именно так и делаю - добавляю к нему http://www.site.com/. В скрипте из этого топика я просто удалил ту строку, чтобы не отвлекала. Остальное там как есть.
---------- Добавлено 04.11.2013 в 21:23 ----------
dkameleon, как я понял из контекта, стандартный параметр followlocation обрабатывает относительные ссылки вполне нормально. А вот функция-костыль - это уже неизвестно. Я ещё грешу на реферер, который возможно, не верно подставляется. Я бы даже сразу так сделал:
function curl_flollow_exec($ch, $redirects = 0) {
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
$data = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (($http_code == 301 || $http_code == 302) && ++$redirects < 10) {
preg_match('/(Location:|URI:)(.*?)\n/', $data, $matches);
if (isset($matches[2])) {
$redirect_url = trim($matches[2]);
if ($redirect_url !== '') {
$download_url = curl_getinfo ($ch, CURLINFO_EFFECTIVE_URL);
$redirect_url = abs_url ($redirect_url, $download_url);
curl_setopt($ch, CURLOPT_REFERER, $download_url);
curl_setopt($ch, CURLOPT_URL, $redirect_url);
return curl_flollow_exec($ch, $redirects);
}
}
}
return $data;
}
function abs_url ($link, $base_url) {
if (!$link) return $base_url;
$parse_url = parse_url($link);
$base = parse_url($base_url);
$host_url = $base['scheme'] . "://" . $base['host'];
if ($parse_url['scheme']) {
$abs_url = $link;
} elseif ($parse_url['host']) {
$abs_url = "http://" . $link;
} else { // ссылка относительная
if (preg_match("!^/!", $link)) {
$abs_url = $host_url . $link;
} elseif (preg_match("!^(\.\./)+!", $link, $tt0)) {
$num = preg_match_all("!\.\./!", $tt0['0'], $tt1);
preg_match("!(.*)/(?:.+?/){{$num}}$!", dirname($base['path']) . "/", $tt2);
$abs_url = $host_url . $tt2['1'] . "/" . preg_replace("!^(\.\./){{$num}}!", "", $link);
} elseif (preg_match("!^\./!", $link)) {
$abs_url = $host_url . dirname($base['path']) . substr($link, 1);
} else {
$abs_url = $base_url . ((preg_match("!/$!", $base_url))?"":"/") . $link;
}
}
return $abs_url;
}
Подставляем реферер загрузившейся страницы, и преобразовываем ссылку редиректа в абсолютную.
И я проспал :)
Не с подстановкой реферера все равно 404. Дело не в нем, видимо...
Так там может 404 и отдают, что у вас кука не та, которую ждут. Есть такая тема например на pinterest, там followlocation не проходит тк курл не подхватывает куку и ее приходиться парсить из заголовка и ручками подставлять. То есть если URL верный, но вам там отдают 404, где должно быты 200 значит у вас:
1. Плохой рефер
2. Не тот заголовок запроса
3. Нет куки, которая нужна
4. Вас забинили:D
AutoBlogger, тогда, по идее, curl_flollow_exec шлет POST запрос вместо GET.
Может быть попробовать так:
function curl_flollow_exec($ch, $redirects = 0) {
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
$data = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (($http_code == 301 || $http_code == 302) && ++$redirects < 10) {
preg_match('/(Location:|URI:)(.*?)\n/', $data, $matches);
if (isset($matches[2])) {
$redirect_url = trim($matches[2]);
if ($redirect_url !== '') {
$download_url = curl_getinfo ($ch, CURLINFO_EFFECTIVE_URL);
$redirect_url = abs_url ($redirect_url, $download_url);
curl_setopt($ch, CURLOPT_POST, false);
curl_setopt($ch, CURLOPT_REFERER, $download_url);
curl_setopt($ch, CURLOPT_URL, $redirect_url);
return curl_flollow_exec($ch, $redirects);
}
}
}
return $data;
}
function abs_url ($link, $base_url) {
if (!$link) return $base_url;
$parse_url = parse_url($link);
$base = parse_url($base_url);
$host_url = $base['scheme'] . "://" . $base['host'];
if ($parse_url['scheme']) {
$abs_url = $link;
} elseif ($parse_url['host']) {
$abs_url = "http://" . $link;
} else { // ссылка относительная
if (preg_match("!^/!", $link)) {
$abs_url = $host_url . $link;
} elseif (preg_match("!^(\.\./)+!", $link, $tt0)) {
$num = preg_match_all("!\.\./!", $tt0['0'], $tt1);
preg_match("!(.*)/(?:.+?/){{$num}}$!", dirname($base['path']) . "/", $tt2);
$abs_url = $host_url . $tt2['1'] . "/" . preg_replace("!^(\.\./){{$num}}!", "", $link);
} elseif (preg_match("!^\./!", $link)) {
$abs_url = $host_url . dirname($base['path']) . substr($link, 1);
} else {
$abs_url = $base_url . ((preg_match("!/$!", $base_url))?"":"/") . $link;
}
}
return $abs_url;
}
А я примерно так и сделал:
function abs_url($link, $base_url) {
if (!$link) {
return $base_url;
}
$parse_url = parse_url($link);
$base = parse_url($base_url);
$host_url = $base['scheme'] . "://" . $base['host'];
if (isset($parse_url['scheme'])) {
$abs_url = $link;
} elseif (isset($parse_url['host'])) {
$abs_url = "http://" . $link;
} else {
if (preg_match("!^/!", $link)) {
$abs_url = $host_url . $link;
} elseif (preg_match("!^(\.\./)+!", $link, $tt0)) {
$num = preg_match_all("!\.\./!", $tt0['0'], $tt1);
preg_match("!(.*)/(?:.+?/){{$num}}$!", dirname($base['path']) . "/", $tt2);
$abs_url = $host_url . $tt2['1'] . "/" . preg_replace("!^(\.\./){{$num}}!", "", $link);
} elseif (preg_match("!^\./!", $link)) {
$abs_url = $host_url . dirname($base['path']) . substr($link, 1);
} else {
$abs_url = $base_url . ((preg_match("!/$!", $base_url)) ? "" : "/") . $link;
}
}
return $abs_url;
}
function curl_flollow_exec($ch, $redirects = 0) {
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
$data = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (($http_code == 301 || $http_code == 302) && ++$redirects < 10) {
preg_match('/(Location:|URI:)(.*?)\n/', $data, $matches);
if (isset($matches[2])) {
$redirect_url = trim($matches[2]);
if (stripos($redirect_url, 'http') !== 0) {
$download_url = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
$redirect_url = abs_url($redirect_url, $download_url);
}
if ($redirect_url !== '') {
curl_setopt($ch, CURLOPT_URL, $redirect_url);
return curl_flollow_exec($ch, $redirects);
}
}
}
return $data;
}
function curl_post($url, $data, $set_cookie) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_REFERER, $url);
curl_setopt($ch, CURLOPT_AUTOREFERER, true);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (X11; Linux i686; rv:16.0) Gecko/20100101 Firefox/16.0 Iceweasel/16.0');
if ($set_cookie) {
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt');
}
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookie.txt');
if ($data) {
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, mk_post_data($data));
} else {
curl_setopt($ch, CURLOPT_POST, false);
}
$result = curl_flollow_exec($ch);
curl_close($ch);
return $result;
}
Но все равно, приходится сначала передавать данные по POST для установки куки, а потом передавать их снова, но уже через GET для правильного редиректа. Костыль, конечно...
AutoBlogger, то, что я выше написал - работает?
И да - лучше сделать так:
Таким образом, для GET запроса достаточно указать один параметр
$html = curl_post('http://ya.ru');AutoBlogger, то, что я выше написал - работает?
Нет, к сожалению.
Кому интересно, могу кинуть URL в личку. Это один из клонов pinterest-а.
AutoBlogger, мне интересно :) Всё-таки хочу добить эту проблему.
Нет, к сожалению.
Кому интересно, могу кинуть URL в личку. Это один из клонов pinterest-а.
Не знаю как у клона, но у самого pinterest куки надо парсить и передавать с заголовом, курл их не может нормально обработать
FollowLocation, bukachuk, отправил Вам ссылку в личку. Посмотрите пожалуйста.