Search code examples
pythonparsingpython-requestsinstagram-api

WEIRD "json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)"


The problem: when i try to use the first code below, i got json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0). All that code worked fine yesterday and also yesterday it stopped working. Today it's not working too. The strange part that i just launched second code (also below) and it worked once and then after another launch it got the same problem again!

The error is thrown by the line:

post_info = instagram_web_api.media_info2("<SHORTCODE>")

Please, help : (. Russian stack overflow has no answers.

I use instagram-private-api 1.6.0.0

1-st code when i get that error:

from instagram_web_api import Client

instagram_web_api = Client(auto_patch=False, drop_incompat_keys=False)

post_info = instagram_web_api.media_info2('CVNgb7us34V') # Get the short code.
post_text = post_info['edge_media_to_caption']['edges'][0]['node']['text']

print(post_text)

2-nd code:

from instagram_web_api import Client

web_api = Client(auto_patch=False, drop_incompat_keys=False)
user_feed_info = web_api.user_feed('329452045', count=10)

enter image description here


Solution

  • The problem is between the library you are using and instagram: the latter is not sending you JSON where you expect it.

    If you have a look at the source for media_info2 it looks like this:

    def media_info2(self, short_code):
        """
        Alternative method to get media info. This method works for carousel media.
    
        :param short_code: A media's shortcode
        :param kwargs:
        :return:
        """
        headers = {
            'User-Agent': self.user_agent,
            'Accept': '*/*',
            'Accept-Language': 'en-US',
            'Accept-Encoding': 'gzip, deflate',
            'Connection': 'close',
            'Referer': 'https://www.instagram.com',
            'x-requested-with': 'XMLHttpRequest',
        }
        info = self._make_request(
            'https://www.instagram.com/p/{0!s}/'.format(short_code),
            query={'__a': '1', '__b': '1'},
            headers=headers)
        ...
    

    Following your traceback, the error is in make_request. So we go and look at the source and we see that the important lines are:

    self.logger.debug('REQ DATA: {0!s}'.format(data))
    res = self.opener.open(req, data=data, timeout=self.timeout)
    ...
    
    if return_response:
        return res
    response_content = self._read_response(res)
        self.logger.debug('RES BODY: {0!s}'.format(response_content))
        return json.loads(response_content)
    

    We now have everything we would need to do a bit of manual debugging, since the program works like this:

    • set headers and pass them and url to make_request
    • get data from url
    • parse date as json
    • return data

    We could put together our own call to opener, or even just run curl on the url passed to _make_request, or temporarily modify the code to print some stuff and be a bit more verbose. But in this case we have an even easier option: the code will already debug itself for us, we just have to tell it to be verbose:

    import logging
    logging.basic_config(level=logging.DEBUG)
    

    Put that at the top of your failing script and run it again, and it should spew out lots of data telling you exactly what it's doing. Since it prints the entire return body, you should get whatever it's returning, and be able to figure out what's going on.

    And remember.... use the source, Luke.

    Alright, that was awful, but the only way to know what code is doing is to read the source. The great thing about python is its readability. Compare this to trying to figure out some c++ library by reading it...