Làm cách nào tôi có thể nhận được phương tiện của người dùng từ Instagram mà không cần xác thực là người dùng?


175

Tôi đang cố gắng đưa phương tiện Instagram gần đây của người dùng lên một thanh bên. Tôi đang cố gắng sử dụng API Instagram để tìm nạp phương tiện truyền thông.

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

Tài liệu nói với GET https://api.instagram.com/v1/users/<user-id>/media/recent/, nhưng nó nói để vượt qua mã thông báo truy cập OAuth. Mã thông báo truy cập đại diện cho ủy quyền hành động thay mặt người dùng. Tôi không muốn người dùng đăng nhập vào Instagram để thấy điều này trên thanh bên. Họ thậm chí không cần phải có tài khoản Instagram.

Chẳng hạn, tôi có thể truy cập http://instagram.com/thebrainscoop mà không cần đăng nhập vào Instagram và xem ảnh. Tôi muốn làm điều đó thông qua API.

Trong API Instagram, các yêu cầu không được người dùng xác thực vượt qua client_id thay vì một access_token. Nếu tôi thử điều đó, mặc dù, tôi nhận được:

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

Vì vậy, điều này là không thể? Có cách nào để tìm nạp phương tiện (công khai) mới nhất của người dùng mà không yêu cầu người dùng đăng nhập vào tài khoản Instagram thông qua OAuth không?


Có thể với plugin này, chỉ cần kiểm tra mã nguồn về cách họ tìm nạp phương tiện công cộng mới nhất của người dùng mà không yêu cầu người dùng đăng nhập vào tài khoản instagram của họ. : D smashballoon.com/instagram-feed/demo Bạn chỉ cần một id khách hàng, không cần mã thông báo truy cập. : D
jehzlau

Bạn cần xác thực để họ có thể theo dõi bạn và giới hạn lượt tải xuống của bạn (tỷ lệ ...) như mọi API lớn. Có công khai cho người dùng thực và công khai cho scrappers / bot, thường không giống như người dùng thực sẽ thấy quảng cáo và trực tiếp sử dụng dịch vụ.
Barshe Roussy

1
Không có phương pháp nào trong số này làm việc nữa. Xem stackoverflow.com/questions/49852080/ khăn
Moradnejad

Câu trả lời:


123

Điều này là muộn, nhưng đáng giá nếu nó giúp được ai đó như tôi đã không thấy nó trong tài liệu của Instagram.

Để thực hiện GET trên https://api.instagram.com/v1/users/<user-id>/media/recent/ (tại thời điểm hiện tại viết), bạn thực sự không cần mã thông báo truy cập OAuth.

Bạn có thể thực hiện https://api.instagram.com/v1/users/[USER ID]/media/recent/?client_id=[CLIENT ID]

[ID CLIENT] sẽ là id khách hàng hợp lệ được đăng ký trong ứng dụng thông qua quản lý khách hàng (không liên quan đến người dùng nào). Bạn có thể nhận [ID người dùng] từ tên người dùng bằng cách thực hiện yêu cầu tìm kiếm của người dùng GET: https://api.instagram.com/v1/users/search?q=[USERNAME]&client_id=[CLIENT ID]


9
Tôi nghĩ rằng họ có thể đã thay đổi tâm trí của họ một lần nữa. Tôi nhận được phản hồi lỗi tương tự như được hiển thị trong OP
James

35
Điều này chỉ hợp lệ trên các ứng dụng được tạo trước ngày 17 tháng 11 năm 2015 và hoàn toàn không được hỗ trợ sau tháng 6 năm 2016. Sau đó, bạn sẽ cần một access_token oauth. instagram.com/developer/changelog
Dax Fohl

211
Điều này thật ngu ngốc và khó chịu. Tại sao họ buộc một mã thông báo truy cập chỉ để hiển thị hình ảnh đã được công khai ? Tôi hầu như không cố gắng rửa chúng cho mọi người dùng trên thế giới, tôi chỉ muốn hiển thị insta mới nhất của khách hàng mà không phải mất hàng giờ để làm phiền nó. Trời ạ!
Matt Fletcher

8
@ Giới hạn tỷ lệ, bạn đời.
Walf

20
@MattFletcher bây giờ thậm chí còn ngu ngốc hơn, người ta phải xem xét cấp phép ứng dụng và không chắc liệu nó có khả thi hay không vì trường hợp sử dụng này "hiển thị nguồn cấp dữ liệu của khách hàng trong trang web của riêng họ" không phải là một trong những trường hợp sử dụng. Duh, những hạn chế hút.
Ciantic

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>

Bạn có thể tải xuống bất kỳ nguồn cấp ảnh người dùng Instagram nào ở định dạng JSON bằng cách sử dụng ?__a=1bên cạnh địa chỉ trang đích như thế này . Không cần lấy id người dùng hoặc đăng ký ứng dụng, không mã thông báo, không oAuth.

min_idmax_idcác biến có thể được sử dụng để phân trang, đây là ví dụ

YQLcó thể không hoạt động ở đây bên trong iframe bị bắn tỉa, vì vậy bạn luôn có thể kiểm tra thủ công trong Bảng điều khiển YQL

CẬP NHẬT THÁNG 4 NĂM 2018: Sau các cập nhật instagram mới nhất, bạn không thể thực hiện việc này ở phía máy khách (javascript) vì các tiêu đề tùy chỉnh cho yêu cầu đã ký không thể được đặt bằng javascript do các CORS Access-Control-Allow-Headershạn chế. Nó vẫn có thể làm được điều này thông qua phphoặc bất kỳ phương pháp máy chủ bên kia có chữ ký thích hợp dựa trên rhx_gis, csrf_tokenvà yêu cầu các thông số. Bạn có thể đọc thêm về nó ở đây .

THÁNG 1 NĂM 2019 CẬP NHẬT: YQL đã nghỉ hưu, vì vậy, hãy kiểm tra cập nhật mới nhất của tôi với Google Image Proxy làm CORSproxy cho trang Instagram! Sau đó, chỉ có khoảnh khắc tiêu cực - phân trang không có sẵn với phương pháp này.

PHP giải pháp:

    $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 Làm thế nào bạn tìm thấy điều này? Tôi không thể tìm thấy nó ở bất cứ đâu trong tài liệu của họ. Tôi chỉ muốn đọc thêm về những gì có thể với điểm cuối này (hình vuông EG so với hình vuông, cho dù điều này có kế hoạch kết thúc vào tháng 6, v.v.) - Cảm ơn!
Phil Johnston

8
@Phil Johnston Chỉ cần một nghiên cứu 😀 Lấy cái này khác - bạn có thể thêm / media /? Size = L bên cạnh URL trang đích của ảnh và nhận ảnh có độ phân giải ĐẦY ĐỦ.
350D

9
@ user2659694 Cuối cùng tôi đã tìm thấy giải pháp để có được các trang tiếp theo với phương thức này bạn có thể sử dụng / media /? max_id = [MAX_ID]
Reza

3
FYI này dường như chỉ hoạt động nếu bạn đã đăng nhập vào tài khoản Instagram. Hãy thử thực hiện trong Ẩn danh trong Chrome hoặc tương tự và bạn sẽ thấy phản hồi JSON không chứa mục nào. Tôi đã cố gắng kết hợp điều này vào một tập lệnh để lấy danh sách các URL trên máy chủ web và phải quay lại các phương thức ủy quyền cũ.
Ryan Zink

9
@RyanZink bạn đang thử một tài khoản riêng tư? nó hoạt động tốt đối với tôi đăng xuất hoặc ẩn danh trên tài khoản công cộng.
ryan

41

11.11.2017
Kể từ khi Instagram thay đổi cách họ cung cấp dữ liệu này, hiện tại không có phương pháp nào ở trên hoạt động. Đây là cách mới để có được phương tiện của người dùng:
NHẬN https://instagram.com/graphql/query/?query_id=17888483320059182&variables={"id":"1951415043","first":20,"after":null}
Ở đâu:
query_id- giá trị vĩnh viễn: 17888483320059182 (lưu ý rằng nó có thể được thay đổi trong tương lai).
id- id của người dùng. Nó có thể đi kèm với danh sách người dùng. Để có được danh sách người dùng, bạn có thể sử dụng yêu cầu sau: GET https://www.instagram.com/web/search/topsearch/?context=blended&query=YOUR_QUERY
first- số lượng vật phẩm cần nhận.
after- id của mục cuối cùng nếu bạn muốn nhận các mục từ id đó.


Bạn có thể vui lòng cho tôi biết từ đâu để lấy query_id và id của người dùng không?
Vijaysinh Parmar

2
@VijaysinhParmar như tôi đã đề cập, query_idlà giá trị vĩnh viễn. Điều đó có nghĩa là nó luôn luôn là 17888483320059182 (ít nhất là trừ khi Instagram thay đổi nó). id của người dùng - là id của người dùng (đã chỉnh sửa câu trả lời của tôi một chút)
Footniko

1
Tôi không nhớ chính xác, ở đâu đó trên internet. Nhưng tôi không có bất kỳ mối quan hệ nào với Instagram, vì vậy trong trường hợp nó thay đổi, tôi sẽ không thể cho bạn biết cái mới :(
Footniko

1
Tự hỏi chính sách giới hạn tỷ lệ của phương pháp này là gì?
kkzxak47

1
Nếu bất cứ ai gặp vấn đề với việc yêu cầu URL này thông qua yêu cầu CURL, thì bạn cần lấy tiêu đề yêu cầu cookie (mở tab Mạng, sau khi chạy url, sao chép tiêu đề cookie và dán nó vào tiêu đề yêu cầu curl. Nếu bạn không làm điều này, bạn sẽ nhận được một lỗi truy cập 403 bị từ chối).
Anders

39

Tôi đã có thể nhận được phương tiện truyền thông gần đây nhất của người dùng bằng API sau mà không cần xác thực (bao gồm mô tả, lượt thích, số lượng bình luận).

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

Ví dụ

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

1
điều này cũng làm việc cho tôi. Nhưng khi "is_video = true", không có url video trong dữ liệu.
didikee

4
Đúng, bạn chỉ có thể nhận được hình thu nhỏ (không phải video) - thật không may, tôi không tìm thấy bất kỳ tài liệu chính thức nào cho việc này và tôi không biết API này có bị phản đối hay không hoặc nó sẽ được hỗ trợ trong bao lâu.
Michael

8
Kể từ 2018-04-13, điều này dường như không hoạt động nữa. Có thể do vụ bê bối dữ liệu Cambridge Analytica mới nhất của Facebook, họ đang thắt chặt mọi thứ. Bất kỳ đề xuất nào khác để có được dữ liệu người dùng cơ bản mà không cần xác thực?
BakerStreetSystems

2
Vâng, đã có lúc API này không hoạt động - Nhưng bây giờ nó lại hoạt động trở lại
Michael

4
Nó hoạt động với tôi, nhưng chỉ khi tôi đăng nhập vào Instagram.
zundi

16

Kể từ tuần trước, Instagram đã vô hiệu hóa /media/các url, tôi đã triển khai một cách giải quyết, hiện đang hoạt động khá tốt.

Để giải quyết vấn đề của mọi người trong chủ đề này, tôi đã viết bài này: https://github.com/whizzzkid/instagram-reverse-proxy

Nó cung cấp tất cả dữ liệu công khai của instagram bằng các điểm cuối sau:

Nhận phương tiện người dùng:

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

Nhận phương tiện người dùng với số lượng giới hạn:

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

Sử dụng JSONP:

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

API proxy cũng sẽ thêm URL trang tiếp theo và trang trước vào phản hồi để bạn không cần tính toán điều đó ở cuối.

Hi vọng mọi ngươi thich no!

Cảm ơn @ 350D vì đã phát hiện ra điều này :)


1
@rex cho đến khi họ thay đổi cách mọi thứ hoạt động vào cuối của họ, chúng tôi là tốt! Họ đã không làm phiền trong 3 năm qua, có lẽ họ sẽ không làm việc trong 3 năm tới
whizzzkid

3
@whizzzkid Thật không may, họ thay đổi nó. Tôi thấy rằng bạn nghĩ rằng điểm cuối của người dùng sẽ thực hiện mọi việc, nhưng có giới hạn cho các yêu cầu không đăng nhập người dùng. Có ý kiến ​​gì không?
nobilik

1
@nobilik giải pháp thay thế, igpi.ga/whizzzkid/media?count=3igpi.ga/graphql/query/?user_id=1606740656&count=3 sẽ trả về dữ liệu của bạn. Hãy nhớ rằng, các tham chiếu không xác định bị vô hiệu hóa cho các url này.
whizzzkid

1
@whizzzkid - Đã hoạt động! Cảm ơn rất nhiều - bạn là một học giả và một quý ông!
James Trickey

1
Tôi đang gặp lỗi "người giới thiệu bị từ chối truy cập". Có lẽ điều này không còn hoạt động?
khalid13

14

API Instagram yêu cầu xác thực người dùng thông qua OAuth để truy cập điểm cuối phương tiện gần đây cho người dùng. Hiện tại không có cách nào khác để lấy tất cả phương tiện cho người dùng.


4
Điều này vô nghĩa, nếu tôi muốn hiển thị phương tiện truyền thông của riêng mình trên trang web của riêng tôi, tại sao tôi cần tất cả những người muốn xem nó để có tài khoản instagram?
ninjasense

5
ninjasense - Tôi không nghĩ đó là cách nó hoạt động. Tôi nghĩ rằng trang web của bạn sẽ cần phải có một chút mã để truy vấn API Instagram với thông tin xác thực được cung cấp để thu hút phương tiện truyền thông của bạn. Sau đó, bạn sẽ hiển thị phương tiện truyền thông của mình cho bất kỳ người dùng trang web của bạn. Trang web của bạn sẽ là điều duy nhất cần để xác thực với Instagram.
Bill Rawlinson

9

Nếu bạn đang tìm cách tạo mã thông báo truy cập để sử dụng trên một tài khoản, bạn có thể thử cách này -> https://coderwall.com/p/cfgneq .

Tôi cần một cách để sử dụng api instagram để lấy tất cả các phương tiện truyền thông mới nhất cho một tài khoản cụ thể.


5
Cuối cùng, đây là những gì tôi đã làm: tạo một tài khoản mới, tạo mã thông báo truy cập cho nó và lưu trữ mã thông báo đó trong cấu hình máy chủ của tôi bên cạnh khóa API. Tuy nhiên, đây là một giải pháp kém cho các ứng dụng JS, vì nó yêu cầu chuyển mã thông báo truy cập của bạn cho người dùng (điều mà tôi đã thấy rất nhiều mã ví dụ làm). May mắn cho tôi, tôi có thể làm điều đó phía máy chủ.
Peeja

4
@CraigHeneveld Làm thế nào để bạn giữ cho mũ access_token được cập nhật? Nó không hết hạn trên bạn?
Ryan Ore

Liệu mã thông báo hết hạn một thời gian?
Monitus

Nếu bộ nhớ của tôi phục vụ cho tôi, khóa chỉ hết hạn nếu bạn thay đổi mật khẩu. Đây là một chủ đề khác về vấn đề này -> stackoverflow.com/questions/22753170/
Kẻ

Làm thế nào chúng ta có thể nhận được nhiều hình ảnh người dùng ?? Giống như chúng ta có thể vượt qua nhiều id người dùng được phân tách bằng ","?
Aadil Keshwani

9

Đây là một giải pháp đường ray. Đó là loại cửa sau, thực sự là cửa trước.

# 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

Đối tượng bạn nhận lại khác nhau tùy thuộc vào việc đó là tìm kiếm người dùng hay tìm kiếm thẻ. Tôi nhận được dữ liệu như thế này:

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

Sau đó tôi nhận được một trang kết quả khác bằng cách xây dựng một url theo cách sau:

  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'

giải pháp này hiệu quả với tôi, nhưng tôi gặp một số rắc rối với nó. Sau khi tải dữ liệu, máy chủ rails của tôi (sử dụng Rails 5.0.0, máy chủ Puma 3.6.0) khởi động lại không thể giải thích được ... Có giải pháp nào khả thi không?
Luis Eduardo Rojas Cabrera

8

Nhờ lược đồ API luôn thay đổi (và được thiết kế khủng khiếp) của Instagram, hầu hết các mục trên sẽ không còn hoạt động kể từ tháng 4 năm 2018.

Dưới đây là đường dẫn mới nhất để truy cập dữ liệu bài đăng cá nhân nếu bạn đang truy vấn trực tiếp API của họ bằng https://www.instagram.com/username/?__a=1phương pháp.

Giả sử JSONdữ liệu được trả về của bạn là $databạn có thể lặp qua từng kết quả bằng các ví dụ đường dẫn sau:

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 ....
}

Những điều chính trong sự thay đổi gần đây là graphqledge_owner_to_timeline_media.

Có vẻ như họ sẽ giết chết quyền truy cập API này đối với các khách hàng không phải là doanh nghiệp vào tháng 12 năm 2018, vì vậy hãy tận dụng tối đa trong khi bạn có thể.

Hy vọng nó sẽ giúp được ai đó;)


Điều này chỉ giúp tôi, tôi chỉ muốn hiển thị các bài đăng instagram mới nhất cho khách hàng. Cảm ơn!
deboner weston

1
instagram.com/username/?__a=1 đưa ra lỗi ngay bây giờ: Truy cập vào www.instagram.com đã bị từ chối Bạn không có quyền xem trang này. HTTP ERROR 403 có ý tưởng nào khác không?
Hese

1
Yep Instagram hiện đã giết chết điều này. "Để liên tục cải thiện quyền riêng tư và bảo mật của người dùng Instagram, chúng tôi đang đẩy nhanh sự phản đối của Nền tảng API Instagram, giúp các thay đổi sau có hiệu lực ngay lập tức. Chúng tôi hiểu rằng điều này có thể ảnh hưởng đến doanh nghiệp hoặc dịch vụ của bạn và chúng tôi đánh giá cao sự hỗ trợ của bạn trong việc giữ an toàn cho nền tảng của chúng tôi. Các khả năng này sẽ bị vô hiệu hóa ngay lập tức (được đặt trước vào ngày 31 tháng 7 năm 2018 hoặc ngày 11 tháng 12 năm 2018). "
gia vị

Nếu những gì tôi đang đọc là chính xác, nó sẽ không còn có thể truy xuất hình ảnh hoặc dữ liệu từ bất kỳ tài khoản "không kinh doanh" nào. Họ đang hoàn toàn tiêu diệt API nền tảng. Tôi đoán đó là ... instagram.com/developer/changelog
gia vị

1
@james_tookey sẽ không thể là bạn đời. Do những hạn chế quyền riêng tư mới của họ, nó sẽ không còn có thể truy vấn hoặc truy xuất người dùng / dữ liệu của tài khoản cá nhân, chỉ những người kinh doanh. Về cơ bản, họ chỉ giết tất cả việc sử dụng API cho tài khoản cá nhân.
gia vị

7

Câu đố

Javascript:

$(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

Chỉ muốn thêm vào câu trả lời @ 350D, vì thật khó để tôi hiểu.

Logic của tôi trong mã là tiếp theo:

Khi gọi API lần đầu tiên, tôi chỉ gọi https://www.instagram.com/_vull_ /media/. Khi tôi nhận được phản hồi, tôi kiểm tra giá trị boolean của more_available. Nếu nó là sự thật, tôi lấy ảnh cuối cùng từ mảng, lấy id của nó và sau đó gọi lại API Instagram nhưng lần này https://www.instagram.com/_vull_/media/?max_id=1400286183132701451_1642962433.

Điều quan trọng cần biết ở đây, Id này là Id của hình ảnh cuối cùng trong mảng. Vì vậy, khi yêu cầu maxId với id cuối cùng của hình ảnh trong mảng, bạn sẽ nhận được 20 hình ảnh tiếp theo, v.v.

Hy vọng điều này làm rõ.


4

Nếu bạn bỏ qua Oauth, có lẽ bạn sẽ không biết họ là người dùng instagram nào. Điều đó đang được nói có một số cách để có được hình ảnh instagram mà không cần xác thực.

  1. API của Instagram cho phép bạn xem những hình ảnh phổ biến nhất của người dùng mà không cần xác thực. Sử dụng điểm cuối sau: Đây là liên kết

  2. Instagram cung cấp nguồn cấp dữ liệu rss cho các thẻ tại đây .

  3. Các trang người dùng Instagram là công khai, vì vậy bạn có thể sử dụng PHP với CURL để lấy trang của họ và trình phân tích cú pháp DOM để tìm kiếm html cho các thẻ hình ảnh bạn muốn.


9
Có vẻ đã lỗi thời.
Burak Tokak

có thể bỏ qua xác thực cho instagram
JAck

3

Thêm một mẹo nữa, tìm kiếm ảnh bằng hashtags:

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

Ở đâu:

query_hash - giá trị vĩnh viễn (tôi tin rằng hàm băm của nó là 17888483320059182, có thể được thay đổi trong tương lai)

tag_name - Cái tiêu đề đã nói lên ý cần nói

first - số lượng vật phẩm cần nhận (tôi không biết tại sao, nhưng giá trị này không hoạt động như mong đợi. Số lượng ảnh trả về thực tế lớn hơn một chút so với giá trị nhân với 4,5 (khoảng 110 cho giá trị 25 và khoảng 460 cho giá trị 100))

after- id của mục cuối cùng nếu bạn muốn nhận các mục từ id đó. Giá trị end_cursortừ phản hồi JSON có thể được sử dụng ở đây.


Làm thế nào bạn tìm thấy điều này?
ekntrtmz


3

Nếu bạn muốn tìm kiếm người dùng mà không cần có clientID và mã thông báo truy cập:

1: Nếu bạn muốn tìm kiếm tất cả người dùng có tên giống với từ tìm kiếm của bạn:

thay thế SeachName bằng văn bản bạn muốn tìm kiếm:

https://www.instagram.com/web/search/topsearch/?query=SearchName

2: nếu bạn muốn tìm kiếm chính xác tên người dùng:

thay thế Tên người dùng bằng Tên tìm kiếm mong muốn của bạn:

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


2

Bạn có thể sử dụng API này để lấy thông tin công cộng của người sử dụng instagram:
https://api.lityapp.com/instagrams/thebrainscoop?limit=2

Nếu bạn không đặt tham số giới hạn, các bài viết được giới hạn ở mức 12 theo mặc định

này api được tạo trong SpringBoot với HtmlUnit như bạn có thể thấy trong mã:

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);
}


Đó là một ví dụ về phản ứng:

{
  "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
        }
      ]
    }
  ]
}

Tôi có thể lấy dữ liệu bằng userid (pk)
SAURABH RATHOD

Xin lỗi @SAURABHRATHOD Tôi đã thử nhưng tôi chưa tìm được cách nào để làm điều này. Tôi sẽ rất hài lòng nếu ai đó giải quyết điều này. Cảm ơn các bình luận.
Ruan Barroso

2

Tôi thực sự cần chức năng này nhưng cho Wordpress. Tôi phù hợp và nó hoạt động hoàn hảo

<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

Mã nodejs bên dưới sẽ loại bỏ các hình ảnh phổ biến từ Trang Instagram. Hàm 'ScrapeInstagramPage' đảm nhiệm hiệu ứng lão hóa bài.

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});

Thử nó ở đây

Ví dụ: Đối với một URL ' https://www.instagram.com/dress_blouse_designer/ ', người ta có thể gọi hàm

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

Tôi chỉ có thể nhìn thấy 12 bài viết đầu tiên, làm thế nào tôi có thể nhận được tất cả chúng?
rahul gawale

0

Điều này hoạt động bằng cách sử dụng một cuộc gọi ajax đơn giản và lặp lại các đường dẫn hình ảnh.

        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>"
                );
            });
        })

Nó hoạt động với tôi, nhưng chỉ khi tôi đăng nhập vào Instagram.
zundi

-1

Dưới đây là một tập lệnh php tải xuống các hình ảnh và tạo một tệp html với các liên kết trên các hình ảnh. Tín dụng 350D cho phiên bản php, đây chỉ là công phu..Tôi sẽ đề nghị đặt đây là một công việc định kỳ và sa thải theo cách bạn thường cần. Đã xác minh làm việc kể từ tháng 5 năm 2019 .

<?
$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);
?>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.