instagram_user 1.0.2 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +5 -1
- data/instagram_user.gemspec +1 -1
- data/lib/instagram_user/client.rb +32 -15
- data/lib/instagram_user/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 674bceac91ab64010c5a06a357c05a73760e6a4fe863e6c89def4b58fd8b18fa
|
4
|
+
data.tar.gz: afd2d5751f66300b54ee91094993b1a27282577a014ad5884f0af6a050a6c699
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d58053555b985c76b71507d7cad0b38f4997e466ebfde814ebe883e4196cb460e1bedb0c0dd2523865ebee936226e6a7685500b6309d705c6e706470d2da3166
|
7
|
+
data.tar.gz: 826420c446d6c05ce3cae5c362b6c943489c6c4a2ae0f90a8d4e671c811923a4f543485cc561d292053ff0b94cf4029320d242d8b6e67e8edf8c7c6a9199aa55
|
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
[](http://badge.fury.io/rb/instagram_user)
|
4
4
|
[](https://coveralls.io/r/YuzuruS/instagram_user?branch=master)
|
5
|
-
[](https://codeclimate.com/github/YuzuruS/instagram_user/maintainability)
|
6
6
|
|
7
7
|
Client for the Instagram Web Service without Instagram API.
|
8
8
|
Implemented in Ruby using the Selenium and Mechanize module.
|
@@ -42,6 +42,10 @@ res = cli.create_follow('yuzuru_dev')
|
|
42
42
|
# Unfollow the specified user
|
43
43
|
res = cli.delete_follow('yuzuru_dev')
|
44
44
|
# => true or false
|
45
|
+
|
46
|
+
# get media for the specified tag
|
47
|
+
res = cli.get_medias_by_tag('japanesefood')
|
48
|
+
# => {"recent" => [...], "popularity" => [...]}
|
45
49
|
```
|
46
50
|
|
47
51
|
## Contributing
|
data/instagram_user.gemspec
CHANGED
@@ -33,7 +33,7 @@ Gem::Specification.new do |spec|
|
|
33
33
|
spec.add_dependency 'selenium-webdriver'
|
34
34
|
spec.add_development_dependency "bundler", "~> 1.15"
|
35
35
|
spec.add_development_dependency "rake"
|
36
|
-
spec.add_development_dependency 'pry'
|
36
|
+
spec.add_development_dependency 'pry-byebug'
|
37
37
|
spec.add_development_dependency "guard-rspec"
|
38
38
|
spec.add_development_dependency "guard"
|
39
39
|
spec.add_development_dependency "terminal-notifier"
|
@@ -2,7 +2,6 @@ require 'mechanize'
|
|
2
2
|
require 'selenium-webdriver'
|
3
3
|
require 'json'
|
4
4
|
require 'instagram_user/version'
|
5
|
-
require 'pry'
|
6
5
|
|
7
6
|
module InstagramUser
|
8
7
|
class Client
|
@@ -10,8 +9,8 @@ module InstagramUser
|
|
10
9
|
BASE_URL = 'https://www.instagram.com/graphql/query/?query_hash=%s&variables=%s'.freeze
|
11
10
|
LOGIN_URL = 'https://www.instagram.com/accounts/login/ajax/'.freeze
|
12
11
|
USER_INFO_URL = 'https://www.instagram.com/%s/?__a=1'.freeze
|
12
|
+
MEDIA_JSON_BY_TAG_URL = 'https://www.instagram.com/explore/tags/%s/?__a=1&max_id=%s'.freeze
|
13
13
|
DEFAULT_USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36'.freeze
|
14
|
-
DEFAULT_MAX_NUM_USERS = 3000
|
15
14
|
DEFAULT_REFERER = 'https://www.instagram.com/'.freeze
|
16
15
|
|
17
16
|
USER_MAP = {
|
@@ -30,21 +29,22 @@ module InstagramUser
|
|
30
29
|
@password = (ENV['INSTAGRAM_PASSWORD'] || options[:password])
|
31
30
|
@user_agent = (ENV['INSTAGRAM_USER_AGENT'] || options[:user_agent] || DEFAULT_USER_AGENT)
|
32
31
|
@referer = (ENV['INSTAGRAM_REFERER'] || options[:referer] || DEFAULT_REFERER)
|
33
|
-
@num_users = (ENV['INSTAGRAM_NUM_USERS'] || options[:num_users] || DEFAULT_MAX_NUM_USERS)
|
34
32
|
@session = Mechanize.new
|
35
33
|
@user_ids = {}
|
36
|
-
|
37
|
-
|
34
|
+
|
35
|
+
return if @user_name.nil? || @password.nil?
|
36
|
+
mechanize_login_setting
|
37
|
+
selenium_login_setting unless options[:selenium] == false
|
38
38
|
end
|
39
39
|
|
40
|
-
def get_follows(user_name)
|
40
|
+
def get_follows(user_name, num_users = 3000)
|
41
41
|
user_id = @user_ids[user_name].nil? ? get_user_id(user_name) : @user_ids[user_name]
|
42
|
-
fetch_all_user_names(user_id, USER_MAP[:follow])
|
42
|
+
fetch_all_user_names(user_id, USER_MAP[:follow], num_users)
|
43
43
|
end
|
44
44
|
|
45
|
-
def get_followers(user_name)
|
45
|
+
def get_followers(user_name, num_users = 3000)
|
46
46
|
user_id = @user_ids[user_name].nil? ? get_user_id(user_name) : @user_ids[user_name]
|
47
|
-
fetch_all_user_names(user_id, USER_MAP[:follower])
|
47
|
+
fetch_all_user_names(user_id, USER_MAP[:follower], num_users)
|
48
48
|
end
|
49
49
|
|
50
50
|
def create_follow(user_name)
|
@@ -71,6 +71,23 @@ module InstagramUser
|
|
71
71
|
(color == false || color != "rgba(255, 255, 255, 1)") ? false : true
|
72
72
|
end
|
73
73
|
|
74
|
+
def get_medias_by_tag(tag_name, req_num = 1)
|
75
|
+
max_id = nil
|
76
|
+
tags = {"recent" => [], "popularity" => []}
|
77
|
+
|
78
|
+
req_num.times do
|
79
|
+
url = format MEDIA_JSON_BY_TAG_URL, tag_name, max_id
|
80
|
+
page = @session.get(url)
|
81
|
+
json = JSON.parse(page.body)
|
82
|
+
hastags = json["graphql"]["hashtag"]
|
83
|
+
tags["recent"] += hastags["edge_hashtag_to_media"]["edges"]
|
84
|
+
tags["popularity"] = hastags["edge_hashtag_to_top_posts"]["edges"] if max_id.nil?
|
85
|
+
break unless hastags["edge_hashtag_to_media"]["page_info"]["has_next_page"]
|
86
|
+
max_id = hastags["edge_hashtag_to_media"]["page_info"]["end_cursor"]
|
87
|
+
end
|
88
|
+
tags
|
89
|
+
end
|
90
|
+
|
74
91
|
private
|
75
92
|
|
76
93
|
def get_follow_btn_color(user_name)
|
@@ -83,7 +100,7 @@ module InstagramUser
|
|
83
100
|
@driver.find_element(:xpath, '//article//button').css_value("color")
|
84
101
|
end
|
85
102
|
|
86
|
-
def
|
103
|
+
def selenium_login_setting
|
87
104
|
options = Selenium::WebDriver::Chrome::Options.new
|
88
105
|
options.add_argument("--user-agent=#{@user_agent}")
|
89
106
|
options.add_argument('--headless')
|
@@ -117,7 +134,7 @@ module InstagramUser
|
|
117
134
|
@user_ids[user_name]
|
118
135
|
end
|
119
136
|
|
120
|
-
def
|
137
|
+
def mechanize_login_setting
|
121
138
|
@session.request_headers = login_http_headers
|
122
139
|
@session.post(LOGIN_URL, user_info)
|
123
140
|
end
|
@@ -143,12 +160,12 @@ module InstagramUser
|
|
143
160
|
}
|
144
161
|
end
|
145
162
|
|
146
|
-
def fetch_all_user_names(user_id, request_params)
|
163
|
+
def fetch_all_user_names(user_id, request_params, num_users)
|
147
164
|
after = nil
|
148
165
|
user_names = []
|
149
166
|
|
150
167
|
loop do
|
151
|
-
res = fetch_user_names(user_id, request_params, after)
|
168
|
+
res = fetch_user_names(user_id, request_params, num_users, after)
|
152
169
|
user_names += res[:user_names]
|
153
170
|
break unless res[:has_next]
|
154
171
|
after = res[:after]
|
@@ -156,10 +173,10 @@ module InstagramUser
|
|
156
173
|
user_names
|
157
174
|
end
|
158
175
|
|
159
|
-
def fetch_user_names(user_id, request_params, after
|
176
|
+
def fetch_user_names(user_id, request_params, num_users, after)
|
160
177
|
variables = {
|
161
178
|
id: user_id,
|
162
|
-
first:
|
179
|
+
first: num_users
|
163
180
|
}
|
164
181
|
variables[:after] = after unless after.nil?
|
165
182
|
url = format BASE_URL, request_params[:query_hash], JSON.generate(variables)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: instagram_user
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yuzuru Suzuki
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-03-
|
11
|
+
date: 2018-03-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mechanize
|
@@ -67,7 +67,7 @@ dependencies:
|
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name: pry
|
70
|
+
name: pry-byebug
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - ">="
|