From a2a508bc0ea2859080cd9435fdfd3634507ff6a3 Mon Sep 17 00:00:00 2001 From: Andrei Sivtsov <55785095+Siwaaa@users.noreply.github.com> Date: Mon, 18 Oct 2021 12:29:21 +0300 Subject: [PATCH] search users by following and followers (#979) --- examples/searchUsersByFollowers.php | 15 ++++++ src/InstagramScraper/Endpoints.php | 16 +++++++ src/InstagramScraper/Instagram.php | 74 +++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+) create mode 100644 examples/searchUsersByFollowers.php diff --git a/examples/searchUsersByFollowers.php b/examples/searchUsersByFollowers.php new file mode 100644 index 00000000..6c6bbf20 --- /dev/null +++ b/examples/searchUsersByFollowers.php @@ -0,0 +1,15 @@ +login(); +sleep(2); // Delay to mimic user + +$username = 'kevin'; +$search_result = []; +$account = $instagram->getAccount($username); +sleep(1); +$search_result = $instagram->searchFollowers($account->getId(), 'andy'); // Search users with a nickname 'andy' by followers 'kevin' +echo '
' . json_encode($search_result, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . '
'; diff --git a/src/InstagramScraper/Endpoints.php b/src/InstagramScraper/Endpoints.php index e30d6329..1f6b94d5 100644 --- a/src/InstagramScraper/Endpoints.php +++ b/src/InstagramScraper/Endpoints.php @@ -22,6 +22,8 @@ class Endpoints const LIKES_BY_SHORTCODE = 'https://www.instagram.com/graphql/query/?query_id=17864450716183058&variables={"shortcode":"{{shortcode}}","first":{{count}},"after":"{{likeId}}"}'; const FOLLOWING_URL = 'https://www.instagram.com/graphql/query/?query_id=17874545323001329&id={{accountId}}&first={{count}}&after={{after}}'; const FOLLOWERS_URL = 'https://www.instagram.com/graphql/query/?query_id=17851374694183129&id={{accountId}}&first={{count}}&after={{after}}'; + const FOLLOWING_URL_V1 = 'https://i.instagram.com/api/v1/friendships/{{accountId}}/following/'; + const FOLLOWERS_URL_V1 = 'https://i.instagram.com/api/v1/friendships/{{accountId}}/followers/'; const FOLLOW_URL = 'https://www.instagram.com/web/friendships/{{accountId}}/follow/'; const UNFOLLOW_URL = 'https://www.instagram.com/web/friendships/{{accountId}}/unfollow/'; const REMOVE_FOLLOWER_URL = 'https://www.instagram.com/web/friendships/{{accountId}}/remove_follower/'; @@ -215,6 +217,20 @@ public static function getFollowingJsonLink($accountId, $count, $after = '') return $url; } + public static function getFollowersUrl_v1($accountId) + { + $url = str_replace('{{accountId}}', urlencode($accountId), static::FOLLOWERS_URL_V1); + + return $url; + } + + public static function getFollowingUrl_v1($accountId) + { + $url = str_replace('{{accountId}}', urlencode($accountId), static::FOLLOWING_URL_V1); + + return $url; + } + public static function getUserStoriesLink($variables=[]) { $url = self::getGraphQlUrl(InstagramQueryId::USER_STORIES, ['variables' => json_encode($variables)]); diff --git a/src/InstagramScraper/Instagram.php b/src/InstagramScraper/Instagram.php index 2b406a4d..aacdb7f3 100644 --- a/src/InstagramScraper/Instagram.php +++ b/src/InstagramScraper/Instagram.php @@ -1796,6 +1796,80 @@ public function getPaginateAllFollowing($accountId, $pageSize = 20, $nextPage = 'accounts' => $accounts ]; } + + /** + * Search users by followers + * @param string $accountId Account id of the profile to query + * @param string $query Query to search by followers + * + * @return array + * @throws InstagramException + */ + public function searchFollowers($accountId, $query = '') + { + $response = Request::get( + Endpoints::getFollowersUrl_v1($accountId), + array_merge( + ['x-ig-app-id' => self::X_IG_APP_ID], + $this->generateHeaders($this->userSession) + ), + array( + "search_surface" => "follow_list_page", + "query" => $query, + "enable_groups" => "true" + ) + ); + + if ($response->code !== static::HTTP_OK) { + throw new InstagramException('Response code is ' . $response->code . '. Body: ' . static::getErrorBody($response->body) . ' Something went wrong. Please report issue.', $response->code); + } + + $jsonResponse = $this->decodeRawBodyToJson($response->raw_body); + + if ($jsonResponse['status'] !== 'ok') { + throw new InstagramException('Response status is ' . $jsonResponse['status'] . '. Body: ' . static::getErrorBody($response->body) . ' Something went wrong. Please report issue.', $response->code); + } + + return $jsonResponse; + } + + /** + * Search users by following + * @param string $accountId Account id of the profile to query + * @param string $query Query to search by following + * + * @return array + * @throws InstagramException + */ + public function searchFollowing($accountId, $query = '') + { + $response = Request::get( + Endpoints::getFollowingUrl_v1($accountId), + array_merge( + ['x-ig-app-id' => self::X_IG_APP_ID], + $this->generateHeaders($this->userSession) + ), + array( + "includes_hashtags" => "false", + "search_surface" => "follow_list_page", + "query" => $query, + "enable_groups" => "true" + ) + ); + + if ($response->code !== static::HTTP_OK) { + throw new InstagramException('Response code is ' . $response->code . '. Body: ' . static::getErrorBody($response->body) . ' Something went wrong. Please report issue.', $response->code); + } + + $jsonResponse = $this->decodeRawBodyToJson($response->raw_body); + + if ($jsonResponse['status'] !== 'ok') { + throw new InstagramException('Response status is ' . $jsonResponse['status'] . '. Body: ' . static::getErrorBody($response->body) . ' Something went wrong. Please report issue.', $response->code); + } + + return $jsonResponse; + } + /** * @param array $reel_ids - array of instagram user ids * @return array