Пару дней назад мои хорошие знакомые из магазина http://www.sakura-shop.ru/ попросили меня посмотреть, почему при оформлении заказа не подсчитывается стоимость отправлений через почту России.
У меня тоже есть несколько магазинов. И на одном из них http://sumki.natropinkah.ru использовался похожий метод расчета. Проверив его работу, я был неприятно удивлен: алгоритм выдавал ошибку.
Пришлось лечить.
Мне известны несколько способов считать почту.
Один из них заключается в сборе текущих тарифов и самостоятельном подсчете стоимости пересылки. Но тарифы меняются, меняется алгоритм расчета. Более того, расчетная стоимость отличается от итоговой суммы, которую узнаешь уже в почтовом отделении. После анализа около 50-ти случайным образом взятых почтовых чеков, этот метод был отброшен.
Мною не был найден API почты, что породило другой способ подсчета. Он прост, и в его основе лежит парсинг выдаваемых скриптом http://www.russianpost.ru/autotarif/SelautotarifRus.aspx данных. Конечно, почта уже не раз меняла скрипт, и перебои с расчетом тоже случались, но этот способ мне показался более эффективным. В первую очередь потому, что сумма расчета лучше отражала реальное положение дел. Погрешность составляла не более 100 рублей.
Есть и другие способы расчета, но остановимся пока на парсинге.
Скрипт у моих друзей изначально выглядел так:
$url = "http://www.russianpost.ru/autotarif/Autotarif.aspx?viewPost=53&countryCode=643&typePost=4&viewPostName=asd&countryCodeName=asd&typePostName=asd&weight={$ves}&value1={$cennost}&postOfficeId={$indeks}";
$result = file_get_contents($url);
Далее шел парсинг и бралось содержимое тега с id=«TarifValue».
Тут я поставил брейк и пошел смотреть получаемый файл. Вот, что я увидел:
<html><head></head><body onload="document.myform.submit();"><form method="post" name="myform" style="visibility:hidden;"><input id="key" name="key" value="959114"/><input type="submit"/></form></body></html>
Интересно. Получается, почтовикам не нравится, что мы дергаем их сервер, и они решили придумать защиту.
Давайте дадим им POST.
$key = substr($result,strpos($result,'value="')+7,6);
$ch = curl_init( $url );
curl_setopt( $ch, CURLOPT_POST, 1);
curl_setopt( $ch, CURLOPT_POSTFIELDS, 'key='.$key);
curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt( $ch, CURLOPT_HEADER, 0);
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec( $ch );
Но и тут оказалось все очень интересно.
<html><head></head><body onload="window.location.replace(window.location.toString())"></body></html>
Продублировав запрос, я получил желаемое. Вот скрипт полностью:
$url = "http://www.russianpost.ru/autotarif/Autotarif.aspx?viewPost=53&countryCode=643&typePost=4&viewPostName=asd&countryCodeName=asd&typePostName=asd&weight={$ves}&value1={$cennost}&postOfficeId={$indeks}";
$result = file_get_contents($url);
$key = substr($result,strpos($result,'value="')+7,6);
$ch = curl_init( $url );
curl_setopt( $ch, CURLOPT_POST, 1);
curl_setopt( $ch, CURLOPT_POSTFIELDS, 'key='.$key);
curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt( $ch, CURLOPT_HEADER, 0);
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec( $ch );
$result = curl_exec( $ch );
На текущий момент систему я победил. Пока почтовики еще что-нибудь не придумают. Пользуйтесь на здоровье.
Автор: valkoivo
Пытался адаптировать ваш скрипт для вытаскивания трекинга посылки (там механизм тот же через key) и ничего не получается :(