instagram_user 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/README.md +13 -5
- data/instagram_user.gemspec +3 -2
- data/lib/instagram_user/client.rb +70 -8
- data/lib/instagram_user/version.rb +1 -1
- metadata +19 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 395fc13b93a50fa026b63b06ebef8ec4a0ea6aa1807bf5fb65b4e25c7db34f4d
|
4
|
+
data.tar.gz: 8511e7ee0deca25b3b4a9f1d1562c17755bbe77de87af62ac517d46153f8ba8b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6026802ae89b4fc471f6710747aa00a6f0ada1ec7b7dd15e86d52b351b761fba573f08da07a0759b2e69f56eb3d83e841afe76c45c61e8e32ae29305d4d0549c
|
7
|
+
data.tar.gz: 34e00dc9fc9663a714cb099ee8e89fdbc73944da2774ef0c14e752210935d4272d3232cacc6e31a009dfad3af99f67e7f673f21e313e8cafb9c0a6bf83df8f46
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -5,13 +5,11 @@
|
|
5
5
|
[![Coverage Status](https://img.shields.io/coveralls/YuzuruS/instagram_user.svg?style=flat)](https://coveralls.io/r/YuzuruS/instagram_user?branch=master)
|
6
6
|
[![Code Climate](https://img.shields.io/codeclimate/github/YuzuruS/instagram_user.svg?style=flat)](https://codeclimate.com/github/YuzuruS/instagram_user)
|
7
7
|
|
8
|
-
Client for the Instagram Web Service
|
9
|
-
|
10
|
-
It may be unusable in the future because of using private api in the future.
|
8
|
+
Client for the Instagram Web Service without Instagram API.
|
9
|
+
Implemented in Ruby using the Selenium and Mechanize module.
|
11
10
|
|
12
11
|
## Installation
|
13
12
|
|
14
|
-
Add this line to your application's Gemfile:
|
15
13
|
|
16
14
|
```ruby
|
17
15
|
gem 'instagram_user'
|
@@ -28,13 +26,23 @@ Or install it yourself as:
|
|
28
26
|
## Usage
|
29
27
|
|
30
28
|
```ruby
|
31
|
-
cli = InstagramUser.new(user_name: '
|
29
|
+
cli = InstagramUser.new(user_name: 'YOUR_USER_NAME', password: 'YOUR_PASSWORD')
|
32
30
|
|
31
|
+
# Get the follow list for the specified user
|
33
32
|
follows = cli.get_follows('yuzuru_dev')
|
34
33
|
# => ["yudsuzuk", "instagram"]
|
35
34
|
|
35
|
+
# Get the follower list for the specified user
|
36
36
|
followers = cli.get_followers('yuzuru_dev')
|
37
37
|
# => ["yudsuzuk"]
|
38
|
+
|
39
|
+
# Follow the specified user
|
40
|
+
res = cli.create_follow('yuzuru_dev')
|
41
|
+
# => true or false
|
42
|
+
|
43
|
+
# Unfollow the specified user
|
44
|
+
res = cli.delete_follow('yuzuru_dev')
|
45
|
+
# => true or false
|
38
46
|
```
|
39
47
|
|
40
48
|
## Contributing
|
data/instagram_user.gemspec
CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.authors = ["Yuzuru Suzuki"]
|
9
9
|
spec.email = ["navitima@gmail.com"]
|
10
10
|
|
11
|
-
spec.summary =
|
12
|
-
spec.description =
|
11
|
+
spec.summary = "Client for the Instagram using scraping"
|
12
|
+
spec.description = "Client for the Instagram Web Service without Instagram API. Implemented in Ruby using the Selenium and Mechanize module."
|
13
13
|
spec.homepage = "https://github.com/YuzuruS/instagram_user"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
@@ -30,6 +30,7 @@ Gem::Specification.new do |spec|
|
|
30
30
|
spec.require_paths = ["lib"]
|
31
31
|
|
32
32
|
spec.add_dependency 'mechanize'
|
33
|
+
spec.add_dependency 'selenium-webdriver'
|
33
34
|
spec.add_development_dependency "bundler", "~> 1.15"
|
34
35
|
spec.add_development_dependency "rake"
|
35
36
|
spec.add_development_dependency "guard-rspec"
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'mechanize'
|
2
|
+
require 'selenium-webdriver'
|
2
3
|
require 'json'
|
3
4
|
require 'instagram_user/version'
|
4
5
|
|
@@ -32,6 +33,7 @@ module InstagramUser
|
|
32
33
|
@session = Mechanize.new
|
33
34
|
@user_ids = {}
|
34
35
|
logined_session
|
36
|
+
selenium_setting
|
35
37
|
end
|
36
38
|
|
37
39
|
def get_follows(user_name)
|
@@ -44,10 +46,72 @@ module InstagramUser
|
|
44
46
|
fetch_all_user_names(user_id, USER_MAP[:follower])
|
45
47
|
end
|
46
48
|
|
49
|
+
def create_follow(user_name)
|
50
|
+
@driver.get "https://www.instagram.com/#{user_name}"
|
51
|
+
begin
|
52
|
+
@wait.until { !@driver.find_elements(:xpath, '//article//button').empty? }
|
53
|
+
rescue => e
|
54
|
+
return false
|
55
|
+
end
|
56
|
+
|
57
|
+
color = @driver.find_element(:xpath, '//article//button').css_value("color")
|
58
|
+
return false if color != "rgba(255, 255, 255, 1)"
|
59
|
+
|
60
|
+
@driver.find_element(:xpath, '//article//button').click
|
61
|
+
sleep(2)
|
62
|
+
|
63
|
+
@driver.get "https://www.instagram.com/#{name.user_name}"
|
64
|
+
@wait.until { !@driver.find_elements(:xpath, '//article//button').empty? }
|
65
|
+
color = @driver.find_element(:xpath, '//article//button').css_value("color")
|
66
|
+
(color == "rgba(255, 255, 255, 1)") ? false : true
|
67
|
+
end
|
68
|
+
|
69
|
+
def delete_follow(user_name)
|
70
|
+
@driver.get "https://www.instagram.com/#{user_name}"
|
71
|
+
begin
|
72
|
+
@wait.until { !@driver.find_elements(:xpath, '//article//button').empty? }
|
73
|
+
rescue => e
|
74
|
+
return false
|
75
|
+
end
|
76
|
+
|
77
|
+
color = @driver.find_element(:xpath, '//article//button').css_value("color")
|
78
|
+
return false if color == "rgba(255, 255, 255, 1)"
|
79
|
+
|
80
|
+
@driver.find_element(:xpath, '//article//button').click
|
81
|
+
sleep(2)
|
82
|
+
|
83
|
+
@driver.get "https://www.instagram.com/#{name.user_name}"
|
84
|
+
@wait.until { !@driver.find_elements(:xpath, '//article//button').empty? }
|
85
|
+
color = @driver.find_element(:xpath, '//article//button').css_value("color")
|
86
|
+
(color != "rgba(255, 255, 255, 1)") ? false : true
|
87
|
+
end
|
88
|
+
|
47
89
|
private
|
48
90
|
|
91
|
+
def selenium_setting
|
92
|
+
options = Selenium::WebDriver::Chrome::Options.new
|
93
|
+
options.add_argument("--user-agent=#{@user_agent}")
|
94
|
+
#options.add_argument('--headless')
|
95
|
+
@driver = Selenium::WebDriver.for :chrome, options: options
|
96
|
+
@session.cookie_jar.cookies.each do |c|
|
97
|
+
cookie_hash = {
|
98
|
+
name: c.name,
|
99
|
+
value: c.value,
|
100
|
+
path: c.path,
|
101
|
+
secure: c.secure,
|
102
|
+
expires: c.expires,
|
103
|
+
domain: c.domain,
|
104
|
+
for_domain: c.for_domain,
|
105
|
+
httponly: c.httponly,
|
106
|
+
max_age: c.max_age
|
107
|
+
}
|
108
|
+
@driver.manage.add_cookie(cookie_hash)
|
109
|
+
end
|
110
|
+
@wait = Selenium::WebDriver::Wait.new(timeout: 60)
|
111
|
+
end
|
112
|
+
|
49
113
|
def get_user_id(user_name)
|
50
|
-
url = USER_INFO_URL
|
114
|
+
url = format USER_INFO_URL, user_name
|
51
115
|
page = @session.get(url)
|
52
116
|
json = JSON.parse(page.body)
|
53
117
|
@user_ids[user_name] = json["user"]["id"]
|
@@ -60,15 +124,13 @@ module InstagramUser
|
|
60
124
|
end
|
61
125
|
|
62
126
|
def login_http_headers
|
63
|
-
|
64
|
-
"user-agent" => @user_agent,
|
65
|
-
"referer" => @referer,
|
127
|
+
default_http_headers.update(
|
66
128
|
"x-csrftoken" => "null",
|
67
129
|
"cookie" => "sessionid=null; csrftoken=null"
|
68
|
-
|
130
|
+
)
|
69
131
|
end
|
70
132
|
|
71
|
-
def
|
133
|
+
def default_http_headers
|
72
134
|
{
|
73
135
|
"user-agent" => @user_agent,
|
74
136
|
"referer" => @referer
|
@@ -101,8 +163,8 @@ module InstagramUser
|
|
101
163
|
first: @num_users
|
102
164
|
}
|
103
165
|
variables[:after] = after unless after.nil?
|
104
|
-
url = BASE_URL
|
105
|
-
@session.request_headers =
|
166
|
+
url = format BASE_URL, request_params[:query_hash], JSON.generate(variables)
|
167
|
+
@session.request_headers = default_http_headers
|
106
168
|
page = @session.get(url)
|
107
169
|
json = JSON.parse(page.body)
|
108
170
|
edge = json["data"]["user"][request_params[:edge]]
|
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: 0.1.
|
4
|
+
version: 0.1.2
|
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-02-
|
11
|
+
date: 2018-02-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mechanize
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: selenium-webdriver
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: bundler
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -136,8 +150,8 @@ dependencies:
|
|
136
150
|
- - ">="
|
137
151
|
- !ruby/object:Gem::Version
|
138
152
|
version: '0'
|
139
|
-
description:
|
140
|
-
|
153
|
+
description: Client for the Instagram Web Service without Instagram API. Implemented
|
154
|
+
in Ruby using the Selenium and Mechanize module.
|
141
155
|
email:
|
142
156
|
- navitima@gmail.com
|
143
157
|
executables: []
|
@@ -185,5 +199,5 @@ rubyforge_project:
|
|
185
199
|
rubygems_version: 2.7.4
|
186
200
|
signing_key:
|
187
201
|
specification_version: 4
|
188
|
-
summary:
|
202
|
+
summary: Client for the Instagram using scraping
|
189
203
|
test_files: []
|