사용자 인증없이 Instagram에서 사용자 미디어를 얻으려면 어떻게해야합니까?


175

사용자의 최근 Instagram 미디어를 사이드 바에 넣으려고합니다. Instagram API를 사용하여 미디어를 가져 오려고합니다.

http://instagram.com/developer/endpoints/users/

설명서에는 GET https://api.instagram.com/v1/users/<user-id>/media/recent/이 있지만 OAuth 액세스 토큰을 전달한다고 나와 있습니다. 액세스 토큰은 사용자를 대신하여 행동 할 수있는 권한을 나타냅니다. 사이드 바에서 이것을 볼 수 있도록 Instagram에 로그인하는 것을 원하지 않습니다. 인스 타 그램 계정이 없어도됩니다.

예를 들어, Instagram에 로그인하지 않고 http://instagram.com/thebrainscoop 로 이동하여 사진을 볼 수 있습니다. API를 통해 그렇게하고 싶습니다.

Instagram API에서 사용자 인증이 client_id아닌 요청은 대신을 전달 합니다 access_token. 그래도 시도하면 얻을 수 있습니다.

{
  "meta":{
    "error_type":"OAuthParameterException",
    "code":400,
    "error_message":"\"access_token\" URL parameter missing. This OAuth request requires an \"access_token\" URL parameter."
  }
}

그래서 이것이 불가능합니까? 사용자에게 먼저 OAuth를 통해 Instagram 계정에 로그인하도록 요청하지 않고 사용자의 최신 (공용) 미디어를 가져올 수있는 방법이 없습니까?


이 플러그인을 사용하면 사용자가 Instagram 계정에 로그인하도록 요청하지 않고 사용자의 최신 퍼블릭 미디어를 가져온 방법의 소스 코드를 확인할 수 있습니다. : D smashballoon.com/instagram-feed/demo 액세스 토큰이 필요없는 클라이언트 ID 만 있으면됩니다. : D
jehzlau

그들이 당신을 추적하고 모든 큰 API처럼 다운로드 (등급 ...)를 제한 할 수 있도록 인증해야합니다. 실제 사용자와 스크래퍼 / 봇에 대한 공개가 있습니다. 일반적으로 실제 사용자가 광고를보고 서비스를 직접 사용하는 것과는 다릅니다.
Christophe Roussy

1
이 방법들 중 어느 것도 더 이상 작동하지 않습니다. 참조 stackoverflow.com/questions/49852080/...
Moradnejad

답변:


123

Instagram의 문서에서 보지 못해서 누군가를 돕는다면 늦었지만 가치가 있습니다.

https://api.instagram.com/v1/users/<user-id>/media/recent/(현재 쓰는 시점에) GET을 수행하려면 실제로 OAuth 액세스 토큰이 필요하지 않습니다.

수행 할 수 있습니다 https://api.instagram.com/v1/users/[USER ID]/media/recent/?client_id=[CLIENT ID]

[CLIENT ID]는 클라이언트 관리 (사용자와 무관)를 통해 앱에 등록 된 유효한 클라이언트 ID입니다. GET 사용자 검색 요청을 수행하여 username에서 [USER ID]를 얻을 수 있습니다. https://api.instagram.com/v1/users/search?q=[USERNAME]&client_id=[CLIENT ID]


9
나는 그들이 그들의 마음을 다시 바꿨을 것이라고 생각합니다. OP에 표시된 것과 동일한 오류 응답이 표시됩니다.
James

35
2015 년 11 월 17 일 이전에 생성 된 앱에서만 유효하며 2016 년 6 월 이후에는 전혀 지원되지 않습니다. 이후에는 oauth access_token이 필요합니다. instagram.com/developer/changelog
닥스 Fohl

211
이것은 너무 어리 석고 자극적입니다. 왜 액세스 토큰이 이미 공개 된 이미지 만 표시하도록 강제 합니까? 전 세계의 모든 사용자를 위해 헹구려고 거의 노력하지 않습니다. 클라이언트를 엉망으로 만드는 데 몇 시간을 소비하지 않고 고객의 최신 채소를 표시하고 싶습니다. 가!
매트 플레처

8
@Cabus 요금 제한, 친구.
Walf

20
@MattFletcher 지금은 더 어리 석습니다. 앱 사용 권한 검토를 거쳐야합니다.이 유스 케이스 "자신의 웹 페이지에 고객의 피드 표시"가 사용 사례 중 하나가 아니기 때문에 실행 가능한지 확실하지 않습니다. 어,이 제한은 짜증나.
Ciantic 2016 년

334

var name = "smena8m";
$.get("https://images"+~~(Math.random()*3333)+"-focus-opensocial.googleusercontent.com/gadgets/proxy?container=none&url=https://www.instagram.com/" + name + "/", function(html) {
if (html) {
    var regex = /_sharedData = ({.*);<\/script>/m,
        json = JSON.parse(regex.exec(html)[1]),
        edges = json.entry_data.ProfilePage[0].graphql.user.edge_owner_to_timeline_media.edges;

      $.each(edges, function(n, edge) {
          var node = edge.node;
          $('body').append(
              $('<a/>', {
              href: 'https://instagr.am/p/'+node.shortcode,
              target: '_blank'
          }).css({
              backgroundImage: 'url(' + node.thumbnail_src + ')'
          }));
      });
    }
});
html, body {
  font-size: 0;
  line-height: 0;
}

a {
  display: inline-block;
  width: 25%;
  height: 0;
  padding-bottom: 25%;
  background: #eee 50% 50% no-repeat;
  background-size: cover;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

이와 같은?__a=1 방문 페이지 주소 옆을 사용하여 Instagram 사용자 사진 피드를 JSON 형식으로 다운로드 할 수 있습니다 . 사용자 ID를 얻거나 앱을 등록 할 필요가 없으며 토큰이나 oAuth가 없습니다.

min_idmax_id변수 매김에 사용될 수 있으며, 여기에서

YQL잠긴 iframe 내부에서 작동하지 않을 수 있으므로 YQL 콘솔 에서 언제든지 수동으로 확인할 수 있습니다

2018 년 4 월 업데이트 : 최신 인스 타 그램 업데이트 후 서명 된 요청에 대한 사용자 정의 헤더를 CORS Access-Control-Allow-Headers제한 으로 인해 자바 스크립트로 설정할 수 없으므로 클라이언트 측 (자바 스크립트) 에서이 작업을 수행 할 수 없습니다 . 가능성은 여전히 통해이를 수행하는 php적절한 서명에 기초하여 또는 다른 서버 측에있어서 rhx_gis, csrf_token요청 파라미터. 자세한 내용은 여기를 참조 하십시오 .

2019 년 1 월 업데이트 : YQL이 종료되었으므로 CORSInstagram 페이지의 프록시로 Google 이미지 프록시를 사용한 최신 업데이트를 확인 하십시오! 그런 다음 부정적인 순간 만-이 방법으로는 페이지 매김을 사용할 수 없습니다.

PHP 해결책:

    $html = file_get_contents('https://instagram.com/apple/');
    preg_match('/_sharedData = ({.*);<\/script>/', $html, $matches);
    $profile_data = json_decode($matches[1])->entry_data->ProfilePage[0]->graphql->user;

14
@ 350D 어떻게 찾았습니까? 나는 그들의 문서에서 그것을 찾을 수 없습니다. 나는이 끝점으로 가능한 것에 대해 더 자세히 읽고 싶습니다 (EG 정사각형 이미지 대 비 정사각형, 6 월에 종료 예정인지 여부 등)-감사합니다!
Phil Johnston

8
@ 필 존스턴 (Phil Johnston) 그냥 조사해 😀 이것을 다시 한 번 가져 가십시오. 사진 방문 페이지 URL 옆에 / media /? size = L을 추가하고 전체 해상도 사진을 얻을 수 있습니다.
350D

9
@ user2659694 마침내이 방법으로 다음 페이지를 얻는 해결책을 찾았습니다. / media /? max_id = [MAX_ID]
Reza

3
참고로 Instagram 계정에 직접 로그인 한 경우에만 작동하는 것으로 보입니다. Chrome 또는 이와 유사한 시크릿에서 시도하면 JSON 응답에 항목이 없습니다. 웹 서버의 URL 목록을 얻기 위해 이것을 스크립트에 통합하려고 시도했으며 이전 권한 부여 방법으로 돌아 가야했습니다.
Ryan Zink 2016 년

9
@RyanZink 당신은 개인 계정을 시도 했습니까? 공개 계정에서 로그 아웃하거나 시크릿 모드에서 작동합니다.
ryan

41

11.11.2017
Instagram 이이 데이터를 제공하는 방식을 변경했기 때문에 현재는 위의 방법 중 어느 것도 작동하지 않습니다. 사용자 미디어를 얻는 새로운 방법은 다음과 같습니다.
GET 위치 https://instagram.com/graphql/query/?query_id=17888483320059182&variables={"id":"1951415043","first":20,"after":null}
:
query_id-영구 가치 : 17888483320059182 (향후 변경 될 수 있음).
id-사용자의 ID 사용자 목록과 함께 제공 될 수 있습니다. 사용자 목록을 얻으려면 다음 요청을 사용할 수 있습니다 GET https://www.instagram.com/web/search/topsearch/?context=blended&query=YOUR_QUERY
first.-가져올 항목 수.
after-해당 ID에서 항목을 가져 오려는 경우 마지막 항목의 ID입니다.


query_id와 사용자 ID를 어디에서 얻을 수 있는지 알려 주시겠습니까?
Vijaysinh Parmar

2
앞에서 언급했듯이 @VijaysinhParmar query_id는 영구적 인 가치입니다. 즉 , 적어도 Instagram이 변경하지 않는 한 항상 17888483320059182 입니다. 사용자
ID-

1
인터넷 어딘가에 정확히 기억 나지 않습니다. 그러나 나는 인스 타 그램과 아무런 관계가 없으므로 변경이 발생하면 새로운 것을 말할 수 없을 것입니다 :(
Footniko

1
이 방법의 속도 제한 정책이 무엇인지 궁금하십니까?
kkzxak47

1
CURL 요청을 통해이 URL을 요청하는 데 문제가있는 경우 쿠키 요청 헤더를 가져와야합니다 (URL을 실행 한 후 네트워크 탭을 열고 쿠키 헤더를 복사하여 curl 요청 헤더에 붙여 넣으십시오). 403 액세스 거부 오류가 발생합니다).
Anders

40

인증없이 다음 API를 사용하여 사용자의 최신 미디어를 얻을 수있었습니다 (설명, 좋아요, 댓글 수 포함).

https://www.instagram.com/apple/?__a=1

예 :

https://www.instagram.com/{username}/?__a=1

1
이것은 또한 나를 위해 일했다. 그러나 "is_video = true"일 때, 데이터에 비디오 URL이 없다.
didikee

4
그렇습니다. 동영상 자체가 아닌 미리보기 이미지 만 가져올 수 있습니다. 불행히도, 공식 문서를 찾지 못했으며이 API가 더 이상 사용되지 않는지 또는 얼마나 오래 지원 될지 잘 모릅니다.
Michael

8
2018-04-13 기준으로 더 이상 작동하지 않는 것 같습니다. 아마도 Facebook의 최신 Cambridge Analytica 데이터 스캔들로 인해 일이 크게 줄어들고 있습니다. 인증없이 기본 사용자 데이터를 얻는 다른 제안이 있습니까?
BakerStreetSystems

2
예,이 API가 작동하지 않는 시간이있었습니다. 그러나 이제 다시 돌아옵니다
Michael

4
그것은 나를 위해 일했지만 Instagram에 로그인 할 때만 작동했습니다.
zundi

16

지난 주에 Instagram은 /media/URL을 비활성화 했으며 해결 방법을 구현했으며 현재로서는 잘 작동합니다.

이 스레드에서 모든 사람의 문제를 해결하기 위해 다음과 같이 썼습니다 : https://github.com/whizzzkid/instagram-reverse-proxy

다음 엔드 포인트를 사용하여 인스 타 그램의 모든 공개 데이터를 제공합니다.

사용자 미디어 가져 오기 :

https://igapi.ga/<username>/media
e.g.: https://igapi.ga/whizzzkid/media 

개수 제한이있는 사용자 미디어를 가져옵니다.

https://igapi.ga/<username>/media?count=N // 1 < N < 20
e.g.: https://igapi.ga/whizzzkid/media?count=5

JSONP를 사용하십시오.

https://igapi.ga/<username>/media?callback=foo
e.g.: https://igapi.ga/whizzzkid/media?callback=bar

또한 프록시 API는 다음 페이지 및 이전 페이지 URL을 응답에 추가하므로 끝에서이를 계산할 필요가 없습니다.

당신이 그것을 좋아 바랍니다!

이것을 발견해 주신 @ 350D에게 감사합니다 :)


1
@rex는 그들이 끝날 때 일하는 방식을 바꿀 때까지 좋습니다. 그들은 지난 3 년 동안 귀찮게하지 않았으며 아마도 다음 3 년에는 그렇지 않을 것입니다.
whizzzkid

3
@whizzzkid 불운, 그들은 그것을 바꾼다. 사용자 엔드 포인트가 작업을 수행 할 것이라고 생각하지만 로그인하지 않은 사용자에 대한 요청에는 제한이 있습니다. 어떤 아이디어?
nobilik

1
@nobilik 해결 방법이 있습니다. igpi.ga/whizzzkid/media?count=3igpi.ga/graphql/query/?user_id=1606740656&count=3 모두 데이터를 반환해야합니다. 이 URL에 대해서는 정의되지 않은 리퍼러가 비활성화되어 있습니다.
whizzzkid

1
@whizzzkid-작동합니다! 정말 감사합니다-당신은 학자와 신사입니다!
제임스 트릭 키

1
"추천자 액세스가 거부되었습니다"오류가 발생합니다. 어쩌면 이것이 더 이상 작동하지 않습니까?
khalid13

14

Instagram API는 사용자의 최신 미디어 엔드 포인트에 액세스하려면 OAuth를 통한 사용자 인증이 필요합니다. 현재 사용자를위한 모든 미디어를 얻는 다른 방법은 없습니다.


4
내 웹 사이트에 내 미디어를 표시하려는 경우, 인스 타 그램 계정을 갖고 싶어하는 모든 사람이 필요한 이유는 무엇입니까?
ninjasense

5
ninjasense-그것이 작동하는 방식이라고 생각하지 않습니다. 귀하의 웹 사이트에는 미디어를 가져 오기 위해 제공된 oauth 자격 증명으로 Instagram API를 쿼리하는 약간의 코드가 있어야한다고 생각합니다. 그런 다음 사이트의 모든 사용자에게 미디어를 보여줄 것입니다. 귀하의 사이트는 Instagram으로 인증하는 데 필요한 유일한 것입니다.
Bill Rawlinson

9

단일 계정에서 사용하기 위해 액세스 토큰을 생성하는 방법을 찾고 있다면 https://coderwall.com/p/cfgneq를 시도 하십시오 .

인스 타 그램 API를 사용하여 특정 계정의 모든 최신 미디어를 가져 오는 방법이 필요했습니다.


5
이것은 결국 내가 한 일입니다. 새 계정을 만들고 액세스 토큰을 만들고 API 키 옆의 서버 구성에 해당 토큰을 저장했습니다. JS 앱에는 좋지 않은 솔루션이지만 액세스 토큰을 사용자에게 제공해야하기 때문에 많은 예제 코드를 보았습니다. 운 좋게도 서버 측에서 할 수 있습니다.
Peeja

4
@CraigHeneveld 어떻게 당신은 hat_access_token을 최신 상태로 유지합니까? 만료되지 않았습니까?
Ryan Ore

토큰이 시간이 만료됩니까?
Monitus

내 기억이 나에게 도움이되면 암호를 변경해야만 키가 만료됩니다. 여기에 또 다른 스레드가 있습니다-> stackoverflow.com/questions/22753170/…
Craig Heneveld

여러 사용자 사진을 어떻게 얻을 수 있습니까 ?? ","로 구분 된 여러 사용자 ID를 전달할 수있는 것처럼?
Aadil Keshwani

9

다음은 레일 솔루션입니다. 백도어의 일종인데, 실제로는 정문입니다.

# create a headless browser
b = Watir::Browser.new :phantomjs
uri = 'https://www.instagram.com/explore/tags/' + query
uri = 'https://www.instagram.com/' + query if type == 'user'

b.goto uri

# all data are stored on this page-level object.
o = b.execute_script( 'return window._sharedData;')

b.close

돌아 오는 개체는 사용자 검색인지 또는 태그 검색인지에 따라 다릅니다. 나는 이와 같은 데이터를 얻는다 :

if type == 'user'
  data = o[ 'entry_data' ][ 'ProfilePage' ][ 0 ][ 'user' ][ 'media' ][ 'nodes' ]
  page_info = o[ 'entry_data' ][ 'ProfilePage' ][ 0 ][ 'user' ][ 'media' ][ 'page_info' ]
  max_id = page_info[ 'end_cursor' ]
  has_next_page = page_info[ 'has_next_page' ]
else
  data = o[ 'entry_data' ][ 'TagPage' ][ 0 ][ 'tag' ][ 'media' ][ 'nodes' ]
  page_info = o[ 'entry_data' ][ 'TagPage' ][ 0 ][ 'tag' ][ 'media' ][ 'page_info' ]
  max_id = page_info[ 'end_cursor' ]
  has_next_page = page_info[ 'has_next_page' ]
end

그런 다음 다음과 같은 방법으로 URL을 구성하여 다른 결과 페이지를 얻습니다.

  uri = 'https://www.instagram.com/explore/tags/' + query_string.to_s\
    + '?&max_id=' + max_id.to_s
  uri = 'https://www.instagram.com/' + query_string.to_s + '?&max_id='\
    + max_id.to_s if type === 'user'

이 솔루션은 저에게 효과적이지만 문제가 있습니다. 데이터를로드 한 후 Rails 서버 (Prails 3.0.0, Puma 3.6.0 서버 사용)가 예기치 않게 다시 시작됩니다. 가능한 해결책이 있습니까?
Luis Eduardo Rojas Cabrera

8

Instagram의 끊임없이 변화하고 끔찍하게 디자인 된 API 스키마 덕분에 위의 대부분은 2018 년 4 월 현재 더 이상 작동하지 않습니다.

다음은 https://www.instagram.com/username/?__a=1메소드를 사용하여 API를 직접 쿼리하는 경우 개별 게시물 데이터에 액세스하는 최신 경로 입니다.

반환 된 JSON데이터를 가정하면 $data다음 경로 예제를 사용하여 각 결과를 반복 할 수 있습니다.

foreach ($data->graphql->user->edge_owner_to_timeline_media->edges as $item) {

    $content_id = $item->node->id; 
    $date_posted = $item-node->taken_at_timestamp;
    $comments = $item->node->edge_media_to_comment->count;
    $likes = $item->node->edge_liked_by->count;
    $image = $item->node->display_url;
    $content = $item->node->edge_media_to_caption->edges[0]->node->text;
    // etc etc ....
}

이 최근 변경의 주요 사항은 graphqledge_owner_to_timeline_media입니다.

DEC 2018 에서 비 '비즈니스'고객을 위해이 API 액세스를 중단 할 것으로 보이므로 최대한 활용하십시오.

그것이 누군가를 돕기를 바랍니다.)


이것은 고객에게 최신 인스 타 그램 게시물을 보여주고 싶습니다. 감사!
weston deboer

1
instagram.com/username/?__a=1에서 오류가 발생했습니다 : www.instagram.com에 대한 액세스가 거부되었습니다.이 페이지를 볼 수있는 권한이 없습니다. HTTP ERROR 403 다른 아이디어가 있습니까?
Hese

1
Yep Instagram은 이제 이것을 없애 버렸습니다. "Instagram 사용자의 개인 정보 보호 및 보안을 지속적으로 개선하기 위해 Instagram API 플랫폼의 사용 중단을 가속화하여 다음 변경 사항을 즉시 적용하고 있습니다. 이는 귀하의 비즈니스 나 서비스에 영향을 줄 수 있음을 이해하고 플랫폼을 안전하게 유지하는 데 도움을 주셔서 감사합니다. 이러한 기능은 즉시 비활성화됩니다 (이전에는 2018 년 7 월 31 일 또는 2018 년 12 월 11 일에 더 이상 사용되지 않음).
spice

내가 읽고있는 내용이 정확하면 더 이상 "비업무"계정에서 이미지 나 데이터를 검색 할 수 없습니다. 그들은 플랫폼 API를 완전히 없애고 있습니다. 그게 다야
spice

1
@ james_tookey는 친구가 될 수 없습니다. 새로운 개인 정보 보호 제한으로 인해 더 이상 개인 계정의 사용자 / 데이터를 쿼리하거나 검색 할 수 없으며 비즈니스 계정 만 검색 할 수 있습니다. 기본적으로 그들은 개인 계정에 대한 모든 API 사용을 중단했습니다.
spice

7

JSFiddle

자바 스크립트 :

$(document).ready(function(){

    var username = "leomessi";
    var max_num_items = 5;

    var jqxhr = $.ajax( "https://www.instagram.com/"+username+"/?__a=1" ).done(function() {
        //alert( "success" );
    }).fail(function() {
        //alert( "error" );
    }).always(function(data) {
        //alert( "complete" )
        items = data.graphql.user.edge_owner_to_timeline_media.edges;
        $.each(items, function(n, item) {
            if( (n+1) <= max_num_items )
            {
                var data_li = "<li><a target='_blank' href='https://www.instagram.com/p/"+item.node.shortcode+"'><img src='" + item.node.thumbnail_src + "'/></a></li>";
                $("ul.instagram").append(data_li);
            }
        });

    });

});

HTML :

<ul class="instagram">
</ul>

CSS :

ul.instagram {
    list-style: none;
}

ul.instagram li {
  float: left;
}

ul.instagram li img {
    height: 100px;
}

5

내가 이해하기 어려웠 기 때문에 @ 350D 답변에 추가하고 싶습니다.

코드의 내 논리는 다음입니다.

API를 처음 호출 할 때 만 호출합니다 https://www.instagram.com/_vull_ /media/. 응답을 받으면 부울 값을 확인합니다 more_available. 그것이 사실이라면, 배열에서 마지막 사진을 가져 와서 id를 얻은 다음 Instagram API를 다시 호출하지만 이번에는 https://www.instagram.com/_vull_/media/?max_id=1400286183132701451_1642962433.

여기서 알아야 할 중요한 것은이 ID는 배열에서 마지막 그림의 ID입니다. 따라서 배열에서 그림의 마지막 id로 maxId를 요청할 때 다음 20 개의 그림 등이 표시됩니다.

이것이 명확하게되기를 바랍니다.


4

Oauth를 무시하면 인스 타 그램 사용자가 누구인지 모를 것입니다. 그것은 인증없이 인스 타 그램 이미지를 얻는 몇 가지 방법이 있다고합니다.

  1. Instagram의 API를 사용하면 인증하지 않고도 사용자에게 가장 인기있는 이미지를 볼 수 있습니다. 다음 엔드 포인트 사용 : 여기 링크

  2. Instagram 은이 태그에 대한 RSS 피드를 제공합니다 .

  3. Instagram 사용자 페이지는 공개되어 있으므로 CURL과 함께 PHP를 사용하여 페이지를 가져오고 DOM 파서는 HTML에서 원하는 이미지 태그를 검색 할 수 있습니다.


9
오래된 것 같습니다.
Burak Tokak

instagram에 대한 인증을 우회하는 것이 가능
JAck

3

또 하나의 트릭, 해시 태그로 사진 검색 :

GET https://www.instagram.com/graphql/query/?query_hash=3e7706b09c6184d5eafd8b032dbcf487&variables={"tag_name":"nature","first":25,"after":""}

어디:

query_hash -영구 가치 (해시 17888483320059182의 해시를 믿으며 나중에 변경할 수 있음)

tag_name -제목 자체를 말합니다

first -얻을 항목의 양 (이유는 모르겠지만이 값은 예상대로 작동하지 않습니다. 반환 된 실제 사진 수는 4.5를 곱한 값 (값 25의 경우 약 110, 값의 경우 약 460)보다 약간 큽니다. 값 100))

after-해당 ID에서 항목을 가져 오려는 경우 마지막 항목의 ID입니다. end_cursorJSON 응답의 값을 여기에서 사용할 수 있습니다.


이걸 어떻게 찾습니까?
ekntrtmz



2

당신은 인스 타 그램 사용자의 공개 정보를 검색하기 위해이 API를 사용할 수 있습니다
https://api.lityapp.com/instagrams/thebrainscoop?limit=2을

당신이 제한 매개 변수를 설정하지 않으면 게시물은 기본적으로 12에서 제한된다

이 api는 코드에서 볼 수 있듯이 HtmlUnit을 사용하여 SpringBoot에서 만들어졌습니다.

public JSONObject getPublicInstagramByUserName(String userName, Integer limit) {
    String html;
    WebClient webClient = new WebClient();

    try {
        webClient.getOptions().setCssEnabled(false);
        webClient.getOptions().setJavaScriptEnabled(false);
        webClient.getOptions().setThrowExceptionOnScriptError(false);
        webClient.getCookieManager().setCookiesEnabled(true);

        Page page = webClient.getPage("https://www.instagram.com/" + userName);
        WebResponse response = page.getWebResponse();

        html = response.getContentAsString();
    } catch (Exception ex) {
        ex.printStackTrace();

        throw new RuntimeException("Ocorreu um erro no Instagram");
    }

    String prefix = "static/bundles/es6/ProfilePageContainer.js";
    String sufix = "\"";
    String script = html.substring(html.indexOf(prefix));

    script = script.substring(0, script.indexOf(sufix));

    try {
        Page page = webClient.getPage("https://www.instagram.com/" + script);
        WebResponse response = page.getWebResponse();

        script = response.getContentAsString();
    } catch (Exception ex) {
        ex.printStackTrace();

        throw new RuntimeException("Ocorreu um erro no Instagram");
    }

    prefix = "l.pagination},queryId:\"";

    String queryHash = script.substring(script.indexOf(prefix) + prefix.length());

    queryHash = queryHash.substring(0, queryHash.indexOf(sufix));
    prefix = "<script type=\"text/javascript\">window._sharedData = ";
    sufix = ";</script>";
    html = html.substring(html.indexOf(prefix) + prefix.length());
    html = html.substring(0, html.indexOf(sufix));

    JSONObject json = new JSONObject(html);
    JSONObject entryData = json.getJSONObject("entry_data");
    JSONObject profilePage = (JSONObject) entryData.getJSONArray("ProfilePage").get(0);
    JSONObject graphql = profilePage.getJSONObject("graphql");
    JSONObject user = graphql.getJSONObject("user");
    JSONObject response = new JSONObject();

    response.put("id", user.getString("id"));
    response.put("username", user.getString("username"));
    response.put("fullName", user.getString("full_name"));
    response.put("followedBy", user.getJSONObject("edge_followed_by").getLong("count"));
    response.put("following", user.getJSONObject("edge_follow").getLong("count"));
    response.put("isBusinessAccount", user.getBoolean("is_business_account"));
    response.put("photoUrl", user.getString("profile_pic_url"));
    response.put("photoUrlHD", user.getString("profile_pic_url_hd"));

    JSONObject edgeOwnerToTimelineMedia = user.getJSONObject("edge_owner_to_timeline_media");
    JSONArray posts = new JSONArray();

    try {
        loadPublicInstagramPosts(webClient, queryHash, user.getString("id"), posts, edgeOwnerToTimelineMedia, limit == null ? 12 : limit);
    } catch (Exception ex) {
        ex.printStackTrace();

        throw new RuntimeException("Você fez muitas chamadas, tente mais tarde");
    }

    response.put("posts", posts);

    return response;
}

private void loadPublicInstagramPosts(WebClient webClient, String queryHash, String userId, JSONArray posts, JSONObject edgeOwnerToTimelineMedia, Integer limit) throws IOException {
    JSONArray edges = edgeOwnerToTimelineMedia.getJSONArray("edges");

    for (Object elem : edges) {
        if (limit != null && posts.length() == limit) {
            return;
        }

        JSONObject node = ((JSONObject) elem).getJSONObject("node");

        if (node.getBoolean("is_video")) {
            continue;
        }

        JSONObject post = new JSONObject();

        post.put("id", node.getString("id"));
        post.put("shortcode", node.getString("shortcode"));

        JSONArray captionEdges = node.getJSONObject("edge_media_to_caption").getJSONArray("edges");

        if (captionEdges.length() > 0) {
            JSONObject captionNode = ((JSONObject) captionEdges.get(0)).getJSONObject("node");

            post.put("caption", captionNode.getString("text"));
        } else {
            post.put("caption", (Object) null);
        }

        post.put("photoUrl", node.getString("display_url"));

        JSONObject dimensions = node.getJSONObject("dimensions");

        post.put("photoWidth", dimensions.getLong("width"));
        post.put("photoHeight", dimensions.getLong("height"));

        JSONArray thumbnailResources = node.getJSONArray("thumbnail_resources");
        JSONArray thumbnails = new JSONArray();

        for (Object elem2 : thumbnailResources) {
            JSONObject obj = (JSONObject) elem2;
            JSONObject thumbnail = new JSONObject();

            thumbnail.put("photoUrl", obj.getString("src"));
            thumbnail.put("photoWidth", obj.getLong("config_width"));
            thumbnail.put("photoHeight", obj.getLong("config_height"));
            thumbnails.put(thumbnail);
        }

        post.put("thumbnails", thumbnails);
        posts.put(post);
    }

    JSONObject pageInfo = edgeOwnerToTimelineMedia.getJSONObject("page_info");

    if (!pageInfo.getBoolean("has_next_page")) {
        return;
    }

    String endCursor = pageInfo.getString("end_cursor");
    String variables = "{\"id\":\"" + userId + "\",\"first\":12,\"after\":\"" + endCursor + "\"}";

    String url = "https://www.instagram.com/graphql/query/?query_hash=" + queryHash + "&variables=" + URLEncoder.encode(variables, "UTF-8");
    Page page = webClient.getPage(url);
    WebResponse response = page.getWebResponse();
    String content = response.getContentAsString();
    JSONObject json = new JSONObject(content);

    loadPublicInstagramPosts(webClient, queryHash, userId, posts, json.getJSONObject("data").getJSONObject("user").getJSONObject("edge_owner_to_timeline_media"), limit);
}


응답의 예입니다.

{
  "id": "290482318",
  "username": "thebrainscoop",
  "fullName": "Official Fan Page",
  "followedBy": 1023,
  "following": 6,
  "isBusinessAccount": false,
  "photoUrl": "https://scontent-gru2-1.cdninstagram.com/vp/447ffd0262082f373acf3d467435f130/5C709C77/t51.2885-19/11351770_612904665516559_678168252_a.jpg",
  "photoUrlHD": "https://scontent-gru2-1.cdninstagram.com/vp/447ffd0262082f373acf3d467435f130/5C709C77/t51.2885-19/11351770_612904665516559_678168252_a.jpg",
  "posts": [
    {
      "id": "1430331382090378714",
      "shortcode": "BPZjtBUly3a",
      "caption": "If I have any active followers anymore; hello! I'm Brianna, and I created this account when I was just 12 years old to show my love for The Brain Scoop. I'm now nearly finished high school, and just rediscovered it. I just wanted to see if anyone is still active on here, and also correct some of my past mistakes - being a child at the time, I didn't realise I had to credit artists for their work, so I'm going to try to correct that post haste. Also; the font in my bio is horrendous. Why'd I think that was a good idea? Anyway, this is a beautiful artwork of the long-tailed pangolin by @chelsealinaeve . Check her out!",
      "photoUrl": "https://scontent-gru2-1.cdninstagram.com/vp/ab823331376ca46136457f4654bf2880/5CAD48E4/t51.2885-15/e35/16110915_400942200241213_3503127351280009216_n.jpg",
      "photoWidth": 640,
      "photoHeight": 457,
      "thumbnails": [
        {
          "photoUrl": "https://scontent-gru2-1.cdninstagram.com/vp/43b195566d0ef2ad5f4663ff76d62d23/5C76D756/t51.2885-15/e35/c91.0.457.457/s150x150/16110915_400942200241213_3503127351280009216_n.jpg",
          "photoWidth": 150,
          "photoHeight": 150
        },
        {
          "photoUrl": "https://scontent-gru2-1.cdninstagram.com/vp/ae39043a7ac050c56d741d8b4355c185/5C93971C/t51.2885-15/e35/c91.0.457.457/s240x240/16110915_400942200241213_3503127351280009216_n.jpg",
          "photoWidth": 240,
          "photoHeight": 240
        },
        {
          "photoUrl": "https://scontent-gru2-1.cdninstagram.com/vp/ae7a22d09e3ef98d0a6bbf31d621a3b7/5CACBBA6/t51.2885-15/e35/c91.0.457.457/s320x320/16110915_400942200241213_3503127351280009216_n.jpg",
          "photoWidth": 320,
          "photoHeight": 320
        },
        {
          "photoUrl": "https://scontent-gru2-1.cdninstagram.com/vp/1439dc72b70e7c0c0a3afcc30970bb13/5C8E2923/t51.2885-15/e35/c91.0.457.457/16110915_400942200241213_3503127351280009216_n.jpg",
          "photoWidth": 480,
          "photoHeight": 480
        },
        {
          "photoUrl": "https://scontent-gru2-1.cdninstagram.com/vp/1439dc72b70e7c0c0a3afcc30970bb13/5C8E2923/t51.2885-15/e35/c91.0.457.457/16110915_400942200241213_3503127351280009216_n.jpg",
          "photoWidth": 640,
          "photoHeight": 640
        }
      ]
    },
    {
      "id": "442527661838057235",
      "shortcode": "YkLJBXJD8T",
      "caption": null,
      "photoUrl": "https://scontent-gru2-1.cdninstagram.com/vp/dc94b38da679826b9ac94ccd2bcc4928/5C7CDF93/t51.2885-15/e15/11327349_860747310663863_2105199307_n.jpg",
      "photoWidth": 612,
      "photoHeight": 612,
      "thumbnails": [
        {
          "photoUrl": "https://scontent-gru2-1.cdninstagram.com/vp/c1153c6513c44a6463d897e14b2d8f06/5CB13ADD/t51.2885-15/e15/s150x150/11327349_860747310663863_2105199307_n.jpg",
          "photoWidth": 150,
          "photoHeight": 150
        },
        {
          "photoUrl": "https://scontent-gru2-1.cdninstagram.com/vp/47e60ec8bca5a1382cd9ac562439d48c/5CAE6A82/t51.2885-15/e15/s240x240/11327349_860747310663863_2105199307_n.jpg",
          "photoWidth": 240,
          "photoHeight": 240
        },
        {
          "photoUrl": "https://scontent-gru2-1.cdninstagram.com/vp/da0ee5b666ab40e4adc1119e2edca014/5CADCB59/t51.2885-15/e15/s320x320/11327349_860747310663863_2105199307_n.jpg",
          "photoWidth": 320,
          "photoHeight": 320
        },
        {
          "photoUrl": "https://scontent-gru2-1.cdninstagram.com/vp/02ee23571322ea8d0992e81e72f80ef2/5C741048/t51.2885-15/e15/s480x480/11327349_860747310663863_2105199307_n.jpg",
          "photoWidth": 480,
          "photoHeight": 480
        },
        {
          "photoUrl": "https://scontent-gru2-1.cdninstagram.com/vp/dc94b38da679826b9ac94ccd2bcc4928/5C7CDF93/t51.2885-15/e15/11327349_860747310663863_2105199307_n.jpg",
          "photoWidth": 640,
          "photoHeight": 640
        }
      ]
    }
  ]
}

userid (pk)로 데이터를 가져올 수
있습니까

죄송합니다 @SAURABHRATHOD 시도했지만이 방법을 찾지 못했습니다. 누군가가 이것을 해결하면 매우 기쁠 것입니다. 의견 주셔서 감사합니다.
Ruan Barroso 2018 년

2

나는이 기능이 정말로 필요했지만 Wordpress를 위해. 나는 맞고 완벽하게 일했다

<script>
    jQuery(function($){
        var name = "caririceara.comcariri";
        $.get("https://images"+~~(Math.random()*33)+"-focus-opensocial.googleusercontent.com/gadgets/proxy?container=none&url=https://www.instagram.com/" + name + "/", function(html) {
            if (html) {
                var regex = /_sharedData = ({.*);<\/script>/m,
                  json = JSON.parse(regex.exec(html)[1]),
                  edges = json.entry_data.ProfilePage[0].graphql.user.edge_owner_to_timeline_media.edges;
              $.each(edges, function(n, edge) {
                   if (n <= 7){
                     var node = edge.node;
                    $('.img_ins').append('<a href="https://instagr.am/p/'+node.shortcode+'" target="_blank"><img src="'+node.thumbnail_src+'" width="150"></a>');
                   }
              });
            }
        });
    }); 
    </script>

1

아래 nodejs 코드는 Instagram 페이지에서 인기있는 이미지를 긁습니다. 'ScrapeInstagramPage'기능은 에이징 후 효과를 처리합니다.

var request = require('parse5');
var request = require('request');
var rp      = require('request-promise');
var $       = require('cheerio'); // Basically jQuery for node.js 
const jsdom = require("jsdom");    
const { JSDOM } = jsdom;


function ScrapeInstagramPage (args) {
    dout("ScrapeInstagramPage for username -> " + args.username);
    var query_url = 'https://www.instagram.com/' + args.username + '/';

    var cookieString = '';

    var options = {
        url: query_url,
        method: 'GET',
        headers: {
            'x-requested-with' : 'XMLHttpRequest',
            'accept-language'  : 'en-US,en;q=0.8,pt;q=0.6,hi;q=0.4', 
            'User-Agent'       : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36',
            'referer'          : 'https://www.instagram.com/dress_blouse_designer/',
            'Cookie'           : cookieString,
            'Accept'           : '*/*',
            'Connection'       : 'keep-alive',
            'authority'        : 'www.instagram.com' 
        }
    };


    function dout (msg) {
        if (args.debug) {
            console.log(msg);
        }
    }

    function autoParse(body, response, resolveWithFullResponse) {
        // FIXME: The content type string could contain additional values like the charset. 
        // Consider using the `content-type` library for a robust comparison. 
        if (response.headers['content-type'] === 'application/json') {
            return JSON.parse(body);
        } else if (response.headers['content-type'] === 'text/html') {
            return $.load(body);
        } else {
            return body;
        }
    }

    options.transform = autoParse;


    rp(options)
        .then(function (autoParsedBody) {
            if (args.debug) {
                console.log("Responce of 'Get first user page': ");
                console.log(autoParsedBody);
                console.log("Creating JSDOM from above Responce...");
            }

            const dom = new JSDOM(autoParsedBody.html(), { runScripts: "dangerously" });
            if (args.debug) console.log(dom.window._sharedData); // full data doc form instagram for a page

            var user = dom.window._sharedData.entry_data.ProfilePage[0].user;
            if (args.debug) {
                console.log(user); // page user
                console.log(user.id); // user ID
                console.log(user.full_name); // user full_name
                console.log(user.username); // user username
                console.log(user.followed_by.count); // user followed_by
                console.log(user.profile_pic_url_hd); // user profile pic
                console.log(autoParsedBody.html());
            }

            if (user.is_private) {
                dout ("User account is PRIVATE");
            } else {
                dout ("User account is public");
                GetPostsFromUser(user.id, 5000, undefined);
            }
        })
        .catch(function (err) {
            console.log( "ERROR: " + err );
        });  

    var pop_posts = [];
    function GetPostsFromUser (user_id, first, end_cursor) {
        var end_cursor_str = "";
        if (end_cursor != undefined) {
            end_cursor_str = '&after=' + end_cursor;
        }

        options.url = 'https://www.instagram.com/graphql/query/?query_id=17880160963012870&id=' 
                        + user_id + '&first=' + first + end_cursor_str;

        rp(options)
            .then(function (autoParsedBody) {
                if (autoParsedBody.status === "ok") {
                    if (args.debug) console.log(autoParsedBody.data);
                    var posts = autoParsedBody.data.user.edge_owner_to_timeline_media;

                    // POSTS processing
                    if (posts.edges.length > 0) {
                        //console.log(posts.edges);
                        pop_posts = pop_posts.concat
                        (posts.edges.map(function(e) {
                            var d = new Date();
                            var now_seconds = d.getTime() / 1000;

                            var seconds_since_post = now_seconds - e.node.taken_at_timestamp;
                            //console.log("seconds_since_post: " + seconds_since_post);

                            var ageing = 10; // valuses (1-10]; big value means no ageing
                            var days_since_post = Math.floor(seconds_since_post/(24*60*60));
                            var df = (Math.log(ageing+days_since_post) / (Math.log(ageing)));
                            var likes_per_day = (e.node.edge_liked_by.count / df);
                            // console.log("likes: " + e.node.edge_liked_by.count);
                            //console.log("df: " + df);
                            //console.log("likes_per_day: " + likes_per_day);
                            //return (likes_per_day > 10 * 1000);
                            var obj = {};
                            obj.url = e.node.display_url;
                            obj.likes_per_day = likes_per_day;
                            obj.days_since_post = days_since_post;
                            obj.total_likes = e.node.edge_liked_by.count;
                            return obj;
                        }
                        ));

                        pop_posts.sort(function (b,a) {
                          if (a.likes_per_day < b.likes_per_day)
                            return -1;
                          if (a.likes_per_day > b.likes_per_day)
                            return 1;
                          return 0;
                        });

                        //console.log(pop_posts);

                        pop_posts.forEach(function (obj) {
                            console.log(obj.url);
                        });
                    }

                    if (posts.page_info.has_next_page) {
                        GetPostsFromUser(user_id, first, posts.page_info.end_cursor);
                    }
                } else {
                    console.log( "ERROR: Posts AJAX call not returned good..." );
                }
            })
            .catch(function (err) {
                console.log( "ERROR: " + err );
            }); 
    }
}


ScrapeInstagramPage ({username : "dress_blouse_designer", debug : false});

여기 사용해보십시오

예 : URL ' https://www.instagram.com/dress_blouse_designer/ '에 대해 함수를 호출 할 수 있습니다

ScrapeInstagramPage ({username : "dress_blouse_designer", debug : false});

처음 12 개의 게시물 만 볼 수 있는데 모든 게시물을 어떻게 얻을 수 있습니까?
rahul gawale

0

이것은 간단한 아약스 호출과 반복 이미지 경로를 사용하여 작동합니다.

        var name = "nasa";
        $.get("https://www.instagram.com/" + name + "/?__a=1", function (data, status) {
            console.log('IG_NODES', data.user.media.nodes);
            $.each(data.user.media.nodes, function (n, item) {
                console.log('ITEMS', item.display_src);
                $('body').append(
                    "<div class='col-md-4'><img class='img-fluid d-block' src='" + item.display_src + "'></div>"
                );
            });
        })

그것은 나를 위해 일했지만 Instagram에 로그인 할 때만 작동했습니다.
zundi

-1

다음은 이미지를 다운로드하고 이미지 링크가 포함 된 html 파일을 생성하는 PHP 스크립트입니다. PHP 버전에 대한 크레딧 350D, 이것은 정교합니다. 2019 년 5 월 현재 작업을 확인했습니다 .

<?
$user = 'smena8m';
$igdata = file_get_contents('https://instagram.com/'.$user.'/');
preg_match('/_sharedData = ({.*);<\/script>/',$igdata,$matches);
$profile_data = json_decode($matches[1])->entry_data->ProfilePage[0]->graphql->user;
$html = '<div class="instagramBox" style="display:inline-grid;grid-template-columns:auto auto auto;">';
$i = 0;
$max = 9;
while($i<$max){
    $imglink = $profile_data->edge_owner_to_timeline_media->edges[$i]->node->shortcode;
    $img = $profile_data->edge_owner_to_timeline_media->edges[$i]->node->thumbnail_resources[0]->src;
    file_put_contents('ig'.$i.'.jpg',file_get_contents($img));
    $html .= '<a href="https://www.instagram.com/p/'.$imglink.'/" target="_blank"><img src="ig'.$i.'.jpg" /></a>';
    $i++;
}
$html .= '</div>';
$instagram = fopen('instagram.html','w');
fwrite($instagram,$html);
fclose($instagram);
?>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.