We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Error when image has no caption
I got this.

> Traceback (most recent call last):
>   File ".\quickstart.py", line 23, in <module>
>     .like_by_tags(['landscape'], amount=97) \
>   File "C:\Users\em\Desktop\InstaPy-master\instapy\instapy.py", line 271, in like_by_tags
>     self.username, self.like_by_followers_upper_limit, self.like_by_followers_lower_limit)
>   File "C:\Users\em\Desktop\InstaPy-master\instapy\like_util.py", line 144, in check_link
>     image_text = image_text[0]['nodes']['text'] if image_text else None
> KeyError: 'nodes'

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `instapy/like_util.py`
Content:
```
1 """Module that handles the like features"""
2 from math import ceil
3 from re import findall
4 from selenium.webdriver.common.keys import Keys
5 
6 from .time_util import sleep
7 
8 
9 def get_links_for_tag(browser, tag, amount, media=None):
10   """Fetches the number of links specified
11   by amount and returns a list of links"""
12   if media is None:
13     # All known media types
14     media = ['', 'Post', 'Video']
15   elif media == 'Photo':
16     # Include posts with multiple images in it
17     media = ['', 'Post']
18   else:
19     # Make it an array to use it in the following part
20     media = [media]
21 
22   browser.get('https://www.instagram.com/explore/tags/'
23               + (tag[1:] if tag[:1] == '#' else tag))
24   sleep(2)
25 
26   # clicking load more
27   body_elem = browser.find_element_by_tag_name('body')
28   sleep(2)
29 
30   abort = True
31   try:
32     load_button = body_elem.find_element_by_xpath \
33       ('//a[contains(@class, "_8imhp _glz1g")]')
34   except:
35     print('Load button not found, working with current images!')
36   else:
37     abort = False
38     body_elem.send_keys(Keys.END)
39     sleep(2)
40     load_button.click()
41 
42   body_elem.send_keys(Keys.HOME)
43   sleep(1)
44 
45   # Get links
46   main_elem = browser.find_element_by_tag_name('main')
47   link_elems = main_elem.find_elements_by_tag_name('a')
48   total_links = len(link_elems)
49   links = [link_elem.get_attribute('href') for link_elem in link_elems
50            if link_elem.text in media]
51   filtered_links = len(links)
52 
53   while (filtered_links < amount) and not abort:
54     amount_left = amount - filtered_links
55     # Average items of the right media per page loaded
56     new_per_page = ceil(12 * filtered_links / total_links)
57     if new_per_page == 0:
58       # Avoid division by zero
59       new_per_page = 1. / 12.
60     # Number of page load needed
61     new_needed = int(ceil(amount_left / new_per_page))
62 
63     if new_needed > 12:
64       # Don't go bananas trying to get all of instagram!
65       new_needed = 12
66 
67     for i in range(new_needed):  # add images x * 12
68       # Keep the latest window active while loading more posts
69       before_load = total_links
70       browser.switch_to.window(browser.window_handles[-1])
71       body_elem.send_keys(Keys.END)
72       sleep(1)
73       browser.switch_to.window(browser.window_handles[-1])
74       body_elem.send_keys(Keys.HOME)
75       sleep(1)
76       link_elems = main_elem.find_elements_by_tag_name('a')
77       total_links = len(link_elems)
78       abort = (before_load == total_links)
79       if abort:
80         break
81 
82     links = [link_elem.get_attribute('href') for link_elem in link_elems
83              if link_elem.text in media]
84     filtered_links = len(links)
85 
86   return links[:amount]
87 
88 def check_link(browser, link, dont_like, ignore_if_contains, ignore_users,
89                username, like_by_followers_upper_limit, like_by_followers_lower_limit):
90   browser.get(link)
91   sleep(2)
92 
93   """Check if the Post is Valid/Exists"""
94   post_page = browser.execute_script("return window._sharedData.entry_data.PostPage")
95   if post_page is None:
96     print('Unavailable Page: {}'.format(link.encode('utf-8')))
97     return True, None, None, 'Unavailable Page'
98 
99   """Gets the description of the link and checks for the dont_like tags"""
100   graphql = 'graphql' in post_page[0]
101   if graphql:
102     media = post_page[0]['graphql']['shortcode_media']
103     is_video = media['is_video']
104     user_name = media['owner']['username']
105     image_text = media['edge_media_to_caption']['edges']
106     image_text = image_text[0]['node']['text'] if image_text else None
107     owner_comments = browser.execute_script('''
108       latest_comments = window._sharedData.entry_data.PostPage[0].graphql.shortcode_media.edge_media_to_comment.edges;
109       if (latest_comments === undefined) latest_comments = Array();
110       owner_comments = latest_comments
111         .filter(item => item.node.owner.username == '{}')
112         .map(item => item.node.text)
113         .reduce((item, total) => item + '\\n' + total, '');
114       return owner_comments;
115     '''.format(user_name))
116   else:
117     media = post_page[0]['media']
118     is_video = media['is_video']
119     user_name = media['owner']['username']
120     image_text = media['caption']
121     owner_comments = browser.execute_script('''
122       latest_comments = window._sharedData.entry_data.PostPage[0].media.comments.nodes;
123       if (latest_comments === undefined) latest_comments = Array();
124       owner_comments = latest_comments
125         .filter(item => item.node.owner.username == '{}')
126         .map(item => item.text)
127         .reduce((item, total) => item + '\\n' + total, '');
128       return owner_comments;
129     '''.format(user_name))
130 
131   if owner_comments == '':
132     owner_comments = None
133 
134   """Append owner comments to description as it might contain further tags"""
135   if image_text is None:
136     image_text = owner_comments
137   elif owner_comments:
138     image_text = image_text + '\n' + owner_comments
139 
140   """If the image still has no description gets the first comment"""
141   if image_text is None:
142     if graphql:
143       image_text = media['edge_media_to_comment']['edges']
144       image_text = image_text[0]['nodes']['text'] if image_text else None
145     else:
146       image_text = media['comments']['nodes']
147       image_text = image_text[0]['text'] if image_text else None
148   if image_text is None:
149     image_text = "No description"
150 
151   print('Image from: {}'.format(user_name.encode('utf-8')))
152 
153   """Find the number of followes the user has"""
154   if like_by_followers_upper_limit or like_by_followers_lower_limit:
155     userlink = 'https://www.instagram.com/' + user_name
156     browser.get(userlink)
157     sleep(1)
158     num_followers = browser.execute_script("return window._sharedData.entry_data.ProfilePage[0].user.followed_by.count")
159     browser.get(link)
160     sleep(1)
161     print('Number of Followers: {}'.format(num_followers))
162 
163     if like_by_followers_upper_limit and num_followers > like_by_followers_upper_limit:
164       return True, user_name, is_video, 'Number of followers exceeds limit'
165     if like_by_followers_lower_limit and num_followers < like_by_followers_lower_limit:
166       return True, user_name, is_video, 'Number of followers does not reach minimum'
167     
168   print('Link: {}'.format(link.encode('utf-8')))
169   print('Description: {}'.format(image_text.encode('utf-8')))
170 
171   """Check if the user_name is in the ignore_users list"""
172   if (user_name in ignore_users) or (user_name == username):
173     return True, user_name, is_video, 'Username'
174 
175   if any((word in image_text for word in ignore_if_contains)):
176       return False, user_name, is_video, 'None'
177 
178   image_text = image_text.lower()
179   if any((tag.lower() in image_text for tag in dont_like)):
180       return True, user_name, is_video, 'Inappropriate'
181     
182   return False, user_name, is_video, 'None'
183 
184 
185 def like_image(browser):
186   """Likes the browser opened image"""
187   like_elem = browser.find_elements_by_xpath("//a[@role = 'button']/span[text()='Like']")
188   liked_elem = browser.find_elements_by_xpath("//a[@role = 'button']/span[text()='Unlike']")
189 
190   if len(like_elem) == 1:
191     browser.execute_script("document.getElementsByClassName('" + like_elem[0].get_attribute("class") + "')[0].click()")
192     print('--> Image Liked!')
193     sleep(2)
194     return True
195   elif len(liked_elem) == 1:
196     print('--> Already Liked!')
197     return False
198   else:
199     print('--> Invalid Like Element!')
200     return False
201 
202 
203 def get_tags(browser, url):
204   """Gets all the tags of the given description in the url"""
205   browser.get(url)
206   sleep(1)
207 
208   graphql = browser.execute_script("return ('graphql' in window._sharedData.entry_data.PostPage[0])")
209   if graphql:
210     image_text = browser.execute_script("return window._sharedData.entry_data.PostPage[0].graphql.shortcode_media.edge_media_to_caption.edges[0].node.text")
211   else:
212     image_text = browser.execute_script("return window._sharedData.entry_data.PostPage[0].media.caption.text")
213 
214   tags = findall(r'#\w*', image_text)
215   return tags
216
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/instapy/like_util.py b/instapy/like_util.py
--- a/instapy/like_util.py
+++ b/instapy/like_util.py
@@ -122,7 +122,7 @@
       latest_comments = window._sharedData.entry_data.PostPage[0].media.comments.nodes;
       if (latest_comments === undefined) latest_comments = Array();
       owner_comments = latest_comments
-        .filter(item => item.node.owner.username == '{}')
+        .filter(item => item.user.username == '{}')
         .map(item => item.text)
         .reduce((item, total) => item + '\\n' + total, '');
       return owner_comments;
@@ -141,7 +141,7 @@
   if image_text is None:
     if graphql:
       image_text = media['edge_media_to_comment']['edges']
-      image_text = image_text[0]['nodes']['text'] if image_text else None
+      image_text = image_text[0]['node']['text'] if image_text else None
     else:
       image_text = media['comments']['nodes']
       image_text = image_text[0]['text'] if image_text else None
@@ -164,7 +164,7 @@
       return True, user_name, is_video, 'Number of followers exceeds limit'
     if like_by_followers_lower_limit and num_followers < like_by_followers_lower_limit:
       return True, user_name, is_video, 'Number of followers does not reach minimum'
-    
+
   print('Link: {}'.format(link.encode('utf-8')))
   print('Description: {}'.format(image_text.encode('utf-8')))
 
@@ -178,7 +178,7 @@
   image_text = image_text.lower()
   if any((tag.lower() in image_text for tag in dont_like)):
       return True, user_name, is_video, 'Inappropriate'
-    
+
   return False, user_name, is_video, 'None'

{"golden_diff": "diff --git a/instapy/like_util.py b/instapy/like_util.py\n--- a/instapy/like_util.py\n+++ b/instapy/like_util.py\n@@ -122,7 +122,7 @@\n       latest_comments = window._sharedData.entry_data.PostPage[0].media.comments.nodes;\n       if (latest_comments === undefined) latest_comments = Array();\n       owner_comments = latest_comments\n-        .filter(item => item.node.owner.username == '{}')\n+        .filter(item => item.user.username == '{}')\n         .map(item => item.text)\n         .reduce((item, total) => item + '\\\\n' + total, '');\n       return owner_comments;\n@@ -141,7 +141,7 @@\n   if image_text is None:\n     if graphql:\n       image_text = media['edge_media_to_comment']['edges']\n-      image_text = image_text[0]['nodes']['text'] if image_text else None\n+      image_text = image_text[0]['node']['text'] if image_text else None\n     else:\n       image_text = media['comments']['nodes']\n       image_text = image_text[0]['text'] if image_text else None\n@@ -164,7 +164,7 @@\n       return True, user_name, is_video, 'Number of followers exceeds limit'\n     if like_by_followers_lower_limit and num_followers < like_by_followers_lower_limit:\n       return True, user_name, is_video, 'Number of followers does not reach minimum'\n-    \n+\n   print('Link: {}'.format(link.encode('utf-8')))\n   print('Description: {}'.format(image_text.encode('utf-8')))\n \n@@ -178,7 +178,7 @@\n   image_text = image_text.lower()\n   if any((tag.lower() in image_text for tag in dont_like)):\n       return True, user_name, is_video, 'Inappropriate'\n-    \n+\n   return False, user_name, is_video, 'None'\n", "issue": "Error when image has no caption\nI got this.\r\n\r\n> Traceback (most recent call last):\r\n>   File \".\\quickstart.py\", line 23, in <module>\r\n>     .like_by_tags(['landscape'], amount=97) \\\r\n>   File \"C:\\Users\\em\\Desktop\\InstaPy-master\\instapy\\instapy.py\", line 271, in like_by_tags\r\n>     self.username, self.like_by_followers_upper_limit, self.like_by_followers_lower_limit)\r\n>   File \"C:\\Users\\em\\Desktop\\InstaPy-master\\instapy\\like_util.py\", line 144, in check_link\r\n>     image_text = image_text[0]['nodes']['text'] if image_text else None\r\n> KeyError: 'nodes'\n", "before_files": [{"content": "\"\"\"Module that handles the like features\"\"\"\nfrom math import ceil\nfrom re import findall\nfrom selenium.webdriver.common.keys import Keys\n\nfrom .time_util import sleep\n\n\ndef get_links_for_tag(browser, tag, amount, media=None):\n  \"\"\"Fetches the number of links specified\n  by amount and returns a list of links\"\"\"\n  if media is None:\n    # All known media types\n    media = ['', 'Post', 'Video']\n  elif media == 'Photo':\n    # Include posts with multiple images in it\n    media = ['', 'Post']\n  else:\n    # Make it an array to use it in the following part\n    media = [media]\n\n  browser.get('https://www.instagram.com/explore/tags/'\n              + (tag[1:] if tag[:1] == '#' else tag))\n  sleep(2)\n\n  # clicking load more\n  body_elem = browser.find_element_by_tag_name('body')\n  sleep(2)\n\n  abort = True\n  try:\n    load_button = body_elem.find_element_by_xpath \\\n      ('//a[contains(@class, \"_8imhp _glz1g\")]')\n  except:\n    print('Load button not found, working with current images!')\n  else:\n    abort = False\n    body_elem.send_keys(Keys.END)\n    sleep(2)\n    load_button.click()\n\n  body_elem.send_keys(Keys.HOME)\n  sleep(1)\n\n  # Get links\n  main_elem = browser.find_element_by_tag_name('main')\n  link_elems = main_elem.find_elements_by_tag_name('a')\n  total_links = len(link_elems)\n  links = [link_elem.get_attribute('href') for link_elem in link_elems\n           if link_elem.text in media]\n  filtered_links = len(links)\n\n  while (filtered_links < amount) and not abort:\n    amount_left = amount - filtered_links\n    # Average items of the right media per page loaded\n    new_per_page = ceil(12 * filtered_links / total_links)\n    if new_per_page == 0:\n      # Avoid division by zero\n      new_per_page = 1. / 12.\n    # Number of page load needed\n    new_needed = int(ceil(amount_left / new_per_page))\n\n    if new_needed > 12:\n      # Don't go bananas trying to get all of instagram!\n      new_needed = 12\n\n    for i in range(new_needed):  # add images x * 12\n      # Keep the latest window active while loading more posts\n      before_load = total_links\n      browser.switch_to.window(browser.window_handles[-1])\n      body_elem.send_keys(Keys.END)\n      sleep(1)\n      browser.switch_to.window(browser.window_handles[-1])\n      body_elem.send_keys(Keys.HOME)\n      sleep(1)\n      link_elems = main_elem.find_elements_by_tag_name('a')\n      total_links = len(link_elems)\n      abort = (before_load == total_links)\n      if abort:\n        break\n\n    links = [link_elem.get_attribute('href') for link_elem in link_elems\n             if link_elem.text in media]\n    filtered_links = len(links)\n\n  return links[:amount]\n\ndef check_link(browser, link, dont_like, ignore_if_contains, ignore_users,\n               username, like_by_followers_upper_limit, like_by_followers_lower_limit):\n  browser.get(link)\n  sleep(2)\n\n  \"\"\"Check if the Post is Valid/Exists\"\"\"\n  post_page = browser.execute_script(\"return window._sharedData.entry_data.PostPage\")\n  if post_page is None:\n    print('Unavailable Page: {}'.format(link.encode('utf-8')))\n    return True, None, None, 'Unavailable Page'\n\n  \"\"\"Gets the description of the link and checks for the dont_like tags\"\"\"\n  graphql = 'graphql' in post_page[0]\n  if graphql:\n    media = post_page[0]['graphql']['shortcode_media']\n    is_video = media['is_video']\n    user_name = media['owner']['username']\n    image_text = media['edge_media_to_caption']['edges']\n    image_text = image_text[0]['node']['text'] if image_text else None\n    owner_comments = browser.execute_script('''\n      latest_comments = window._sharedData.entry_data.PostPage[0].graphql.shortcode_media.edge_media_to_comment.edges;\n      if (latest_comments === undefined) latest_comments = Array();\n      owner_comments = latest_comments\n        .filter(item => item.node.owner.username == '{}')\n        .map(item => item.node.text)\n        .reduce((item, total) => item + '\\\\n' + total, '');\n      return owner_comments;\n    '''.format(user_name))\n  else:\n    media = post_page[0]['media']\n    is_video = media['is_video']\n    user_name = media['owner']['username']\n    image_text = media['caption']\n    owner_comments = browser.execute_script('''\n      latest_comments = window._sharedData.entry_data.PostPage[0].media.comments.nodes;\n      if (latest_comments === undefined) latest_comments = Array();\n      owner_comments = latest_comments\n        .filter(item => item.node.owner.username == '{}')\n        .map(item => item.text)\n        .reduce((item, total) => item + '\\\\n' + total, '');\n      return owner_comments;\n    '''.format(user_name))\n\n  if owner_comments == '':\n    owner_comments = None\n\n  \"\"\"Append owner comments to description as it might contain further tags\"\"\"\n  if image_text is None:\n    image_text = owner_comments\n  elif owner_comments:\n    image_text = image_text + '\\n' + owner_comments\n\n  \"\"\"If the image still has no description gets the first comment\"\"\"\n  if image_text is None:\n    if graphql:\n      image_text = media['edge_media_to_comment']['edges']\n      image_text = image_text[0]['nodes']['text'] if image_text else None\n    else:\n      image_text = media['comments']['nodes']\n      image_text = image_text[0]['text'] if image_text else None\n  if image_text is None:\n    image_text = \"No description\"\n\n  print('Image from: {}'.format(user_name.encode('utf-8')))\n\n  \"\"\"Find the number of followes the user has\"\"\"\n  if like_by_followers_upper_limit or like_by_followers_lower_limit:\n    userlink = 'https://www.instagram.com/' + user_name\n    browser.get(userlink)\n    sleep(1)\n    num_followers = browser.execute_script(\"return window._sharedData.entry_data.ProfilePage[0].user.followed_by.count\")\n    browser.get(link)\n    sleep(1)\n    print('Number of Followers: {}'.format(num_followers))\n\n    if like_by_followers_upper_limit and num_followers > like_by_followers_upper_limit:\n      return True, user_name, is_video, 'Number of followers exceeds limit'\n    if like_by_followers_lower_limit and num_followers < like_by_followers_lower_limit:\n      return True, user_name, is_video, 'Number of followers does not reach minimum'\n    \n  print('Link: {}'.format(link.encode('utf-8')))\n  print('Description: {}'.format(image_text.encode('utf-8')))\n\n  \"\"\"Check if the user_name is in the ignore_users list\"\"\"\n  if (user_name in ignore_users) or (user_name == username):\n    return True, user_name, is_video, 'Username'\n\n  if any((word in image_text for word in ignore_if_contains)):\n      return False, user_name, is_video, 'None'\n\n  image_text = image_text.lower()\n  if any((tag.lower() in image_text for tag in dont_like)):\n      return True, user_name, is_video, 'Inappropriate'\n    \n  return False, user_name, is_video, 'None'\n\n\ndef like_image(browser):\n  \"\"\"Likes the browser opened image\"\"\"\n  like_elem = browser.find_elements_by_xpath(\"//a[@role = 'button']/span[text()='Like']\")\n  liked_elem = browser.find_elements_by_xpath(\"//a[@role = 'button']/span[text()='Unlike']\")\n\n  if len(like_elem) == 1:\n    browser.execute_script(\"document.getElementsByClassName('\" + like_elem[0].get_attribute(\"class\") + \"')[0].click()\")\n    print('--> Image Liked!')\n    sleep(2)\n    return True\n  elif len(liked_elem) == 1:\n    print('--> Already Liked!')\n    return False\n  else:\n    print('--> Invalid Like Element!')\n    return False\n\n\ndef get_tags(browser, url):\n  \"\"\"Gets all the tags of the given description in the url\"\"\"\n  browser.get(url)\n  sleep(1)\n\n  graphql = browser.execute_script(\"return ('graphql' in window._sharedData.entry_data.PostPage[0])\")\n  if graphql:\n    image_text = browser.execute_script(\"return window._sharedData.entry_data.PostPage[0].graphql.shortcode_media.edge_media_to_caption.edges[0].node.text\")\n  else:\n    image_text = browser.execute_script(\"return window._sharedData.entry_data.PostPage[0].media.caption.text\")\n\n  tags = findall(r'#\\w*', image_text)\n  return tags\n", "path": "instapy/like_util.py"}], "after_files": [{"content": "\"\"\"Module that handles the like features\"\"\"\nfrom math import ceil\nfrom re import findall\nfrom selenium.webdriver.common.keys import Keys\n\nfrom .time_util import sleep\n\n\ndef get_links_for_tag(browser, tag, amount, media=None):\n  \"\"\"Fetches the number of links specified\n  by amount and returns a list of links\"\"\"\n  if media is None:\n    # All known media types\n    media = ['', 'Post', 'Video']\n  elif media == 'Photo':\n    # Include posts with multiple images in it\n    media = ['', 'Post']\n  else:\n    # Make it an array to use it in the following part\n    media = [media]\n\n  browser.get('https://www.instagram.com/explore/tags/'\n              + (tag[1:] if tag[:1] == '#' else tag))\n  sleep(2)\n\n  # clicking load more\n  body_elem = browser.find_element_by_tag_name('body')\n  sleep(2)\n\n  abort = True\n  try:\n    load_button = body_elem.find_element_by_xpath \\\n      ('//a[contains(@class, \"_8imhp _glz1g\")]')\n  except:\n    print('Load button not found, working with current images!')\n  else:\n    abort = False\n    body_elem.send_keys(Keys.END)\n    sleep(2)\n    load_button.click()\n\n  body_elem.send_keys(Keys.HOME)\n  sleep(1)\n\n  # Get links\n  main_elem = browser.find_element_by_tag_name('main')\n  link_elems = main_elem.find_elements_by_tag_name('a')\n  total_links = len(link_elems)\n  links = [link_elem.get_attribute('href') for link_elem in link_elems\n           if link_elem.text in media]\n  filtered_links = len(links)\n\n  while (filtered_links < amount) and not abort:\n    amount_left = amount - filtered_links\n    # Average items of the right media per page loaded\n    new_per_page = ceil(12 * filtered_links / total_links)\n    if new_per_page == 0:\n      # Avoid division by zero\n      new_per_page = 1. / 12.\n    # Number of page load needed\n    new_needed = int(ceil(amount_left / new_per_page))\n\n    if new_needed > 12:\n      # Don't go bananas trying to get all of instagram!\n      new_needed = 12\n\n    for i in range(new_needed):  # add images x * 12\n      # Keep the latest window active while loading more posts\n      before_load = total_links\n      browser.switch_to.window(browser.window_handles[-1])\n      body_elem.send_keys(Keys.END)\n      sleep(1)\n      browser.switch_to.window(browser.window_handles[-1])\n      body_elem.send_keys(Keys.HOME)\n      sleep(1)\n      link_elems = main_elem.find_elements_by_tag_name('a')\n      total_links = len(link_elems)\n      abort = (before_load == total_links)\n      if abort:\n        break\n\n    links = [link_elem.get_attribute('href') for link_elem in link_elems\n             if link_elem.text in media]\n    filtered_links = len(links)\n\n  return links[:amount]\n\ndef check_link(browser, link, dont_like, ignore_if_contains, ignore_users,\n               username, like_by_followers_upper_limit, like_by_followers_lower_limit):\n  browser.get(link)\n  sleep(2)\n\n  \"\"\"Check if the Post is Valid/Exists\"\"\"\n  post_page = browser.execute_script(\"return window._sharedData.entry_data.PostPage\")\n  if post_page is None:\n    print('Unavailable Page: {}'.format(link.encode('utf-8')))\n    return True, None, None, 'Unavailable Page'\n\n  \"\"\"Gets the description of the link and checks for the dont_like tags\"\"\"\n  graphql = 'graphql' in post_page[0]\n  if graphql:\n    media = post_page[0]['graphql']['shortcode_media']\n    is_video = media['is_video']\n    user_name = media['owner']['username']\n    image_text = media['edge_media_to_caption']['edges']\n    image_text = image_text[0]['node']['text'] if image_text else None\n    owner_comments = browser.execute_script('''\n      latest_comments = window._sharedData.entry_data.PostPage[0].graphql.shortcode_media.edge_media_to_comment.edges;\n      if (latest_comments === undefined) latest_comments = Array();\n      owner_comments = latest_comments\n        .filter(item => item.node.owner.username == '{}')\n        .map(item => item.node.text)\n        .reduce((item, total) => item + '\\\\n' + total, '');\n      return owner_comments;\n    '''.format(user_name))\n  else:\n    media = post_page[0]['media']\n    is_video = media['is_video']\n    user_name = media['owner']['username']\n    image_text = media['caption']\n    owner_comments = browser.execute_script('''\n      latest_comments = window._sharedData.entry_data.PostPage[0].media.comments.nodes;\n      if (latest_comments === undefined) latest_comments = Array();\n      owner_comments = latest_comments\n        .filter(item => item.user.username == '{}')\n        .map(item => item.text)\n        .reduce((item, total) => item + '\\\\n' + total, '');\n      return owner_comments;\n    '''.format(user_name))\n\n  if owner_comments == '':\n    owner_comments = None\n\n  \"\"\"Append owner comments to description as it might contain further tags\"\"\"\n  if image_text is None:\n    image_text = owner_comments\n  elif owner_comments:\n    image_text = image_text + '\\n' + owner_comments\n\n  \"\"\"If the image still has no description gets the first comment\"\"\"\n  if image_text is None:\n    if graphql:\n      image_text = media['edge_media_to_comment']['edges']\n      image_text = image_text[0]['node']['text'] if image_text else None\n    else:\n      image_text = media['comments']['nodes']\n      image_text = image_text[0]['text'] if image_text else None\n  if image_text is None:\n    image_text = \"No description\"\n\n  print('Image from: {}'.format(user_name.encode('utf-8')))\n\n  \"\"\"Find the number of followes the user has\"\"\"\n  if like_by_followers_upper_limit or like_by_followers_lower_limit:\n    userlink = 'https://www.instagram.com/' + user_name\n    browser.get(userlink)\n    sleep(1)\n    num_followers = browser.execute_script(\"return window._sharedData.entry_data.ProfilePage[0].user.followed_by.count\")\n    browser.get(link)\n    sleep(1)\n    print('Number of Followers: {}'.format(num_followers))\n\n    if like_by_followers_upper_limit and num_followers > like_by_followers_upper_limit:\n      return True, user_name, is_video, 'Number of followers exceeds limit'\n    if like_by_followers_lower_limit and num_followers < like_by_followers_lower_limit:\n      return True, user_name, is_video, 'Number of followers does not reach minimum'\n\n  print('Link: {}'.format(link.encode('utf-8')))\n  print('Description: {}'.format(image_text.encode('utf-8')))\n\n  \"\"\"Check if the user_name is in the ignore_users list\"\"\"\n  if (user_name in ignore_users) or (user_name == username):\n    return True, user_name, is_video, 'Username'\n\n  if any((word in image_text for word in ignore_if_contains)):\n      return False, user_name, is_video, 'None'\n\n  image_text = image_text.lower()\n  if any((tag.lower() in image_text for tag in dont_like)):\n      return True, user_name, is_video, 'Inappropriate'\n\n  return False, user_name, is_video, 'None'\n\n\ndef like_image(browser):\n  \"\"\"Likes the browser opened image\"\"\"\n  like_elem = browser.find_elements_by_xpath(\"//a[@role = 'button']/span[text()='Like']\")\n  liked_elem = browser.find_elements_by_xpath(\"//a[@role = 'button']/span[text()='Unlike']\")\n\n  if len(like_elem) == 1:\n    browser.execute_script(\"document.getElementsByClassName('\" + like_elem[0].get_attribute(\"class\") + \"')[0].click()\")\n    print('--> Image Liked!')\n    sleep(2)\n    return True\n  elif len(liked_elem) == 1:\n    print('--> Already Liked!')\n    return False\n  else:\n    print('--> Invalid Like Element!')\n    return False\n\n\ndef get_tags(browser, url):\n  \"\"\"Gets all the tags of the given description in the url\"\"\"\n  browser.get(url)\n  sleep(1)\n\n  graphql = browser.execute_script(\"return ('graphql' in window._sharedData.entry_data.PostPage[0])\")\n  if graphql:\n    image_text = browser.execute_script(\"return window._sharedData.entry_data.PostPage[0].graphql.shortcode_media.edge_media_to_caption.edges[0].node.text\")\n  else:\n    image_text = browser.execute_script(\"return window._sharedData.entry_data.PostPage[0].media.caption.text\")\n\n  tags = findall(r'#\\w*', image_text)\n  return tags\n", "path": "instapy/like_util.py"}]}