PDA

Показать полную графическую версию : [решено] Парсинг страницы с редиректом (PHP)


Luzuk
15-03-2012, 18:48
Здравствуйте.
Мне тут дали такое задание:
С сайта elibrary.ru нужно сдёрнуть список с фамилиями сотрудников универа, а затем сделать по ним поиск на сайте самого вуза и в итоге собрать по ним суммарную инфу.

Все конечно можно вручную сделать, всего то около 100 человек :)
Но что-то, меня, как немного ленивому айтишнику, такая перспектива не устраивает. С учетом, что собранную статистику после еще обновлять скорей всего придется и думаю не раз. По этому и решил сразу написать скрипт по автоматизации этого дела.

Парсинг самих страниц и поиск по найденному уже почти сделал.
Но парсинг первого сайта пока работает только по уже скаченным вручную страницам, заставить его самого их качать ни как не получается.

Пробовал получить страницу через curl
// 1. инициализация
$ch = curl_init();
// 2. указываем параметры, включая url
curl_setopt($ch, CURLOPT_URL, "http://elibrary.ru/defaultx.asp");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_PROXY, 'х.х.х.х:3128');
curl_setopt($ch, CURLOPT_PROXYUSERPWD,'ххххх:ххххх');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_UNRESTRICTED_AUTH, 1);
//curl_setopt($ch, CURLOPT_COOKIESESSION, 1);
// 3. получаем HTML в качестве результата
echo curl_exec($ch);

А в результате получаю: cURL Error: Maximum (20) redirects followed
Как я понял это из-за того что страница пытается получить сессию, и редиректиться из-за этого все время между главной страницей и страницей старта сессии.


Вообще данные которые мне нужны находятся тут... (http://elibrary.ru/authors.asp)
А вот как их от туда вытащить не знаю, с учетом, что на страницу методом POST еще нужно параметры передавать.



Буду очень признателен, за оказанную помощь ;)

Luzuk
15-03-2012, 19:49
Сам нашел причину.

Кукис нужно сохранить
curl_setopt ($ch, CURLOPT_COOKIEJAR, 'cookie.txt');

Но, все равно не получилось, что хотел.

Сниффером перехватил запрос, который передается при нажатии кнопки Поиска. И попробовал его также передать... но толку ни какого.

// 1. инициализация
$ch = curl_init();
// 2. указываем параметры, включая url
curl_setopt($ch, CURLOPT_URL, "http://elibrary.ru/authors.asp");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//curl_setopt($ch, CURLOPT_PROXY, 'х.х.х.х:3128');
//curl_setopt($ch, CURLOPT_PROXYUSERPWD,'ххххх:ххххх');

curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_UNRESTRICTED_AUTH, 1);

curl_setopt ($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3');
curl_setopt ($ch, CURLOPT_POST, 1);
curl_setopt ($ch, CURLOPT_POSTFIELDS, 'authors_all=&pagenum=&authorbox_name=&orgid=984&orgadminid=&surname=&countryid=&town=&regionid=&rubriccode=&orgname=%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%B2%D0%BE%D1%81%D1%82%D0%BE%D0%BA%D1%81%D0%BA%D0%B8%D0%B9+% D0%B3%D0%BE%D1%81%D');

curl_setopt ($ch, CURLOPT_COOKIEJAR, 'cookie.txt');
curl_setopt ($ch, CURLOPT_REFERER, 'http://elibrary.ru/authors.asp');
curl_setopt ($ch, CURLOPT_HTTPHEADER, array('Expect:'));
curl_setopt($ch, CURLOPT_HEADER, 1);
// 3. получаем HTML в качестве результата

$output = curl_exec($ch);

В результате, поля поиска не заполняются, и выводиться пустая форма...

Sham
15-03-2012, 19:54
Да, там бесконечный редирект. Вроде бы если не шлются кукисы, или неправильные кукисы.
//curl_setopt($ch, CURLOPT_COOKIESESSION, 1); »
CURLOPT_COOKIESESSION - начинает новую сессию, поэтому имхо нужно включить.

Сам пост-запрос можно отловить в браузере (каким-нть livehttpheaders в FF), или посмотреть хтмл формы (атрибуты name контролов)
см. (http://ru.php.net/manual/ru/function.curl-setopt.php) CURLOPT_POST и CURLOPT_POSTFIELDS

Luzuk
16-03-2012, 18:06
Все заработало. Оказалось, что если указывать не верный идентификатор браузера, форма не возвращается.
указан был фаерфокс, а я тестил через хром и ИЕ6. Поставил USERAGENT Интернет Эксплорера 6го и в нем все заработало.
В итоге просто закоментил указание USERAGENT и все заработало в обоих браузерах.

Вот конечный вариант функции для пост запроса через прокси:
function post_content ($url,$postdata) {
$uagent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)";

$ch = curl_init( $url );
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_PROXY, 'x.x.x.x:8080');
curl_setopt($ch, CURLOPT_PROXYUSERPWD,'xxx:xxx');
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_ENCODING, "");
// curl_setopt($ch, CURLOPT_USERAGENT, $uagent);
curl_setopt($ch, CURLOPT_TIMEOUT, 120);
curl_setopt($ch, CURLOPT_FAILONERROR, 1);
curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);
curl_setopt($ch, CURLOPT_COOKIEJAR, "d://coo.txt");
curl_setopt($ch, CURLOPT_COOKIEFILE,"d://coo.txt");

$content = curl_exec( $ch );
$err = curl_errno( $ch );
$errmsg = curl_error( $ch );
$header = curl_getinfo( $ch );
curl_close( $ch );

$header['errno'] = $err;
$header['errmsg'] = $errmsg;
$header['content'] = $content;
return $header;
}

//(c) parsing-and-i.blogspot.com




© OSzone.net 2001-2012