mirror of
https://github.com/instaloader/instaloader.git
synced 2026-10-19 23:22:16 -07:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
03aabc52bb | ||
|
|
9d4df0d5fb | ||
|
|
bf2f4f16ed | ||
|
|
1a3712d112 | ||
|
|
65462b01ec | ||
|
|
9857c5fa24 |
@@ -1,7 +1,7 @@
|
|||||||
"""Download pictures (or videos) along with their captions and other metadata from Instagram."""
|
"""Download pictures (or videos) along with their captions and other metadata from Instagram."""
|
||||||
|
|
||||||
|
|
||||||
__version__ = '4.4'
|
__version__ = '4.4.3'
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ def _main(instaloader: Instaloader, targetlist: List[str],
|
|||||||
for followee in profile.get_followees():
|
for followee in profile.get_followees():
|
||||||
instaloader.save_profile_id(followee)
|
instaloader.save_profile_id(followee)
|
||||||
profiles.add(followee)
|
profiles.add(followee)
|
||||||
elif re.match(r"^#[A-Za-z0-9]+$", target):
|
elif re.match(r"^#\w+$", target):
|
||||||
instaloader.download_hashtag(hashtag=target[1:], max_count=max_count, fast_update=fast_update,
|
instaloader.download_hashtag(hashtag=target[1:], max_count=max_count, fast_update=fast_update,
|
||||||
post_filter=post_filter,
|
post_filter=post_filter,
|
||||||
profile_pic=download_profile_pic, posts=download_posts)
|
profile_pic=download_profile_pic, posts=download_posts)
|
||||||
|
|||||||
+14
-13
@@ -103,22 +103,20 @@ class _ArbitraryItemFormatter(string.Formatter):
|
|||||||
|
|
||||||
|
|
||||||
class _PostPathFormatter(_ArbitraryItemFormatter):
|
class _PostPathFormatter(_ArbitraryItemFormatter):
|
||||||
def vformat(self, format_string, args, kwargs):
|
|
||||||
"""Override :meth:`string.Formatter.vformat` for character substitution in paths for Windows, see issue #84."""
|
|
||||||
ret = super().vformat(format_string, args, kwargs)
|
|
||||||
if platform.system() == 'Windows':
|
|
||||||
ret = ret.replace(':', '\ua789').replace('<', '\ufe64').replace('>', '\ufe65').replace('\"', '\uff02')
|
|
||||||
ret = ret.replace('\\', '\ufe68').replace('|', '\uff5c').replace('?', '\ufe16').replace('*', '\uff0a')
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def get_value(self, key, args, kwargs):
|
def get_value(self, key, args, kwargs):
|
||||||
"""Replaces '/' with similar looking Division Slash and on windows newline with space"""
|
|
||||||
ret = super().get_value(key, args, kwargs)
|
ret = super().get_value(key, args, kwargs)
|
||||||
if not isinstance(ret, str):
|
if not isinstance(ret, str):
|
||||||
return ret
|
return ret
|
||||||
|
return self.sanitize_path(ret)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def sanitize_path(ret: str) -> str:
|
||||||
|
"""Replaces '/' with similar looking Division Slash and some other illegal filename characters on Windows."""
|
||||||
ret = ret.replace('/', '\u2215')
|
ret = ret.replace('/', '\u2215')
|
||||||
if platform.system() == 'Windows':
|
if platform.system() == 'Windows':
|
||||||
ret = ret.replace('\n', ' ')
|
ret = ret.replace(':', '\uff1a').replace('<', '\ufe64').replace('>', '\ufe65').replace('\"', '\uff02')
|
||||||
|
ret = ret.replace('\\', '\ufe68').replace('|', '\uff5c').replace('?', '\ufe16').replace('*', '\uff0a')
|
||||||
|
ret = ret.replace('\n', ' ').replace('\r', ' ')
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
@@ -681,7 +679,8 @@ class Instaloader:
|
|||||||
name = user_highlight.owner_username
|
name = user_highlight.owner_username
|
||||||
highlight_target = (filename_target
|
highlight_target = (filename_target
|
||||||
if filename_target
|
if filename_target
|
||||||
else Path(name) / Path(user_highlight.title)) # type: Union[str, Path]
|
else (Path(_PostPathFormatter.sanitize_path(name)) /
|
||||||
|
_PostPathFormatter.sanitize_path(user_highlight.title))) # type: Union[str, Path]
|
||||||
self.context.log("Retrieving highlights \"{}\" from profile {}".format(user_highlight.title, name))
|
self.context.log("Retrieving highlights \"{}\" from profile {}".format(user_highlight.title, name))
|
||||||
self.download_highlight_cover(user_highlight, highlight_target)
|
self.download_highlight_cover(user_highlight, highlight_target)
|
||||||
totalcount = user_highlight.itemcount
|
totalcount = user_highlight.itemcount
|
||||||
@@ -942,8 +941,10 @@ class Instaloader:
|
|||||||
.. versionadded:: 4.1"""
|
.. versionadded:: 4.1"""
|
||||||
self.context.log("Retrieving tagged posts for profile {}.".format(profile.username))
|
self.context.log("Retrieving tagged posts for profile {}.".format(profile.username))
|
||||||
self.posts_download_loop(profile.get_tagged_posts(),
|
self.posts_download_loop(profile.get_tagged_posts(),
|
||||||
target if target else Path(profile.username) / Path(':tagged'), fast_update,
|
target if target
|
||||||
post_filter)
|
else (Path(_PostPathFormatter.sanitize_path(profile.username)) /
|
||||||
|
_PostPathFormatter.sanitize_path(':tagged')),
|
||||||
|
fast_update, post_filter)
|
||||||
|
|
||||||
def download_igtv(self, profile: Profile, fast_update: bool = False,
|
def download_igtv(self, profile: Profile, fast_update: bool = False,
|
||||||
post_filter: Optional[Callable[[Post], bool]] = None) -> None:
|
post_filter: Optional[Callable[[Post], bool]] = None) -> None:
|
||||||
|
|||||||
@@ -215,8 +215,11 @@ class InstaloaderContext:
|
|||||||
session.headers.update({'X-CSRFToken': csrf_token})
|
session.headers.update({'X-CSRFToken': csrf_token})
|
||||||
# Not using self.get_json() here, because we need to access csrftoken cookie
|
# Not using self.get_json() here, because we need to access csrftoken cookie
|
||||||
self.do_sleep()
|
self.do_sleep()
|
||||||
|
# Workaround credits to pgrimaud.
|
||||||
|
# See: https://github.com/pgrimaud/instagram-user-feed/commit/96ad4cf54d1ad331b337f325c73e664999a6d066
|
||||||
|
enc_password = '#PWD_INSTAGRAM_BROWSER:0:{}:{}'.format(int(datetime.now().timestamp()), passwd)
|
||||||
login = session.post('https://www.instagram.com/accounts/login/ajax/',
|
login = session.post('https://www.instagram.com/accounts/login/ajax/',
|
||||||
data={'password': passwd, 'username': user}, allow_redirects=True)
|
data={'enc_password': enc_password, 'username': user}, allow_redirects=True)
|
||||||
try:
|
try:
|
||||||
resp_json = login.json()
|
resp_json = login.json()
|
||||||
except json.decoder.JSONDecodeError:
|
except json.decoder.JSONDecodeError:
|
||||||
|
|||||||
Reference in New Issue
Block a user