Packages

Instagram JSON and HTML endpoints without a API key, inspired on InstaScrapex

Current section

Files

Jump to
insta_insta lib insta_insta.ex
Raw

lib/insta_insta.ex

defmodule InstaInsta do
use HTTPoison.Base
# Date Limiter
# Pages Limiter
# Rows Limiter
# ID's manager
@doc """
Use this function to generate the right url
"""
def generate_url(type, params \\ nil)
# User Profile
# URL => https://www.instagram.com/#{username}/?__a=1
def generate_url("user_profile", %{username: username}),
do: "https://www.instagram.com/#{username}/"
# User Media
# URL => https://instagram.com/graphql/query/?query_id=17888483320059182&id=#{user_id}&first=#{count}&after=#{end_cursor}
# URL2 => https://www.instagram.com/graphql/query/?query_hash=472f257a40c653c64c666ce877d59d2b&variables={"id":"#{user_id}","first":#{count},"after":"#{end_cursor}"}
def generate_url("user_media", %{
user_id: user_id,
count: count,
end_cursor: end_cursor
}),
do:
"https://www.instagram.com/graphql/query/?query_id=17888483320059182&id=#{user_id}&first=#{
count
}&after=#{end_cursor}"
# Search by Tag
# URL => https://www.instagram.com/explore/tags/#{tag}/?__a=1&max_id=#{max_id}
def generate_url("search_by_tag", %{tag: tag, max_id: max_id}),
do: "https://www.instagram.com/explore/tags/#{tag}/?__a=1&max_id=#{max_id}"
# Search by Location
# URL => https://www.instagram.com/explore/locations/#{location_id}/?__a=1&max_id=#{max_id}
def generate_url("search_by_location", %{location_id: location_id, max_id: max_id}),
do: "https://www.instagram.com/explore/locations/#{location_id}/?__a=1&max_id=#{max_id}"
# General User Search
# URL => https://www.instagram.com/web/search/topsearch/?query=#{query}&context=#{context ex:blended}&rank_token=#{rank_token ex:0.4948977584648091}
def generate_url("search_user", %{
query: query,
context: context,
rank_token: rank_token
}),
do:
"https://www.instagram.com/web/search/topsearch/?query=#{query}&context=#{context}&rank_token=#{
rank_token
}"
# Media Info
# URL => https://www.instagram.com/p/#{media_code}/?__a=1
def generate_url("media_info", %{media_code: media_code}),
do: "https://www.instagram.com/p/#{media_code}/?__a=1"
# Media Comments
# URL => https://www.instagram.com/graphql/query/?query_id=17852405266163336&shortcode=#{shortcode}&first=#{count}&after=#{end_cursor}
# URL2 => https://www.instagram.com/graphql/query/?query_hash=33ba35852cb50da46f5b5e889df7d159&variables={"shortcode":"#{shortcode}","first":#{count},"after":"#{end_cursor}"}
def generate_url("media_comments", %{
shortcode: shortcode,
count: count,
end_cursor: end_cursor
}),
do:
"https://www.instagram.com/graphql/query/?query_id=17852405266163336&shortcode=#{
shortcode
}&first=#{count}&after=#{end_cursor}"
# Media Likes
# URL => https://www.instagram.com/graphql/query/?query_id=17864450716183058&shortcode=#{shortcode}&first=#{count}&after=#{end_cursor}
# URL2 => https://www.instagram.com/graphql/query/?query_hash=1cb6ec562846122743b61e492c85999f&variables={"shortcode":"#{shortcode}","first":#{count},"after":"#{end_cursor}"}
def generate_url("media_likes", %{
shortcode: shortcode,
count: count,
end_cursor: end_cursor
}),
do:
"https://www.instagram.com/graphql/query/?query_id=17864450716183058&shortcode=#{
shortcode
}&first=#{count}&after=#{end_cursor}"
# Followers List
# URL => https://instagram.com/graphql/query/?query_id=17851374694183129&id=#{user_id}&first=#{count}&after=#{end_cursor}
# URL2 => https://www.instagram.com/graphql/query/?query_hash=37479f2b8209594dde7facb0d904896a&variables={"id":"#{user_id}","first":#{count},"after":"#{end_cursor}"}
def generate_url("followers_list", %{
user_id: user_id,
count: count,
end_cursor: end_cursor
}),
do:
"https://www.instagram.com/graphql/query/?query_id=17851374694183129&id=#{user_id}&first=#{
count
}&after=#{end_cursor}"
# Following List
# URL => https://instagram.com/graphql/query/?query_id=17874545323001329&id=#{user_id}&first=#{count}&after=#{end_cursor}
# URL2 => https://www.instagram.com/graphql/query/?query_hash=58712303d941c6855d4e888c5f0cd22f&variables={"id":"#{user_id}","first":#{count},"after":"#{end_cursor}"}
def generate_url("following_list", %{
user_id: user_id,
count: count,
end_cursor: end_cursor
}),
do:
"https://www.instagram.com/graphql/query/?query_id=17874545323001329&id=#{user_id}&first=#{
count
}&after=#{end_cursor}"
def user_profile(username) do
http_response = run("user_profile", %{username: username})
Regex.scan(~r/(?<=\window._sharedData =)(.*\n?)(?=;<\/script>)/, http_response.body)
|> List.first()
|> List.first()
end
def user_media(user_id, count, end_cursor \\ ""),
do:
run(
"user_media",
%{
user_id: user_id,
count: count,
end_cursor: end_cursor
},
fake_headers(true)
)
def search_by_tag(tag, max_id \\ ""),
do: run("search_by_tag", %{tag: tag, max_id: max_id}, fake_headers(true))
def search_by_location(location_id, max_id \\ ""),
do: run("search_by_location", %{location_id: location_id, max_id: max_id}, fake_headers(true))
def search_user(query, context \\ "blended", rank_token \\ 0.4948977584648091),
do:
run("search_user", %{
query: query,
context: context,
rank_token: rank_token
})
def media_info(media_code), do: run("media_info", %{media_code: media_code})
def media_comments(shortcode, count, end_cursor \\ ""),
do:
run(
"media_comments",
%{
shortcode: shortcode,
count: count,
end_cursor: end_cursor
},
fake_headers(true)
)
def media_likes(shortcode, count, end_cursor \\ ""),
do:
run(
"media_likes",
%{
shortcode: shortcode,
count: count,
end_cursor: end_cursor
},
fake_headers(true)
)
def followers_list(user_id, count, end_cursor \\ ""),
do:
run(
"followers_list",
%{
user_id: user_id,
count: count,
end_cursor: end_cursor
},
fake_headers(true)
)
def following_list(user_id, count, end_cursor \\ ""),
do:
run(
"following_list",
%{
user_id: user_id,
count: count,
end_cursor: end_cursor
},
fake_headers(true)
)
@doc false
defp run(type, params, headers \\ fake_headers(), options \\ []) do
generate_url(type, params)
|> get!(headers, options)
end
defp post_login(%{username: username, password: password}) do
login_body = "username=#{username}&password=#{password}"
HTTPoison.post(
"https://www.instagram.com/accounts/login/ajax/",
login_body,
fake_headers()
)
end
def get_cookies(username, password) do
{:ok, headers} = post_login(%{username: username, password: password})
cookies =
Enum.filter(headers.headers, fn
{"Set-Cookie", _} -> true
_ -> false
end)
|> Enum.map(fn x -> Enum.at(String.split(elem(x, 1), ";"), 0) end)
|> Enum.join("; ")
cookies
end
defp fake_headers(get_cookies \\ nil) do
random = random_string()
if get_cookies do
cookies =
get_cookies(
Application.get_env(:insta_insta, :username),
Application.get_env(:insta_insta, :password)
)
else
cookies = "csrftoken=#{random};"
end
[
"content-type": "application/x-www-form-urlencoded",
"X-CSRFToken": random,
cookie: cookies,
Referer: "https://www.instagram.com/",
"x-instagram-ajax": "1",
"x-requested-with": "XMLHttpRequest"
]
end
defp random_string(length \\ 10) do
:crypto.strong_rand_bytes(length)
|> Base.url_encode64()
|> binary_part(0, length)
|> String.replace(~r/[_-]/, "a")
end
end