diff --git a/docs/as-module.rst b/docs/as-module.rst index 4a0d820..ebf8049 100644 --- a/docs/as-module.rst +++ b/docs/as-module.rst @@ -13,7 +13,7 @@ Python Module :mod:`instaloader` .. highlight:: python Instaloader exposes its internally used methods and structures as a Python -module, making it a **powerful and intuitive Python API for Instagram**, +module, making it a powerful and intuitive Python API for Instagram, allowing to further customize obtaining media and metadata. Start with getting an instance of :class:`Instaloader`:: @@ -82,20 +82,20 @@ metadata of a Profile. :class:`Profile` instances can be created with: - :meth:`Profile.get_followers` Profiles that follow given user. -- :attr:`Post.owner_profile`, :attr:`Story.owner_profile` and :attr:`StoryItem.owner_profile` +- :attr:`Post.owner_profile`, :attr:`Story.owner_profile`, :attr:`StoryItem.owner_profile` Owner profile of particular object. - :meth:`Post.get_likes` Profiles that liked a given :class:`Post` -- :attr:`PostComment.owner` attribute for comment in :meth:`Post.get_comments` +- :attr:`PostComment.owner` Profile of a Post comment. -For a list of real code examples using the Instaloader module for advanced -tasks, see :ref:`codesnippets`. +For a list of a few code examples that use the Instaloader module, see +:ref:`codesnippets`. -The reference of the many classes provided by the :mod:`instaloader` module is -divided into the following subsections. +The reference of the classes and functions provided by the :mod:`instaloader` module is +divided into the following subsections: .. toctree:: :maxdepth: 2 diff --git a/docs/basic-usage.rst b/docs/basic-usage.rst index ce72400..bec5af8 100644 --- a/docs/basic-usage.rst +++ b/docs/basic-usage.rst @@ -77,7 +77,7 @@ Instaloader supports the following targets: instructs Instaloader to also **download the user's stories**, - :option:`--highlights` - to **download highlights of each profile that is downloaded**, + to **download the highlights of that profile**, - :option:`--tagged` to **download posts where the user is tagged**, and @@ -86,7 +86,7 @@ Instaloader supports the following targets: to **download IGTV videos**. - ``"#hashtag"`` - Posts with a certain **hashtag** (the quotes are usually necessary), + Posts with a certain **hashtag** (the quotes are usually necessary). - ``%location id`` Posts tagged with a given location; the location ID is the numerical ID @@ -98,13 +98,13 @@ Instaloader supports the following targets: - ``:stories`` The currently-visible **stories** of your followees (requires - :option:`--login`), + :option:`--login`). - ``:feed`` - Your **feed** (requires :option:`--login`), + Your **feed** (requires :option:`--login`). - ``:saved`` - Posts which are marked as **saved** (requires :option:`--login`), + Posts which are marked as **saved** (requires :option:`--login`). - ``@profile`` All profiles that are followed by ``profile``, i.e. the *followees* of @@ -196,7 +196,7 @@ Filter Posts .. py:currentmodule:: instaloader The options :option:`--post-filter` and :option:`--storyitem-filter` -allows to specify criteria that posts or story items have to +allow to specify criteria that posts or story items have to meet to be downloaded. If not given, all posts are downloaded. The filter string must be a @@ -208,7 +208,7 @@ Id est, the following attributes can be used with both :option:`--post-filter` and :option:`--storyitem-filter`: - :attr:`~Post.owner_username` (str), :attr:`~Post.owner_id` (int) - Owner profile username / userid. + Owner profile username / user ID. - :attr:`~Post.date_utc` (datetime), :attr:`~Post.date_local` (datetime) Creation timestamp. Since :class:`~datetime.datetime` objects can be created @@ -217,7 +217,7 @@ Id est, the following attributes can be used with both instaloader --post-filter="date_utc <= datetime(2018, 5, 31)" target - :attr:`~Post.is_video` (bool) - Post/StoryItem is a video. For example, you may skip videos:: + Whether Post/StoryItem is a video. For example, you may skip videos:: instaloader --post-filter="not is_video" target @@ -234,8 +234,8 @@ As :option:`--post-filter`, the following attributes can be used additionally: instaloader --login=your_username --post-filter=viewer_has_liked :feed - :attr:`~Post.likes` (int), :attr:`~Post.comments` (int) - Likes count / Comments count. You might only want to download posts that - either you liked or were liked by many others**:: + Likes count / comments count. You might only want to download posts that + were either liked by yourself or by many others:: instaloader --login=your_username --post-filter="likes>100 or viewer_has_liked" profile @@ -265,7 +265,7 @@ along with each post where the Post's caption is saved. You can customize what metadata to save for each Post or StoryItem with :option:`--post-metadata-txt` and :option:`--storyitem-metadata-txt`. The default is ``--post-metadata-txt={caption}`` and no storyitem metadata txt. -These strings are formatted similar as in the :ref:`filename-specification` and +These strings are formatted similar as the path patterns described in :ref:`filename-specification` and the result is saved in text files, unless it is empty. Specifying these options multiple times results in output having multiple lines, @@ -299,10 +299,10 @@ Instaloader logged-in, create a session file:: instaloader --login=your_username -Then use the same parameter in your cronjob to load the session and download +Then use the same username in your cronjob to load the session and download the given targets:: - instaloader --login=your_username --quiet [...] + instaloader --login=your_username --quiet target [...] Instaloader saves the session file to ``~/.config/instaloader/session-YOUR-USERNAME``. See @@ -317,5 +317,6 @@ Instaloader exposes its internally used methods and structures, making it a powerful and intuitive Python API for Instagram, allowing to further customize obtaining media and metadata. -Also see :ref:`codesnippets`, where we collect example scripts that use -Instaloader to achieve more complex tasks. +Also see :ref:`codesnippets`, where we collect a few example scripts that use +Instaloader for simple tasks that cannot be done with the command line +interface. diff --git a/docs/cli-options.rst b/docs/cli-options.rst index 1aaaf9c..c656142 100644 --- a/docs/cli-options.rst +++ b/docs/cli-options.rst @@ -59,7 +59,7 @@ What to Download of each Post .. option:: --geotags, -G - **Download geotags** when available. Geotags are stored as a text file with + Download geotags when available. Geotags are stored as a text file with the location's name and a Google Maps link. This requires an additional request to the Instagram server for each picture. Requires :option:`--login`. @@ -106,12 +106,12 @@ What to Download of each Profile .. option:: --stories, -s - Also **download stories** of each profile that is downloaded. Requires + Also download stories of each profile that is downloaded. Requires :option:`--login`. .. option:: --highlights - Also **download highlights** of each profile that is downloaded. Requires + Also download highlights of each profile that is downloaded. Requires :option:`--login`. .. versionadded:: 4.1 @@ -161,7 +161,7 @@ Which Posts to Download Login (Download Private Profiles) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Instaloader can **login to Instagram**. This allows downloading private +Instaloader can login to Instagram. This allows downloading private profiles. To login, pass the :option:`--login` option. Your session cookie (not your password!) will be saved to a local file to be reused next time you want Instaloader to login. @@ -261,12 +261,12 @@ Miscellaneous Options Text file should separate arguments with line breaks. - args.txt example:: + args.txt example:: - --login=MYUSERNAME - --password=MYPASSWORD - --fast-update - profile1 - profile2 + --login=MYUSERNAME + --password=MYPASSWORD + --fast-update + profile1 + profile2 .. versionadded:: 4.1 diff --git a/docs/codesnippets.rst b/docs/codesnippets.rst index 16d6cba..e676419 100644 --- a/docs/codesnippets.rst +++ b/docs/codesnippets.rst @@ -42,7 +42,7 @@ The code example with :func:`~itertools.dropwhile` and :func:`~itertools.takewhile` makes the assumption that the post iterator returns posts in exact chronological order. As discussed in :issue:`666`, the following approach fits for an **almost chronological order**, where up to *k* older posts -are inserted into an otherwise chronological order, such as an Hashtag feed. +are inserted into an otherwise chronological order, such as a Hashtag feed. .. literalinclude:: codesnippets/666_historical_hashtag_data.py @@ -50,7 +50,7 @@ Likes of a Profile / Ghost Followers ------------------------------------ To obtain a list of your inactive followers, i.e. followers that did not like -any of your pictures, into a file you can use this approach. +any of your pictures, you can use this approach. .. literalinclude:: codesnippets/120_ghost_followers.py @@ -78,11 +78,11 @@ Discussed in :issue:`56`. Only one Post per User ---------------------- -To download only the one most recent post from each user, this snippet creates a -:class:`set` that contains the users of which a post has already been -downloaded. While iterating the posts, it checks whether the post's owner -already is in the set. If not, the post is downloaded from Instagram and the -user is added to that set. +To download only the single most recent post per user within a hashtag feed, +this snippet uses a :class:`set` that contains the users of whom a post has +already been downloaded. For each post, it checks whether the post's creator is +already contained in that set. If not, the post is downloaded from Instagram and +the user is added to that set. .. literalinclude:: codesnippets/113_only_one_per_user.py @@ -100,31 +100,6 @@ With Instaloader, it is easy to download the few most-liked pictures of a user. Discussed in :issue:`194`. -Upgrade Images by Local Copies ------------------------------- - -The following script finds local versions of images fetched by Instaloader, in -order to upgrade the downloaded images by locally-found versions with better -quality. It uses image hashing to identify similar images. - -`updgrade-instaloader-images.py `__ (external link to GitHub Gist) - -Discussed in :issue:`46`. - -Add Captions to Images ----------------------- - -Instaloader does not modify the downloaded JPEG file. However, one could combine -it with an imaging library such as Pillow or PIL to render the caption on -Instagram pictures. The following shows an approach. - -.. literalinclude:: codesnippets/110_pil_captions.py - -See also :attr:`Post.caption`, :attr:`Post.url`, :meth:`Post.from_shortcode`, -:func:`load_structure_from_file`. - -Discussed in :issue:`110`. - Metadata JSON Files ------------------- diff --git a/docs/codesnippets/110_pil_captions.py b/docs/codesnippets/110_pil_captions.py deleted file mode 100644 index c49157a..0000000 --- a/docs/codesnippets/110_pil_captions.py +++ /dev/null @@ -1,20 +0,0 @@ -from io import BytesIO - -from requests import get -from PIL import Image, ImageDraw -from instaloader import * - -L = Instaloader() - -# Load Post instance -post = load_structure_from_file(L.context, '2017-10-01_18-53-03_UTC.json.xz') -# or post = Post.from_shortcode(L.context, SHORTCODE) - -# Render caption -image = Image.open(BytesIO(get(post.url).content)) -draw = ImageDraw.Draw(image) -color = 'rgb(0, 0, 0)' # black color -draw.text((300,100), post.caption.encode('latin1', errors='ignore'), fill=color) - -# Save image -image.save('test.jpg') diff --git a/docs/codesnippets/120_ghost_followers.py b/docs/codesnippets/120_ghost_followers.py index bab2076..fb0a555 100644 --- a/docs/codesnippets/120_ghost_followers.py +++ b/docs/codesnippets/120_ghost_followers.py @@ -2,26 +2,26 @@ import instaloader L = instaloader.Instaloader() -USER = 'your_account' +USER = "your_account" PROFILE = USER -# Your preferred way of logging in: +# Load session previously saved with `instaloader -l USERNAME`: L.load_session_from_file(USER) profile = instaloader.Profile.from_username(L.context, PROFILE) likes = set() -print('Fetching likes of all posts of profile {}.'.format(profile.username)) +print("Fetching likes of all posts of profile {}.".format(profile.username)) for post in profile.get_posts(): print(post) likes = likes | set(post.get_likes()) -print('Fetching followers of profile {}.'.format(profile.username)) +print("Fetching followers of profile {}.".format(profile.username)) followers = set(profile.get_followers()) ghosts = followers - likes -print('Storing ghosts into file.') -with open('/YOUR PATH/inactive-users.txt', 'w') as f: +print("Storing ghosts into file.") +with open("inactive-users.txt", 'w') as f: for ghost in ghosts: print(ghost.username, file=f) diff --git a/docs/codesnippets/666_historical_hashtag_data.py b/docs/codesnippets/666_historical_hashtag_data.py index 8889937..8b9f0fe 100644 --- a/docs/codesnippets/666_historical_hashtag_data.py +++ b/docs/codesnippets/666_historical_hashtag_data.py @@ -9,7 +9,7 @@ SINCE = datetime(2020, 5, 10) # further from today, inclusive UNTIL = datetime(2020, 5, 11) # closer to today, not inclusive k = 0 # initiate k -k_list = [] # uncomment this to tune k +#k_list = [] # uncomment this to tune k for post in posts: postdate = post.date @@ -24,7 +24,8 @@ for post in posts: continue else: L.download_post(post, "#urbanphotography") - k = 0 # set k to 0 # if you want to tune k, uncomment below to get your k max #k_list.append(k) + k = 0 # set k to 0 + #max(k_list) diff --git a/docs/installation.rst b/docs/installation.rst index f7e7433..d27f268 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -5,27 +5,27 @@ Install Instaloader .. highlight:: none -**To install Instaloader**, +To **install Instaloader**, #. Ensure that you have `Python `__, at least - version 3.5 and `pip `__ - installed + version 3.5, and `pip `__ + installed. #. Then, install Instaloader using:: pip3 install instaloader -**To upgrade Instaloader**, do:: +To **upgrade Instaloader** to its current version, do:: pip3 install --upgrade instaloader -**Alternative methods for installing Instaloader:** +**Alternative methods** for installing Instaloader: - If you do not want to use pip, even though it is highly recommended, and prefer to **install Instaloader manually**, `Download the Source `__, - extract the Zip or Tarball and execute ``instaloader.py`` from there. + extract the Zip or Tarball and run ``setup.py`` from there. - On **Arch Linux**, you may install Instaloader using the `Instaloader AUR package `__. @@ -33,6 +33,6 @@ Install Instaloader - On **Windows 10**, you may download the standalone executable from the `current release page `__. -- To test the most current pre-release or development version of Instaloader:: +- To test the most current **pre-release** version of Instaloader:: pip3 install --pre instaloader diff --git a/docs/troubleshooting.rst b/docs/troubleshooting.rst index c4413a0..861e5ca 100644 --- a/docs/troubleshooting.rst +++ b/docs/troubleshooting.rst @@ -5,8 +5,8 @@ Troubleshooting .. highlight:: python -429 - Too Many Requests ------------------------ +429 Too Many Requests +--------------------- Instaloader has a logic to keep track of its requests to Instagram and to obey their rate limits. Since they are nowhere documented, we try them out @@ -14,17 +14,17 @@ experimentally. We have a daily cron job running to confirm that Instaloader still stays within the rate limits. Nevertheless, the rate control logic assumes that -- at one time, Instaloader is the only application that consumes requests. I.e. +- at one time, Instaloader is the only application that consumes requests, i.e. neither the Instagram browser interface, nor a mobile app, nor another - Instaloader instance is running in parallel, + Instaloader instance is running in parallel, and - no requests had been consumed when Instaloader starts. The latter one implies that restarting or reinstantiating Instaloader often -within short time is prone to cause a 429. When a request is denied with a 429, +within short time is prone to cause a 429. If a request is denied with a 429, Instaloader retries the request as soon as the temporary ban is assumed to be expired. In case the retry continuously fails for some reason, which should not -happen in normal conditions, consider adjusting the +happen under normal conditions, consider adjusting the :option:`--max-connection-attempts` option. There have been observations that services, that in their nature offer @@ -46,7 +46,7 @@ Private but not followed You have to follow a private account to access most of its associated information. -Login Error +Login error ----------- Instaloader's login *should* work fine, both with and without @@ -55,13 +55,13 @@ issued when Instagram suspects authentication activity on your account, by pointing the user to an URL to be opened in a browser. Nevertheless, in :issue:`92` and :issue:`615` users reported problems with -logging in. We recommend to always keep the sessionfile which Instaloader -creates when using :option:`--login`. If a sessionfile is present, +logging in. We recommend to always keep the session file which Instaloader +creates when using :option:`--login`. If a session file is present, :option:`--login` does not make make use of the failure-prone login procedure. Also, session files usually do not expire and can be copied between different computers without any problems. -If you do not have a sessionfile present, you may use the following script +If you do not have a session file present, you may use the following script (:example:`615_import_firefox_session.py`) to workaround login problems by importing the session cookies from Firefox and bypassing Instaloader's login and so still use Instaloader's logged-in functionality. @@ -80,5 +80,5 @@ To use this script, This script also supports specifying a cookie file path, which may be useful if you use multiple Firefox profiles or if your operating system has the directory -structure differently set up. Also, you can specify an alternative sessionfile +structure differently set up. Also, you can specify an alternative session file path.