0

For learning purposes I'm trying to reproduce Instagram internal API with Ruby and Faraday. However, the response's body I get when making a POST is somehow encoded instead of JSON:

What the response's body should look like:

{
  "status": "ok",
  "media": {
    "page_info": {
      "start_cursor": "1447303180937779444_4460593680",
      "has_next_page": true,
      "end_cursor": "1447303180937779444",
      "has_previous_page": true
    },
...

What I get:

#=> \x1F\x8B\b\x00#\x15\x9EX\x02\xFF...

Question:

Any idea (i) why I'm getting a response's body like that and (ii) how can I convert that to JSON?


Flow:

When you hit https://www.instagram.com/explore/locations/127963847/madrid-spain/ in your browser Instagram makes two requests (among others):

  1. GET: https://www.instagram.com/explore/locations/127963847/madrid-spain/
  2. POST: https://www.instagram.com/query/

I used Postman to intercept requests and just copied headers and parameters for the second (/query/) request. This is my implementation (get status '200'):

class IcTest
  require 'open-uri'
  require "net/http"
  require "uri"

  def self.faraday
    conn = Faraday.new(:url => 'https://www.instagram.com') do |faraday|
      faraday.request  :url_encoded             # form-encode POST params
      faraday.response :logger                  # log requests to STDOUT
      faraday.adapter  Faraday.default_adapter  # make requests with Net::HTTP
    end

    res = conn.post do |req|
      req.url '/query/'
      req.headers['Origin'] = 'https://www.instagram.com'
      req.headers['X-Instagram-AJAX'] = '1'
      req.headers['User-Agent'] = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36'
      req.headers['Content-Type'] = 'application/x-www-form-urlencoded'
      # req.headers['Accept'] = '*/*'
      req.headers['X-Requested-With'] = 'XMLHttpRequest'
      req.headers['X-CSRFToken'] = 'SrxvROytxQHAesy1XcgcM2PWrEHHuQnD'
      req.headers['Referer'] = 'https://www.instagram.com/explore/locations/127963847/madrid-spain/'
      req.headers['Accept-Encoding'] = 'gzip, deflate, br'
      req.headers['Accept-Language'] = 'es,en;q=0.8,gl;q=0.6,pt;q=0.4,pl;q=0.2'
      req.headers['Cookie'] = 'mid=SJt50gAEAAE6KZ50GByVoStJKLUH; sessionid=IGSC514a2e9015f548b09176228f83ad5fe716f32e7143f6fe710c19a71c08b9828b%3Apc2KPxgwvokLyZhfZHcO1Qzfb2mpykG8%3A%7B%22_token%22%3A%2233263701%3Ai7HSIbxIMLj70AoUrCRjd0o1g7egHg79%3Acde5fe679ed6d86011d70b7291901998b8aae7d0aaaccdf02a2c5abeeaeb5908%22%2C%22asns%22%3A%7B%2283.34.38.249%22%3A3352%2C%22time%22%3A1486584547%7D%2C%22last_refreshed%22%3A1436584547.2838287%2C%22_platform%22%3A4%2C%22_token_ver%22%3A2%2C%22_auth_user_backend%22%3A%22accounts.backends.CaseInsensitiveModelBackend%22%2C%22_auth_user_id%22%3A33233701%2C%22_auth_user_hash%22%3A%22%22%7D; ds_user_id=31263701; csrftoken=sxvROytxQHAesy1XcgcM2PWrEHHuQnD; s_network=""; ig_vw=1440; ig_pr=2;'

      req.body = { :q => "ig_location(127963847) { media.after('', 60) {  count,  nodes {    caption,    code,    comments {      count    },    comments_disabled,    date,    dimensions {      height,      width    },    display_src,    id,    is_video,    likes {      count    },    owner {      id    },    thumbnail_src,    video_views  },  page_info} }",
                   :ref => "locations::show",
                   :query_id => "" }
    end
  end

Thanks.

borjagvo
  • 1,802
  • 2
  • 20
  • 35

1 Answers1

0

Josh comment made it! :-)

The body's content was gzip.

Solution here.

borjagvo
  • 1,802
  • 2
  • 20
  • 35