Для проекта мне нужно долгое время просматривать страницы страницы (например, 1-2 года) в facebook.
Сначала я попытался сделать один запрос, но оказалось, что только запрос
/PAGE_ID/insights?since=xxx&until=xxx
не возвращает все данные, которые я хочу (он каким-то образом подавляет данные, как если бы был некоторый предел размеру ответа).
Затем я попытался разделить диапазон дат (например, 01.04.2011-01.04.2011 -> 01.04.2011-01.08.2011-01.12.2011-01.04.2011), который также не работал, как будто я хотел ,
Мой следующий подход состоял в том, чтобы запрашивать только те значения, которые мне нужны, например «page_stories, page_impressions, …». Запросы выглядели так:
/PAGE_ID/insights/page_impressions/day?since=xxx&until=xxx
Это действительно сработало, но не с ajax. Иногда иногда возникали некоторые запросы (особенно если я изменил вкладку браузера в google chrome), и мне нужно быть уверенным, что все запросы возвращают ответ. Решение с синхронным синдромом займет слишком много времени, учитывая, что один запрос требует не менее 2 секунд, а с диапазоном дат 2 года у меня может быть около 300 одиночных запросов, для этого требуется слишком много времени для завершения.
Наконец, я наткнулся на способность facebook выполнять пакетные запросы, которые именно то, что мне нужно. Он может упаковать до 50 запросов за один вызов, что значительно снижает полосу пропускания. И вот где я застрял. В facebook api приведены некоторые примеры использования, но никто из них не работал, когда я тестировал их в Graph Explorer и через php facebook api sdk. Я попытался упаковать этот запрос
PAGE_ID/insights/page_fan_adds/day?since=1332486000&until=1333695600
в пакетный запрос, но не удалось.
Кажется, что api прослушивается. Это всегда дает мне эту ошибку, когда я использую знак вопроса '?' в поле 'relative_url'.
{ "error": { "message": "batch parameter must be a JSON array", "type": "GraphBatchException" } }
Вот что я пробовал:
Они дают ошибку «должен быть JSON-массив»:
?batch=[{"method":"GET","relative_url":"/PAGE_ID/insights/page_fan_adds/day?since=1332486000&until=1333695600"}]
Эти два фактически возвращают данные, но они игнорируют параметры:
?batch=[{"method":"GET","relative_url":"/PAGE_ID/insights/page_fan_adds/day","body":"since=1332486000 until=1333695600"}] ?batch=[{"method":"GET","relative_url":"/PAGE_ID/insights/page_fan_adds/day","body":"since=1332486000,until=1333695600"}] ?batch=[{"method":"GET","relative_url":"/PAGE_ID/insights/page_fan_adds/day","body":{"since":"1332486000","until":"1333695600"}}]
И этот говорит мне, что это «Неподдерживаемый пост-запрос»:
?batch=[{"method":"POST","relative_url":"/PAGE_ID/insights/page_fan_adds/day","body":"since=1332486000 until=1333695600"}]
Может кто-нибудь помочь?
Наконец, я нашел решение своей проблемы. Он не упоминается в документации на facebook, но для этого запроса
?batch=[{"method":"GET","relative_url":"/PAGE_ID/insights/page_fan_adds/day?since=1332486000&until=1333695600"}]
для правильной работы мы должны использовать такую функцию, как
urlencode()
для кодирования json-части. Таким образом, запросы работают как шарм. Пример php:
$insights = $facebook->api('?batch=['.urlencode('{"method":"GET","relative_url":"/PAGE_ID/insights/page_fan_adds/day?since=1332572400&until=1333782000"}').']' ,'post',array('access_token' => $this->facebook->getAccessToken()));
что приводит к следующему:
?batch=[%7B%22method%22%3A%22GET%22%2C%22relative_url%22%3A%22%2FPAGE_ID%2Finsights%2Fpage_fan_adds%2Fday%3Fsince%3D1300086000%26until%3D1307862000%22%7D]
В этом примере используется array
идентификаторов для выполнения пакетного запроса с использованием urlencoding.
$postIds = [ 'XXXXXXXXXXXXXXX_XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX_XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX_XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX_XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX_XXXXXXXXXXXXXXX', ]; $queries = []; foreach( $postIds as $postId ) { $queries[] = [ 'method' => 'GET', 'relative_url' => '/' . $postId . '/comments?summary=1&filter=stream&order=reverse_chronological', ]; } $requests = $facebook->post( '?batch=' . urlencode( json_encode( $queries ) ) )->getGraphNode();