Esempio n. 1
0
    def media_info_a1(self, media_pk: int, max_id: str = None) -> Media:
        """
        Get Media from PK

        Parameters
        ----------
        media_pk: int
            Unique identifier of the media
        max_id: str, optional
            Max ID, default value is None

        Returns
        -------
        Media
            An object of Media type
        """
        media_pk = self.media_pk(media_pk)
        shortcode = InstagramIdCodec.encode(media_pk)
        """Use Client.media_info
        """
        params = {"max_id": max_id} if max_id else None
        data = self.public_a1_request(
            "/p/{shortcode!s}/".format(**{"shortcode": shortcode}),
            params=params)
        if not data.get("shortcode_media"):
            raise MediaNotFound(media_pk=media_pk, **data)
        return extract_media_gql(data["shortcode_media"])
Esempio n. 2
0
    def media_info_gql(self, media_pk: int) -> Media:
        """
        Get Media from PK

        Parameters
        ----------
        media_pk: int
            Unique identifier of the media

        Returns
        -------
        Media
            An object of Media type
        """
        media_pk = self.media_pk(media_pk)
        shortcode = InstagramIdCodec.encode(media_pk)
        """Use Client.media_info
        """
        variables = {
            "shortcode": shortcode,
            "child_comment_count": 3,
            "fetch_comment_count": 40,
            "parent_comment_count": 24,
            "has_threaded_comments": False,
        }
        data = self.public_graphql_request(
            variables, query_hash="477b65a610463740ccdb83135b2014db")
        if not data.get("shortcode_media"):
            raise MediaNotFound(media_pk=media_pk, **data)
        if data["shortcode_media"]["location"]:
            data["shortcode_media"]["location"] = self.location_complete(
                extract_location(data["shortcode_media"]["location"])).dict()
        return extract_media_gql(data["shortcode_media"])
Esempio n. 3
0
    def hashtag_medias_a1_chunk(
        self, name: str, max_amount: int = 27, tab_key: str = "", end_cursor: str = None
    ) -> Tuple[List[Media], str]:
        """
        Get chunk of medias and end_cursor by Public Web API

        Parameters
        ----------
        name: str
            Name of the hashtag
        max_amount: int, optional
            Maximum number of media to return, default is 27
        tab_key: str, optional
            Tab Key, default value is ""
        end_cursor: str, optional
            End Cursor, default value is None

        Returns
        -------
        Tuple[List[Media], str]
            List of objects of Media and end_cursor
        """
        unique_set = set()
        medias = []
        while True:
            data = self.public_a1_request(
                f"/explore/tags/{name}/",
                params={"max_id": end_cursor} if end_cursor else {},
            )["hashtag"]
            page_info = data["edge_hashtag_to_media"]["page_info"]
            end_cursor = page_info["end_cursor"]
            edges = data[tab_key]["edges"]
            for edge in edges:
                if max_amount and len(medias) >= max_amount:
                    break
                # check uniq
                media_pk = edge["node"]["id"]
                if media_pk in unique_set:
                    continue
                unique_set.add(media_pk)
                # check contains hashtag in caption
                media = extract_media_gql(edge["node"])
                if f"#{name}" not in media.caption_text:
                    continue
                # Enrich media: Full user, usertags and video_url
                medias.append(self.media_info_gql(media_pk))
            ######################################################
            # infinity loop in hashtag_medias_top_a1
            # https://github.com/adw0rd/instagrapi/issues/52
            ######################################################
            # Mikhail Andreev, [30.12.20 02:17]:
            # Instagram always returns the same 9 medias for top
            # I think we should return them without a loop
            ######################################################
            # if not page_info["has_next_page"] or not end_cursor:
            #     break
            # if max_amount and len(medias) >= max_amount:
            #     break
            break
        return medias, end_cursor
Esempio n. 4
0
    def usertag_medias_gql(self,
                           user_id: int,
                           amount: int = 0,
                           sleep: int = 2) -> List[Media]:
        """
        Get medias where a user is tagged (by Public GraphQL API)

        Parameters
        ----------
        user_id: int
        amount: int, optional
            Maximum number of media to return, default is 0 (all medias)
        sleep: int, optional
            Timeout between pages iterations, default is 2

        Returns
        -------
        List[Media]
            A list of objects of Media
        """
        amount = int(amount)
        user_id = int(user_id)
        medias = []
        end_cursor = None
        variables = {
            "id": user_id,
            "first": 50 if not amount or amount > 50 else amount,
            # These are Instagram restrictions, you can only specify <= 50
        }
        while True:
            if end_cursor:
                variables["after"] = end_cursor
            data = self.public_graphql_request(
                variables, query_hash="be13233562af2d229b008d2976b998b5")
            page_info = json_value(data,
                                   "user",
                                   "edge_user_to_photos_of_you",
                                   "page_info",
                                   default={})
            edges = json_value(data,
                               "user",
                               "edge_user_to_photos_of_you",
                               "edges",
                               default=[])
            for edge in edges:
                medias.append(edge["node"])
            end_cursor = page_info.get("end_cursor")
            if not page_info.get("has_next_page") or not end_cursor:
                break
            if amount and len(medias) >= amount:
                break
            time.sleep(sleep)
        if amount:
            medias = medias[:amount]
        return [extract_media_gql(media) for media in medias]
Esempio n. 5
0
    def user_medias_gql(self,
                        user_id: int,
                        amount: int = 50,
                        sleep: int = 2) -> List[Media]:
        """
        Get a user's media by Public Graphql API

        Parameters
        ----------
        user_id: int
        amount: int, optional
            Maximum number of media to return, default is 50
        sleep: int, optional
            Timeout between pages iterations, default is 2

        Returns
        -------
        List[Media]
            A list of objects of Media
        """
        amount = int(amount)
        user_id = int(user_id)
        medias = []
        end_cursor = None
        variables = {
            "id": user_id,
            "first": 50 if amount > 50 else
            amount,  # These are Instagram restrictions, you can only specify <= 50
        }
        while True:
            if end_cursor:
                variables["after"] = end_cursor
            data = self.public_graphql_request(
                variables, query_hash="e7e2f4da4b02303f74f0841279e52d76")
            page_info = json_value(data,
                                   "user",
                                   "edge_owner_to_timeline_media",
                                   "page_info",
                                   default={})
            edges = json_value(data,
                               "user",
                               "edge_owner_to_timeline_media",
                               "edges",
                               default=[])
            for edge in edges:
                medias.append(edge["node"])
            end_cursor = page_info.get("end_cursor")
            if not page_info.get("has_next_page") or not end_cursor:
                break
            if len(medias) >= amount:
                break
            time.sleep(sleep)
        return [extract_media_gql(media) for media in medias[:amount]]
Esempio n. 6
0
    def user_medias_paginated_gql(self,
                                  user_id: int,
                                  amount: int = 0,
                                  sleep: int = 2,
                                  end_cursor=None) -> Tuple[List[Media], str]:
        """
        Get a page of a user's media by Public Graphql API

        Parameters
        ----------
        user_id: int
        amount: int, optional
            Maximum number of media to return, default is 0 (all medias)
        sleep: int, optional
            Timeout between pages iterations, default is 2
        end_cursor: str, optional
            Cursor value to start at, obtained from previous call to this method
        Returns
        -------
        Tuple[List[Media], str]
            A tuple containing a list of medias and the next end_cursor value
        """
        amount = int(amount)
        user_id = int(user_id)
        medias = []
        variables = {
            "id": user_id,
            "first": 50 if not amount or amount > 50 else amount,
            # These are Instagram restrictions, you can only specify <= 50
        }
        variables["after"] = end_cursor
        data = self.public_graphql_request(
            variables, query_hash="e7e2f4da4b02303f74f0841279e52d76")
        page_info = json_value(data,
                               "user",
                               "edge_owner_to_timeline_media",
                               "page_info",
                               default={})
        edges = json_value(data,
                           "user",
                           "edge_owner_to_timeline_media",
                           "edges",
                           default=[])
        for edge in edges:
            medias.append(edge["node"])
        end_cursor = page_info.get("end_cursor")
        if amount:
            medias = medias[:amount]
        return ([extract_media_gql(media) for media in medias], end_cursor)
Esempio n. 7
0
    def hashtag_medias_a1(self,
                          name: str,
                          amount: int = 27,
                          tab_key: str = '') -> List[Media]:
        """
        Get medias for a hashtag

        Parameters
        ----------
        name: str
            Name of the hashtag
        amount: int, optional
            Maximum number of media to return, default is 27
        tab_key: str, optional
            Tab Key, default value is ""

        Returns
        -------
        List[Media]
            List of objects of Media
        """
        unique_set = set()
        medias = []
        end_cursor = None
        while True:
            data = self.public_a1_request(
                f'/explore/tags/{name}/',
                params={"max_id": end_cursor} if end_cursor else {})['hashtag']
            page_info = data["edge_hashtag_to_media"]["page_info"]
            end_cursor = page_info["end_cursor"]
            edges = data[tab_key]["edges"]
            for edge in edges:
                if amount and len(medias) >= amount:
                    break
                # check uniq
                media_pk = edge['node']['id']
                if media_pk in unique_set:
                    continue
                unique_set.add(media_pk)
                # check contains hashtag in caption
                media = extract_media_gql(edge['node'])
                if f'#{name}' not in media.caption_text:
                    continue
                # Enrich media: Full user, usertags and video_url
                medias.append(self.media_info_gql(media_pk))
            ######################################################
            # infinity loop in hashtag_medias_top_a1
            # https://github.com/adw0rd/instagrapi/issues/52
            ######################################################
            # Mikhail Andreev, [30.12.20 02:17]:
            # Instagram always returns the same 9 medias for top
            # I think we should return them without a loop
            ######################################################
            # if not page_info["has_next_page"] or not end_cursor:
            #     break
            # if amount and len(medias) >= amount:
            #     break
            break
        if amount:
            medias = medias[:amount]
        return medias