pinterest-dl 1.0.0 → 1.0.3

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.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +60 -9
  3. data/lib/pinterest-dl.rb +75 -18
  4. metadata +3 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 71ad1b053f92b611430a8e44a0a678037daa37577afaa1a0ff5dd04a3f53329b
4
- data.tar.gz: 2754556eacec0edfcb5f52700773bc9d725597c01c6f512f692fd1eff3c706ac
3
+ metadata.gz: 73cae48cd87360325168ee188b8a67b25944402f33857a61dee4ea3a13457f91
4
+ data.tar.gz: 313a17fd00772aa8980ee8389dc5bd934b8217225f4e4b11f130ad4882e629c0
5
5
  SHA512:
6
- metadata.gz: 55f78b7fe0ffb4d69f17f65b5bdf580d985a8418780145a8717c2a166c61ba123c3de7e64ed6cea1394bc6588db3c0279fe07e621403f0155f71c52eaef3b34b
7
- data.tar.gz: b662d4914cd490516c54f5c0e6b8b42476c6781e65b7a97846381a1be596295725b3525187338d8a62cee79b46b6d9bdf322ab3c26d66bf752d49027290aae43
6
+ metadata.gz: e08fc0e08bec2a47a91659d10b1ba3a87e6d2c70e81fc27134366768108ebf3e1a5f10bfea2dc3391c63fa038eb9daba58594ffd8c5997338b240dd21fcaa558
7
+ data.tar.gz: 7bcfe71875c82f31ddaf9e27a0f648b646bb6381045830d03d6ee0a8fb561283e8a0eb4e85036915a6d71e6f5865e05f0aa4a5e0658f601b593f8e5a6f42f714
data/README.md CHANGED
@@ -1,12 +1,29 @@
1
+ <div align="center">
2
+
1
3
  # pinterest-dl
2
4
 
3
- Get direct image and video URLs from Pinterest:)
5
+ ---
4
6
 
7
+ [![Gem Downloads](https://img.shields.io/gem/dt/pinterest-dl)](https://rubygems.org/gems/pinterest-dl)
8
+ [![License](https://img.shields.io/badge/License-MIT-green)](LICENSE)
9
+ [![Ruby](https://img.shields.io/badge/Ruby-2.5+-red)](https://www.ruby-lang.org/)
5
10
 
11
+ <img src="https://img.icons8.com/color/96/000000/pinterest--v1.png" width="80">
6
12
 
7
- ```ruby
8
- gem install pinterest-dl
13
+ </div>
14
+
15
+ ---
16
+
17
+ Get direct image and video URLs from Pinterest.
18
+
19
+ ![Demo](https://github.com/monji024/pinterest-dl/raw/main/test.gif)
20
+
21
+ > **Note:** Users in Iran may need a VPN to access Pinterest.
9
22
 
23
+ ## Installation
24
+
25
+ ```bash
26
+ gem install pinterest-dl
10
27
  ```
11
28
 
12
29
  ## Usage
@@ -15,11 +32,45 @@ gem install pinterest-dl
15
32
  require 'pinterest-dl'
16
33
  ```
17
34
 
35
+ ### Get Image URL
36
+
37
+ ```ruby
38
+ url = PinterestDL.get_image_url('https://www.pinterest.com/pin/example/')
39
+ ```
40
+
41
+ ### Get Video URL
42
+
43
+ ```ruby
44
+ url = PinterestDL.get_video_url('https://www.pinterest.com/pin/example/')
45
+ ```
46
+
47
+ ### Search Pins
48
+
49
+ ```ruby
50
+ # Search for pins with a specific query
51
+ results = PinterestDL.search('nature landscape', limit: 10)
52
+
53
+ # Returns an array of pin objects with:
54
+ # id, pin_url, title, description, image_url, video_url
55
+
56
+ # Get only image URLs from search results
57
+ images = PinterestDL.search_images('sunset', limit: 5)
58
+ # => ["https://i.pinimg.com/originals/...", ...]
59
+
60
+ # Get only video URLs from search results
61
+ videos = PinterestDL.search_videos('tutorial', limit: 3)
62
+ # => ["https://v.pinimg.com/videos/...", ...]
63
+
64
+ # Get search results as JSON
65
+ json_results = PinterestDL.search_json('anime art', limit: 20)
66
+ # => Returns formatted JSON string
67
+ ```
68
+
69
+ ## Links
70
+
71
+ - [RubyGems](https://rubygems.org/gems/pinterest-dl)
72
+ - [GitHub](https://github.com/monji024/pinterest-dl)
18
73
 
19
- # Get image url
20
- url = PinterestDL.get_image_url('link')
21
- # => "https://i.pinimg.com/originals/8e/2a/..."
74
+ ## License
22
75
 
23
- # Get video url
24
- url = PinterestDL.get_video_url('link')
25
- # => "https://v.pinimg.com/videos/..."
76
+ MIT © [monji024](https://github.com/monji024)
data/lib/pinterest-dl.rb CHANGED
@@ -1,8 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
- # pinterest-dl.rb
3
2
  # Pinterest downloader
4
3
  # creator: Monji
5
- # ver: 1.0.0
4
+ # ver: 1.0.3
6
5
  # github: https://github.com/monji024/pinterest-dl
7
6
 
8
7
  require 'net/http'
@@ -12,11 +11,10 @@ require 'openssl'
12
11
 
13
12
 
14
13
  module PinterestDL
15
- ver = '1.0.0'.freeze
16
- craetor = 'Monji'.freeze
14
+ ver = '1.0.3'.freeze
17
15
  github = 'https://github.com/monji024/pinterest-dl'.freeze
18
16
 
19
- puts "pinterest-dl v#{ver} by #{craetor} (#{github})\n\n"
17
+ puts "pinterest-dl v#{ver} (#{github})\n\n"
20
18
 
21
19
  USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'.freeze
22
20
 
@@ -28,7 +26,6 @@ module PinterestDL
28
26
  # 1 -> json-ld
29
27
  url = extract_json_ld(html, 'ImageObject')
30
28
  return url if url
31
-
32
29
  # 2 -> open graph
33
30
  match = html.match(%r{<meta[^>]*property="og:image"[^>]*content="([^"]+)"})
34
31
  if match
@@ -36,7 +33,6 @@ module PinterestDL
36
33
  puts "image url: #{url}"
37
34
  return url
38
35
  end
39
-
40
36
  # 3 -> direct i.pinimg.com patterns
41
37
  match = html.match(%r{https://i\.pinimg\.com/(?:originals|474x|236x|736x)/[^"\s]+})
42
38
  if match
@@ -46,8 +42,7 @@ module PinterestDL
46
42
  puts "#{green}image url :#{reset} #{url}"
47
43
  return url
48
44
  end
49
-
50
- puts 'No found'
45
+ puts 'No found:)'
51
46
  nil
52
47
  end
53
48
 
@@ -63,7 +58,6 @@ module PinterestDL
63
58
  puts "ok : #{url}"
64
59
  return url
65
60
  end
66
-
67
61
  # 2 -> Open Graph video
68
62
  match = html.match(%r{<meta[^>]*property="og:video"[^>]*content="([^"]+)"})
69
63
  if match
@@ -71,7 +65,6 @@ module PinterestDL
71
65
  puts "video url: #{url}"
72
66
  return url
73
67
  end
74
-
75
68
  # 3 -> contentUrl in page source
76
69
  match = html.match(/"contentUrl"\s*:\s*"([^"]+\.mp4[^"]*)"/)
77
70
  if match
@@ -85,7 +78,76 @@ module PinterestDL
85
78
  puts 'No found'
86
79
  nil
87
80
  end
88
-
81
+ def search(query, limit: 25)
82
+ source_path = "/search/pins/?q=#{URI.encode_www_form_component(query)}"
83
+ home_uri = URI("https://www.pinterest.com#{source_path}")
84
+ http = Net::HTTP.new(home_uri.host, home_uri.port)
85
+ http.use_ssl = true
86
+ http.open_timeout = 10
87
+ http.read_timeout = 20
88
+ home_req = Net::HTTP::Get.new(home_uri, 'User-Agent' => USER_AGENT)
89
+ home_resp = http.request(home_req)
90
+ cookies = (home_resp.get_fields('set-cookie') || []).map { |c| c.split(';').first }
91
+ cookie_header = cookies.join('; ')
92
+ csrf = cookies.find { |c| c.start_with?('csrftoken=') }&.split('=', 2)&.last || 'undefined'
93
+ data = {
94
+ options: { query: query, scope: 'pins', page_size: limit },
95
+ context: {}}.to_json
96
+ res_uri = URI('https://www.pinterest.com/resource/BaseSearchResource/get/')
97
+ res_uri.query = URI.encode_www_form('source_url' => source_path, 'data' => data)
98
+ req = Net::HTTP::Get.new(res_uri)
99
+ req['User-Agent'] = USER_AGENT
100
+ req['Accept'] = 'application/json, text/javascript, */*, q=0.01'
101
+ req['X-Requested-With'] = 'XMLHttpRequest'
102
+ req['X-Pinterest-PWS-Handler'] = 'www/search/[scope].js'
103
+ req['X-CSRFToken'] = csrf
104
+ req['Referer'] = home_uri.to_s
105
+ req['Cookie'] = cookie_header
106
+ resp = http.request(req)
107
+ unless resp.is_a?(Net::HTTPSuccess)
108
+ puts "\e[31msearch http err!:\e[0m #{resp.code}"
109
+ return []
110
+ end
111
+ json = begin
112
+ JSON.parse(resp.body)
113
+ rescue JSON::ParserError
114
+ nil
115
+ end
116
+ return [] unless json
117
+ raw_results = (json.dig('resource_response', 'data', 'results') || []).first(limit)
118
+ pins = raw_results.filter_map do |r|
119
+ id = r['id']
120
+ next nil unless id
121
+ orig_image = r.dig('images', 'orig', 'url')
122
+ fallback_image = r['images']&.values&.map { |v| v.is_a?(Hash) ? v['url'] : nil }&.compact&.last
123
+ image_url = orig_image || fallback_image
124
+ video_url = r.dig('videos', 'video_list')&.values&.first&.dig('url')
125
+ {
126
+ id: id,
127
+ pin_url: "https://www.pinterest.com/pin/#{id}/",
128
+ title: r['title'] || r['grid_title'],
129
+ description: r['description'],
130
+ image_url: image_url,
131
+ video_url: video_url
132
+ }
133
+ end
134
+ green = "\e[32m"
135
+ reset = "\e[0m"
136
+ puts "#{green}found #{pins.size} pin(s) for \"#{query}\"#{reset}"
137
+ pins
138
+ rescue StandardError => e
139
+ puts "\e[31msearch err!:\e[0m #{e.message}"
140
+ []
141
+ end
142
+ def search_json(query, limit: 25)
143
+ JSON.pretty_generate(search(query, limit: limit))
144
+ end
145
+ def search_images(query, limit: 25)
146
+ search(query, limit: limit).filter_map { |p| p[:image_url] }
147
+ end
148
+ def search_videos(query, limit: 25)
149
+ search(query, limit: limit).filter_map { |p| p[:video_url] }
150
+ end
89
151
  private
90
152
 
91
153
  def fetch_html(url)
@@ -95,9 +157,7 @@ module PinterestDL
95
157
  http.max_retries = 2
96
158
  http.open_timeout = 10
97
159
  http.read_timeout = 20
98
-
99
160
  resp = http.request(Net::HTTP::Head.new(uri, 'User-Agent' => USER_AGENT))
100
-
101
161
  5.times do
102
162
  break unless resp.is_a?(Net::HTTPRedirection)
103
163
  location = resp['location']
@@ -107,11 +167,9 @@ module PinterestDL
107
167
  http.use_ssl = (uri.scheme == 'https')
108
168
  resp = http.request(Net::HTTP::Head.new(uri, 'User-Agent' => USER_AGENT))
109
169
  end
110
-
111
170
  # get final page
112
171
  req = Net::HTTP::Get.new(uri, 'User-Agent' => USER_AGENT)
113
172
  resp = http.request(req)
114
-
115
173
  return resp.body if resp.is_a?(Net::HTTPSuccess)
116
174
  nil
117
175
  rescue StandardError => e
@@ -123,7 +181,6 @@ module PinterestDL
123
181
  def extract_json_ld(html, type)
124
182
  match = html.match(%r{<script[^>]*type="application/ld\+json"[^>]*>(.*?)</script>}m)
125
183
  return nil unless match
126
-
127
184
  begin
128
185
  data = JSON.parse(match[1])
129
186
  data = data[0] if data.is_a?(Array) && !data.empty?
@@ -133,4 +190,4 @@ module PinterestDL
133
190
  nil
134
191
  end
135
192
  end
136
- end
193
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pinterest-dl
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Monji
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2026-02-12 00:00:00.000000000 Z
10
+ date: 2026-07-28 00:00:00.000000000 Z
11
11
  dependencies: []
12
12
  description: Simple Pinterest Downloader Tool:)
13
13
  email: hoseinmonjiofficial@gmail.com
@@ -39,5 +39,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
39
39
  requirements: []
40
40
  rubygems_version: 3.6.3
41
41
  specification_version: 4
42
- summary: Extract direct image/video URLs from Pinterest!!!
42
+ summary: Extract direct image/video/search URLs from Pinterest!!!
43
43
  test_files: []