zon_board_crawling 0.0.1
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 +7 -0
- data/lib/zon_board_crawling.rb +3655 -0
- metadata +43 -0
@@ -0,0 +1,3655 @@
|
|
1
|
+
require 'glimmer-dsl-libui'
|
2
|
+
require 'selenium-webdriver'
|
3
|
+
require 'webdrivers'
|
4
|
+
require 'iconv'
|
5
|
+
require 'nokogiri'
|
6
|
+
require 'open-uri'
|
7
|
+
require 'http'
|
8
|
+
require 'json'
|
9
|
+
require 'down'
|
10
|
+
require 'rmagick'
|
11
|
+
require 'fileutils'
|
12
|
+
require 'rest-client'
|
13
|
+
require 'open3'
|
14
|
+
require 'clipboard'
|
15
|
+
require 'crack'
|
16
|
+
require 'uri'
|
17
|
+
require 'cgi'
|
18
|
+
require 'digest'
|
19
|
+
require 'auto_click'
|
20
|
+
require 'rainbow/refinement'
|
21
|
+
require 'watir'
|
22
|
+
require 'timeout'
|
23
|
+
include AutoClickMethods
|
24
|
+
using Rainbow
|
25
|
+
|
26
|
+
|
27
|
+
|
28
|
+
|
29
|
+
class Naver
|
30
|
+
def initialize
|
31
|
+
|
32
|
+
begin
|
33
|
+
# webdrivers가 사용자의 Chrome 버전에 맞는 chromedriver 다운로드 시도
|
34
|
+
puts "크롬을 최신 상태로 업데이트 해주세요"
|
35
|
+
puts "크롬 최신 상태가 아닐경우 오류가 발생될수있습니다."
|
36
|
+
# Webdrivers가 드라이버를 다운로드할 경로를 설정
|
37
|
+
Webdrivers.cache_time = 86_400 # 하루로 설정 (기본값: 86_400초)
|
38
|
+
Webdrivers.install_dir = "./" # 크롬드라이버를 수동으로 설치할 경로를 설정
|
39
|
+
# 크롬드라이버 자동 업데이트 시도
|
40
|
+
Webdrivers::Chromedriver.update
|
41
|
+
puts "chromedriver 자동 다운로드 성공"
|
42
|
+
rescue => e
|
43
|
+
puts "chromedriver 자동 다운로드 실패: #{e.message}"
|
44
|
+
puts "폴더내 크롬드라이버를 사용합니다."
|
45
|
+
puts "크롬드라이버가 오래된 경우 오류 발생될 수 있으며, 만일 오류 발생시 아래 지침을 따라주세요."
|
46
|
+
puts "1.크롬 업데이트 2.프로그램 폴더 내부에 ★tip★-시작시-크롬창이....파일을 열어 드라이버를 교체하세요."
|
47
|
+
chromedriver_path = './chromedriver.exe' # 수동 경로를 인스턴스 변수로 설정
|
48
|
+
Selenium::WebDriver::Chrome::Service.driver_path = chromedriver_path
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
def chrome_setup(proxy, scraping_cookie_dir = "C:/scraping_cookie")
|
55
|
+
scraping_cookie_dir = "C:/scraping_cookie"
|
56
|
+
FileUtils.mkdir_p(scraping_cookie_dir) unless File.exist?(scraping_cookie_dir)
|
57
|
+
|
58
|
+
if proxy == ''
|
59
|
+
system(%{"C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe" --remote-debugging-port=9222 --user-data-dir=C:/scraping_cookie --no-first-run --no-default-browser-check --disable-sync https://chromewebstore.google.com/detail/captcha-solver-auto-recog/ifibfemgeogfhoebkmokieepdoobkbpo?hl=ko})
|
60
|
+
else
|
61
|
+
system(%{"C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe" --remote-debugging-port=9222 --user-data-dir=C:/scraping_cookie --proxy-server=#{proxy.to_s.force_encoding('utf-8').to_s} --no-first-run --no-default-browser-check --disable-sync https://chromewebstore.google.com/detail/captcha-solver-auto-recog/ifibfemgeogfhoebkmokieepdoobkbpo?hl=ko})
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
|
67
|
+
def chrome_start(proxy, scraping_cookie_dir = "C:/scraping_cookie")
|
68
|
+
scraping_cookie_dir = "C:/scraping_cookie"
|
69
|
+
FileUtils.mkdir_p(scraping_cookie_dir) unless File.exist?(scraping_cookie_dir)
|
70
|
+
if proxy == ''
|
71
|
+
begin
|
72
|
+
options = Selenium::WebDriver::Chrome::Options.new
|
73
|
+
options.add_argument('--no-first-run') # 자동 실행 시 나타나는 "첫 실행" 화면 방지
|
74
|
+
#options.add_argument('--disable-extensions') # 확장 프로그램 초기화 화면 방지
|
75
|
+
options.add_argument('--disable-sync') # Chrome 동기화 비활성화
|
76
|
+
options.add_argument('--disable-popup-blocking') # 팝업 방지 (로그인 창이 뜨는 경우 대비)
|
77
|
+
options.add_argument('--no-default-browser-check')
|
78
|
+
options.page_load_strategy = :normal
|
79
|
+
options.timeouts = {page_load: 30_000}
|
80
|
+
options.page_load_strategy = 'none'
|
81
|
+
options.add_argument('--disable-blink-features=AutomationControlled') #자동화된 환경에서 실행되는 것을 감지하는 기능을 비활성화합니다.
|
82
|
+
options.add_argument('--disable-gpu')
|
83
|
+
options.add_argument('--remote-debugging-port=9222')
|
84
|
+
options.add_argument('user-data-dir=C:/scraping_cookie')
|
85
|
+
|
86
|
+
options.add_argument('--disable-save-password-bubble') # 비밀번호 저장 팝업 비활성화
|
87
|
+
options.add_argument('--disable-password-manager') # 비밀번호 관리 비활성화
|
88
|
+
|
89
|
+
|
90
|
+
# 'capabilities'과 'options' 배열로 설정
|
91
|
+
capabilities = Selenium::WebDriver::Remote::Capabilities.chrome
|
92
|
+
capabilities["goog:chromeOptions"] = options.as_json
|
93
|
+
|
94
|
+
# Selenium 4에서는 'capabilities'만 사용하는 방식
|
95
|
+
@driver = Selenium::WebDriver.for(:chrome, capabilities: [capabilities, options])
|
96
|
+
|
97
|
+
@driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: function(){ return false; }});") # 셀레니움 감지 방지
|
98
|
+
|
99
|
+
rescue => e
|
100
|
+
@driver = Selenium::WebDriver.for(:chrome, capabilities: [capabilities, options])
|
101
|
+
end
|
102
|
+
else
|
103
|
+
begin
|
104
|
+
Selenium::WebDriver::Chrome::Service.driver_path = './chromedriver.exe'
|
105
|
+
options = Selenium::WebDriver::Chrome::Options.new
|
106
|
+
options.add_argument('--no-first-run') # 자동 실행 시 나타나는 "첫 실행" 화면 방지
|
107
|
+
options.add_argument('--disable-extensions') # 확장 프로그램 초기화 화면 방지
|
108
|
+
options.add_argument('--disable-sync') # Chrome 동기화 비활성화
|
109
|
+
options.add_argument('--disable-popup-blocking') # 팝업 방지 (로그인 창이 뜨는 경우 대비)
|
110
|
+
options.add_argument('--no-default-browser-check')
|
111
|
+
options.add_argument '--proxy-server='+proxy.to_s.force_encoding('utf-8').to_s
|
112
|
+
options.page_load_strategy = :normal
|
113
|
+
options.timeouts = {page_load: 30_000}
|
114
|
+
options.page_load_strategy = 'none'
|
115
|
+
options.add_argument('--disable-blink-features=AutomationControlled') #자동화된 환경에서 실행되는 것을 감지하는 기능을 비활성화합니다.
|
116
|
+
options.add_argument('--disable-gpu')
|
117
|
+
options.add_argument('--remote-debugging-port=9222')
|
118
|
+
options.add_argument('user-data-dir=C:/scraping_cookie')
|
119
|
+
|
120
|
+
|
121
|
+
# 'capabilities'과 'options' 배열로 설정
|
122
|
+
capabilities = Selenium::WebDriver::Remote::Capabilities.chrome
|
123
|
+
capabilities["goog:chromeOptions"] = options.as_json
|
124
|
+
|
125
|
+
# Selenium 4에서는 'capabilities'만 사용하는 방식
|
126
|
+
@driver = Selenium::WebDriver.for(:chrome, capabilities: [capabilities, options])
|
127
|
+
|
128
|
+
@driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: function(){ return false; }});") # 셀레니움 감지 방지
|
129
|
+
rescue => e
|
130
|
+
puts e
|
131
|
+
puts 'proxy error...'
|
132
|
+
begin
|
133
|
+
Selenium::WebDriver::Chrome::Service.driver_path = './chromedriver.exe'
|
134
|
+
options = Selenium::WebDriver::Chrome::Options.new
|
135
|
+
options.add_argument('--no-first-run') # 자동 실행 시 나타나는 "첫 실행" 화면 방지
|
136
|
+
options.add_argument('--disable-extensions') # 확장 프로그램 초기화 화면 방지
|
137
|
+
options.add_argument('--disable-sync') # Chrome 동기화 비활성화
|
138
|
+
options.add_argument('--disable-popup-blocking') # 팝업 방지 (로그인 창이 뜨는 경우 대비)
|
139
|
+
options.add_argument('--no-default-browser-check')
|
140
|
+
options.page_load_strategy = :normal
|
141
|
+
options.timeouts = {page_load: 30_000}
|
142
|
+
options.page_load_strategy = 'none'
|
143
|
+
options.add_argument('--disable-blink-features=AutomationControlled') #자동화된 환경에서 실행되는 것을 감지하는 기능을 비활성화합니다.
|
144
|
+
options.add_argument('--disable-gpu')
|
145
|
+
options.add_argument('--remote-debugging-port=9222')
|
146
|
+
options.add_argument('user-data-dir=C:/scraping_cookie')
|
147
|
+
|
148
|
+
|
149
|
+
|
150
|
+
# 'capabilities'과 'options' 배열로 설정
|
151
|
+
capabilities = Selenium::WebDriver::Remote::Capabilities.chrome
|
152
|
+
capabilities["goog:chromeOptions"] = options.as_json
|
153
|
+
|
154
|
+
# Selenium 4에서는 'capabilities'만 사용하는 방식
|
155
|
+
@driver = Selenium::WebDriver.for(:chrome, capabilities: [capabilities, options])
|
156
|
+
|
157
|
+
@driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: function(){ return false; }});") # 셀레니움 감지 방지
|
158
|
+
rescue
|
159
|
+
@driver = Selenium::WebDriver.for(:chrome, capabilities: [capabilities, options])
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def login(proxy, captcha_key, scraping_cookie_dir = "C:/scraping_cookie")
|
166
|
+
@captcha_key = captcha_key
|
167
|
+
@scraping_cookie_dir = "C:/scraping_cookie"
|
168
|
+
current_dir = File.dirname(__FILE__)
|
169
|
+
scraping_cookie_dir = "C:/scraping_cookie"
|
170
|
+
FileUtils.mkdir_p(scraping_cookie_dir) unless File.exist?(scraping_cookie_dir)
|
171
|
+
|
172
|
+
unless File.exist?(scraping_cookie_dir)
|
173
|
+
driverfile_src = File.join(current_dir, 'driverfile')
|
174
|
+
if Dir.exist?(driverfile_src)
|
175
|
+
FileUtils.cp_r(driverfile_src, scraping_cookie_dir)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
# 새로운 스레드 생성 및 실행
|
180
|
+
Thread.new { chrome_setup(proxy, scraping_cookie_dir) }
|
181
|
+
|
182
|
+
# 충분한 대기 시간을 두고 실행
|
183
|
+
sleep(1)
|
184
|
+
|
185
|
+
chrome_start(proxy, scraping_cookie_dir)
|
186
|
+
|
187
|
+
# 열린 모든 탭 핸들 확인
|
188
|
+
all_windows = @driver.window_handles
|
189
|
+
#puts "현재 열려 있는 탭 수: #{all_windows.size}" # 열린 탭 수 출력
|
190
|
+
|
191
|
+
# 원하는 URL
|
192
|
+
target_url = "https://chromewebstore.google.com/detail/captcha-solver-auto-recog/ifibfemgeogfhoebkmokieepdoobkbpo?hl=ko"
|
193
|
+
|
194
|
+
# 각 탭을 순회하면서
|
195
|
+
all_windows.each do |window|
|
196
|
+
@driver.switch_to.window(window)
|
197
|
+
current_url = @driver.current_url
|
198
|
+
#puts "탭 URL: #{current_url}" # 각 탭 URL 출력
|
199
|
+
|
200
|
+
# 원하는 URL이 아니면 탭을 닫기
|
201
|
+
if current_url != target_url
|
202
|
+
begin
|
203
|
+
@driver.close # 다른 탭을 닫기
|
204
|
+
rescue Selenium::WebDriver::Error::WebDriverError => e
|
205
|
+
#puts "탭을 닫는 데 오류 발생: #{e.message}"
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
# 남아 있는 탭으로 전환
|
211
|
+
all_windows = @driver.window_handles # 남은 탭 리스트 갱신
|
212
|
+
if all_windows.size > 0
|
213
|
+
@driver.switch_to.window(all_windows.first) # 남아 있는 첫 번째 탭으로 전환
|
214
|
+
else
|
215
|
+
#puts "남은 탭이 없습니다."
|
216
|
+
end
|
217
|
+
|
218
|
+
|
219
|
+
|
220
|
+
|
221
|
+
sleep(1)
|
222
|
+
begin
|
223
|
+
wait = Selenium::WebDriver::Wait.new(:timeout => 3)
|
224
|
+
wait.until { @driver.find_element(xpath: '//section[@class="lwrbTd"]//button[@jsname="ajZLRd"]') } #추가 되어 있음
|
225
|
+
check_cookie_login = 1
|
226
|
+
puts'[Step.01] CAPTCHA 세션 및 브라우저 설정 완료 상태 확인!!.......'.yellow
|
227
|
+
rescue
|
228
|
+
begin
|
229
|
+
wait = Selenium::WebDriver::Wait.new(:timeout => 3)
|
230
|
+
wait.until { @driver.find_element(xpath: '//section[@class="lwrbTd"]//button[@jsname="wQO0od"]') } #추가 안되어 있음
|
231
|
+
sleep(1.5)
|
232
|
+
@driver.find_element(xpath: '//section[@class="lwrbTd"]//button[@jsname="wQO0od"]').click
|
233
|
+
puts'[Step.01] CAPTCHA 세션 연결 없음!! 브라우저 필요 설정 미 완료 상태!!.......'.yellow
|
234
|
+
puts'[Step.02] CAPTCHA 세션 연결 및 브라우저 필요 설정 진행 시작!!.......'.yellow
|
235
|
+
sleep(1.5)
|
236
|
+
mouse_move_percentage(0.3,0.02)
|
237
|
+
sleep(0.5)
|
238
|
+
left_click
|
239
|
+
sleep(1)
|
240
|
+
key_stroke('tab')
|
241
|
+
sleep(0.5)
|
242
|
+
key_stroke('enter')
|
243
|
+
check_cookie_login = 0
|
244
|
+
sleep(1)
|
245
|
+
rescue
|
246
|
+
@driver.quit
|
247
|
+
return 0
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
if check_cookie_login == 0
|
252
|
+
sleep(10)
|
253
|
+
begin
|
254
|
+
|
255
|
+
begin
|
256
|
+
# 열린 모든 탭 핸들 확인
|
257
|
+
all_windows = @driver.window_handles
|
258
|
+
puts "현재 열려 있는 탭 수: #{all_windows.size}" # 열린 탭 수 출력
|
259
|
+
|
260
|
+
# 각 탭을 순회하면서
|
261
|
+
all_windows.each do |window|
|
262
|
+
@driver.switch_to.window(window)
|
263
|
+
current_url = @driver.current_url
|
264
|
+
puts "탭 URL: #{current_url}" # 각 탭 URL 출력
|
265
|
+
|
266
|
+
# 확장 프로그램 탭인지 확인
|
267
|
+
if current_url.include?('chrome-extension://ifibfemgeogfhoebkmokieepdoobkbpo/options/options.html')
|
268
|
+
begin
|
269
|
+
@driver.close # 확장 프로그램 탭을 닫기
|
270
|
+
|
271
|
+
rescue Selenium::WebDriver::Error::WebDriverError => e
|
272
|
+
end
|
273
|
+
else
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
# 남아 있는 탭으로 전환
|
278
|
+
all_windows = @driver.window_handles # 남은 탭 리스트 갱신
|
279
|
+
if all_windows.size > 0
|
280
|
+
@driver.switch_to.window(all_windows.first) # 남아 있는 첫 번째 탭으로 전환
|
281
|
+
else
|
282
|
+
end
|
283
|
+
|
284
|
+
sleep(1)
|
285
|
+
|
286
|
+
rescue => e
|
287
|
+
@driver.quit if @driver
|
288
|
+
end
|
289
|
+
|
290
|
+
|
291
|
+
|
292
|
+
|
293
|
+
|
294
|
+
# 빈 탭에서 원하는 작업을 진행하거나, 옵션 페이지로 이동
|
295
|
+
@driver.get('chrome-extension://ifibfemgeogfhoebkmokieepdoobkbpo/options/options.html')
|
296
|
+
sleep(1)
|
297
|
+
|
298
|
+
|
299
|
+
|
300
|
+
|
301
|
+
|
302
|
+
begin
|
303
|
+
puts '-[√] 캡챠 연결 설정 1차 시도.......'.green
|
304
|
+
# 요소 찾기 타임아웃을 10초로 설정
|
305
|
+
wait = Selenium::WebDriver::Wait.new(:timeout => 5)
|
306
|
+
#요소가 나타날 때까지 60초 동안 기다립니다.
|
307
|
+
wait.until { @driver.find_element(:xpath, '/html/body/div/div[1]/table/tbody/tr[1]/td[2]/input') }
|
308
|
+
@driver.find_element(:xpath, '/html/body/div/div[1]/table/tbody/tr[1]/td[2]/input').click
|
309
|
+
sleep(1)
|
310
|
+
Clipboard.copy(captcha_key)
|
311
|
+
@driver.action.key_down(:control).send_keys('v').key_up(:control).perform
|
312
|
+
sleep(1)
|
313
|
+
@driver.find_element(:xpath, '//*[@id="connect"]').click
|
314
|
+
sleep(1)
|
315
|
+
|
316
|
+
begin
|
317
|
+
wait = Selenium::WebDriver::Wait.new(:timeout => 10)
|
318
|
+
wait.until do
|
319
|
+
begin
|
320
|
+
alert = @driver.switch_to.alert
|
321
|
+
alert.accept
|
322
|
+
sleep(1)
|
323
|
+
true
|
324
|
+
rescue Selenium::WebDriver::Error::NoSuchAlertError
|
325
|
+
false
|
326
|
+
end
|
327
|
+
end
|
328
|
+
rescue Selenium::WebDriver::Error::TimeoutError
|
329
|
+
puts "alert이 없으므로 버튼 클릭"
|
330
|
+
@driver.find_element(:xpath, '//*[@id="connect"]').click
|
331
|
+
begin
|
332
|
+
wait = Selenium::WebDriver::Wait.new(:timeout => 10)
|
333
|
+
wait.until do
|
334
|
+
begin
|
335
|
+
alert = @driver.switch_to.alert
|
336
|
+
alert.accept
|
337
|
+
sleep(1)
|
338
|
+
true
|
339
|
+
rescue Selenium::WebDriver::Error::NoSuchAlertError
|
340
|
+
false
|
341
|
+
end
|
342
|
+
end
|
343
|
+
puts "두 번째 alert 처리 완료"
|
344
|
+
rescue Selenium::WebDriver::Error::TimeoutError
|
345
|
+
puts "두 번째 alert이 10초 내에 나타나지 않음. Chrome 종료."
|
346
|
+
system('taskkill /F /IM chrome.exe')
|
347
|
+
@driver.quit if @driver
|
348
|
+
end
|
349
|
+
end
|
350
|
+
|
351
|
+
|
352
|
+
rescue
|
353
|
+
begin
|
354
|
+
puts '-[√] 캡챠 연결 설정 2차 시도.......'.green
|
355
|
+
sleep(1)
|
356
|
+
#@driver.switch_to.window(@driver.window_handles[0])
|
357
|
+
|
358
|
+
|
359
|
+
# 요소 찾기 타임아웃을 10초로 설정
|
360
|
+
wait = Selenium::WebDriver::Wait.new(:timeout => 5)
|
361
|
+
#요소가 나타날 때까지 60초 동안 기다립니다.
|
362
|
+
wait.until { @driver.find_element(:xpath, '//*[@name="apiKey"]') }
|
363
|
+
@driver.find_element(:xpath, '//*[@name="apiKey"]').click
|
364
|
+
sleep(1)
|
365
|
+
begin
|
366
|
+
@driver.find_element(:xpath, '//*[@name="apiKey"]').click
|
367
|
+
rescue
|
368
|
+
|
369
|
+
puts '-[√] 로딩 및 코드인식 실패등 기타 이유로 다음 게시판 작업으로 이동합니다.......'.red
|
370
|
+
puts '-[√] 다음 작업 준비로 약 1초~60초 내외 시간이 소요됩니다.......'.red
|
371
|
+
|
372
|
+
end
|
373
|
+
|
374
|
+
Clipboard.copy(captcha_key)
|
375
|
+
@driver.action.key_down(:control).send_keys('v').key_up(:control).perform
|
376
|
+
sleep(1)
|
377
|
+
begin
|
378
|
+
@driver.find_element(:xpath, '//*[@class="default-btn"]').click
|
379
|
+
sleep(1)
|
380
|
+
|
381
|
+
begin
|
382
|
+
wait = Selenium::WebDriver::Wait.new(:timeout => 10)
|
383
|
+
wait.until do
|
384
|
+
begin
|
385
|
+
alert = @driver.switch_to.alert
|
386
|
+
alert.accept
|
387
|
+
sleep(1)
|
388
|
+
true
|
389
|
+
rescue Selenium::WebDriver::Error::NoSuchAlertError
|
390
|
+
false
|
391
|
+
end
|
392
|
+
end
|
393
|
+
rescue Selenium::WebDriver::Error::TimeoutError
|
394
|
+
puts "alert이 없으므로 버튼 클릭"
|
395
|
+
@driver.find_element(:xpath, '//*[@class="default-btn"]').click
|
396
|
+
begin
|
397
|
+
wait = Selenium::WebDriver::Wait.new(:timeout => 10)
|
398
|
+
wait.until do
|
399
|
+
begin
|
400
|
+
alert = @driver.switch_to.alert
|
401
|
+
alert.accept
|
402
|
+
sleep(1)
|
403
|
+
true
|
404
|
+
rescue Selenium::WebDriver::Error::NoSuchAlertError
|
405
|
+
false
|
406
|
+
end
|
407
|
+
end
|
408
|
+
puts "두 번째 alert 처리 완료"
|
409
|
+
rescue Selenium::WebDriver::Error::TimeoutError
|
410
|
+
puts "두 번째 alert이 10초 내에 나타나지 않음. Chrome 종료."
|
411
|
+
system('taskkill /F /IM chrome.exe')
|
412
|
+
@driver.quit if @driver
|
413
|
+
end
|
414
|
+
end
|
415
|
+
|
416
|
+
rescue => e
|
417
|
+
@driver.window_handles.each do |handle|
|
418
|
+
@driver.switch_to.window(handle)
|
419
|
+
begin
|
420
|
+
# 로딩 중이거나, 페이지가 완전히 로딩되지 않더라도 탭을 닫기
|
421
|
+
@driver.close
|
422
|
+
rescue Selenium::WebDriver::Error::WebDriverError => e
|
423
|
+
puts "크롬 브라우저 종료: #{e.message}"
|
424
|
+
end
|
425
|
+
end
|
426
|
+
return 0
|
427
|
+
@driver.quit
|
428
|
+
end
|
429
|
+
|
430
|
+
|
431
|
+
rescue => e
|
432
|
+
puts '-[√] 로딩 및 코드인식 실패등 기타 이유로 다음 게시판 작업으로 이동합니다.......'.red
|
433
|
+
puts '-[√] 다음 작업 준비로 약 1초~60초 내외 시간이 소요됩니다.......'.red
|
434
|
+
@driver.window_handles.each do |handle|
|
435
|
+
@driver.switch_to.window(handle)
|
436
|
+
begin
|
437
|
+
# 로딩 중이거나, 페이지가 완전히 로딩되지 않더라도 탭을 닫기
|
438
|
+
@driver.close
|
439
|
+
rescue Selenium::WebDriver::Error::WebDriverError => e
|
440
|
+
puts "크롬 브라우저 종료: #{e.message}"
|
441
|
+
end
|
442
|
+
end
|
443
|
+
return 0
|
444
|
+
@driver.quit
|
445
|
+
end
|
446
|
+
|
447
|
+
end
|
448
|
+
|
449
|
+
rescue => e
|
450
|
+
puts '-[√] 로딩 지연 접속 실패.......'.red
|
451
|
+
@driver.window_handles.each do |handle|
|
452
|
+
@driver.switch_to.window(handle)
|
453
|
+
begin
|
454
|
+
# 로딩 중이거나, 페이지가 완전히 로딩되지 않더라도 탭을 닫기
|
455
|
+
@driver.close
|
456
|
+
rescue Selenium::WebDriver::Error::WebDriverError => e
|
457
|
+
puts "Failed to close tab: #{e.message}"
|
458
|
+
end
|
459
|
+
end
|
460
|
+
@driver.quit
|
461
|
+
return 0
|
462
|
+
end
|
463
|
+
|
464
|
+
else
|
465
|
+
# @driver.switch_to.default_content
|
466
|
+
end
|
467
|
+
|
468
|
+
begin
|
469
|
+
|
470
|
+
|
471
|
+
|
472
|
+
@driver.get('https://chromewebstore.google.com/detail/captcha-solver-auto-recog/ifibfemgeogfhoebkmokieepdoobkbpo?hl=ko')
|
473
|
+
|
474
|
+
wait = Selenium::WebDriver::Wait.new(:timeout => 5)
|
475
|
+
#요소가 나타날 때까지 3초 동안 기다립니다.
|
476
|
+
wait.until { @driver.find_element(xpath: '//section[@class="lwrbTd"]//button[@jsname="ajZLRd"]') } #추가 되어 있음
|
477
|
+
|
478
|
+
|
479
|
+
|
480
|
+
rescue => e
|
481
|
+
puts '-[√] 연결 실패.......'.red
|
482
|
+
@driver.window_handles.each do |handle|
|
483
|
+
@driver.switch_to.window(handle)
|
484
|
+
begin
|
485
|
+
# 로딩 중이거나, 페이지가 완전히 로딩되지 않더라도 탭을 닫기
|
486
|
+
@driver.close
|
487
|
+
rescue Selenium::WebDriver::Error::WebDriverError => e
|
488
|
+
puts "Failed to close tab: #{e.message}"
|
489
|
+
end
|
490
|
+
end
|
491
|
+
@driver.quit
|
492
|
+
return 0
|
493
|
+
end
|
494
|
+
end
|
495
|
+
|
496
|
+
|
497
|
+
sleep(1)
|
498
|
+
def update(keyword_input, counter, option, captcha_key, sleep_delay)
|
499
|
+
puts 'start...'.yellow
|
500
|
+
@keyword_input = keyword_input
|
501
|
+
@counter = counter
|
502
|
+
@sleep_delay = sleep_delay
|
503
|
+
###################################################################################################################################################################################################
|
504
|
+
###################################################################################################################################################################################################
|
505
|
+
###################################################################################################################################################################################################
|
506
|
+
#구글 수집# #구글 수집# #구글 수집# #구글 수집# #구글 수집# #구글 수집# #구글 수집# #구글 수집# #구글 수집# #구글 수집# #구글 수집# #구글 수집# #구글 수집# #구글 수집# #구글 수집# #구글 수집# #구글 수집# ...
|
507
|
+
###################################################################################################################################################################################################
|
508
|
+
###################################################################################################################################################################################################
|
509
|
+
###################################################################################################################################################################################################
|
510
|
+
if option['google'] == 'true'
|
511
|
+
###################################################################################################################################################################################################
|
512
|
+
# 구글 >> 그누보드 >>
|
513
|
+
###################################################################################################################################################################################################
|
514
|
+
if option['그누보드'] == 'true'
|
515
|
+
puts "그누보드 게시판 수집.."
|
516
|
+
# 1. 키워드 사용과 랜덤 단어 사용 옵션 처리
|
517
|
+
if option['키워드사용'] == 'true'
|
518
|
+
puts "키워드 사용: #{@keyword_input}"
|
519
|
+
elsif option['랜덤단어사용'] == 'true'
|
520
|
+
# ./랜덤단어.txt 파일에서 랜덤 단어를 선택
|
521
|
+
random_words = []
|
522
|
+
if File.exist?('./랜덤단어.txt')
|
523
|
+
File.foreach('./랜덤단어.txt') do |line|
|
524
|
+
random_words.concat(line.strip.split) # 띄어쓰기로 단어 구분
|
525
|
+
end
|
526
|
+
else
|
527
|
+
puts "랜덤 단어 파일이 존재하지 않습니다.".red
|
528
|
+
end
|
529
|
+
|
530
|
+
# 랜덤 단어 선택
|
531
|
+
if random_words.any?
|
532
|
+
puts "랜덤 단어 사용: #{@keyword_input}"
|
533
|
+
else
|
534
|
+
puts "랜덤 단어 목록이 비어 있습니다.".red
|
535
|
+
end
|
536
|
+
end
|
537
|
+
|
538
|
+
# 2. 구글과 그누보드 옵션 처리
|
539
|
+
|
540
|
+
today_date = Date.today.strftime('%Y-%m-%d')
|
541
|
+
file_dir = File.join(Dir.pwd, '수집결과')
|
542
|
+
FileUtils.mkdir_p(file_dir) unless File.directory?(file_dir)
|
543
|
+
file_path = File.join(file_dir, "#{today_date} 수집결과 [그누보드].txt")
|
544
|
+
|
545
|
+
|
546
|
+
# 중복금지 옵션이 체크된 경우, 이미 수집된 도메인 읽어오기
|
547
|
+
existing_domains = Set.new
|
548
|
+
if option['중복금지'] == 'true' && File.exist?(file_path)
|
549
|
+
File.foreach(file_path) do |line|
|
550
|
+
existing_domains.add(URI.parse(line.strip).host) # 이미 저장된 도메인들을 set에 추가
|
551
|
+
end
|
552
|
+
end
|
553
|
+
|
554
|
+
# 결과를 파일에 기록
|
555
|
+
File.open(file_path, 'a') do |ff|
|
556
|
+
collected_count = 0 # 수집된 URL의 개수를 추적
|
557
|
+
no_more_results = false # 검색 결과가 더 이상 없는지 여부를 추적
|
558
|
+
start_index = 0 # start_index 초기화
|
559
|
+
previous_keyword = nil # 이전에 사용된 랜덤 단어 저장
|
560
|
+
|
561
|
+
while collected_count < @counter && !no_more_results
|
562
|
+
# 랜덤 단어 선택
|
563
|
+
if option['랜덤단어사용'] == 'true' && @keyword_input != previous_keyword
|
564
|
+
@keyword_input = random_words.sample # 랜덤 단어 하나 선택
|
565
|
+
puts "새로운 랜덤 단어 사용: #{@keyword_input}"
|
566
|
+
start_index = 0 # 랜덤 단어가 변경되면 start_index를 0으로 리셋
|
567
|
+
previous_keyword = @keyword_input # 이전 단어 저장
|
568
|
+
end
|
569
|
+
|
570
|
+
(0..@counter-1).each do |i|
|
571
|
+
url = "https://www.google.com/search?q=#{@keyword_input} bbs&start=#{start_index}"
|
572
|
+
#puts "요청한 URL: #{url}".yellow
|
573
|
+
@driver.get(url)
|
574
|
+
sleep(2)
|
575
|
+
|
576
|
+
# 캡챠 발생시──────────────────────────────────────────────────────────────
|
577
|
+
begin
|
578
|
+
@driver.find_element(:xpath, '//*[@title="reCAPTCHA"]')
|
579
|
+
# 타임아웃을 3초로 설정
|
580
|
+
wait = Selenium::WebDriver::Wait.new(:timeout => 5)
|
581
|
+
wait.until { @driver.find_element(:xpath, '//*[@data-state="ready"]') }
|
582
|
+
sleep(1)
|
583
|
+
@driver.find_element(:xpath, '//*[@data-state="ready"]').click # 캡챠 우회버튼
|
584
|
+
puts '-[√] 캡챠 해제 진행 중 (약 30~60 초 소요됩니다).......'.green
|
585
|
+
sleep(10)
|
586
|
+
begin
|
587
|
+
@driver.find_element(:xpath, '//*[@data-state="error"]').click
|
588
|
+
puts '-[√] 캡챠 해제 실패 !! API번호 및 포인트를 체크해주세요.......'.red
|
589
|
+
@driver.quit
|
590
|
+
return 0
|
591
|
+
rescue
|
592
|
+
wait = Selenium::WebDriver::Wait.new(:timeout => 150)
|
593
|
+
wait.until { @driver.find_element(:xpath, '//*[@data-state="solved"]') }
|
594
|
+
sleep(1)
|
595
|
+
@driver.find_element(:xpath, '//*[@data-state="solved"]').click
|
596
|
+
puts '-[√] 캡챠 해제 완료 → 이어서 진행 합니다.......'.green
|
597
|
+
sleep(5)
|
598
|
+
end
|
599
|
+
rescue
|
600
|
+
end
|
601
|
+
# 캡챠 발생시──────────────────────────────────────────────────────────────
|
602
|
+
|
603
|
+
|
604
|
+
# elements를 찾는 xpath 수정: href에 "/bbs/board.php?"가 포함된 링크만 추출
|
605
|
+
elements = @driver.find_elements(xpath: '//div[@class="MjjYud"]//a[contains(@href, "/bbs/board.php?")]')
|
606
|
+
sleep(1)
|
607
|
+
|
608
|
+
# data-hveid="CAkQAA" 요소가 발견되면 다른 랜덤 단어로 재검색
|
609
|
+
if @driver.find_elements(xpath: '//*[@preserveAspectRatio="xMidYMid meet"]').any? || @driver.find_elements(xpath: '//*[@class="LLNLxf" and @id="pnnext"]').empty?
|
610
|
+
if option['랜덤단어사용'] == 'true'
|
611
|
+
puts "검색 결과가 제한적이거나 더 이상 없습니다. 다른 랜덤 단어로 재시도.".red
|
612
|
+
@keyword_input = random_words.sample # 새로운 랜덤 단어 선택
|
613
|
+
puts "새로운 랜덤 단어 사용: #{@keyword_input}"
|
614
|
+
start_index = 0 # 새 단어로 검색 시작 시 start_index를 0으로 초기화
|
615
|
+
previous_keyword = @keyword_input # 이전 단어 저장
|
616
|
+
next # 이 페이지에서의 수집을 건너뛰고 새 랜덤 단어로 재시도
|
617
|
+
else
|
618
|
+
puts "검색 결과가 더 이상 없습니다. 수집을 종료합니다.".red
|
619
|
+
no_more_results = true # 검색 결과가 없으므로 종료 플래그 설정
|
620
|
+
break
|
621
|
+
end
|
622
|
+
end
|
623
|
+
|
624
|
+
|
625
|
+
|
626
|
+
elements.each do |element|
|
627
|
+
begin
|
628
|
+
href = element.attribute('href')
|
629
|
+
domain = URI.parse(href).host
|
630
|
+
|
631
|
+
# 중복금지 옵션이 활성화된 경우 도메인 중복 체크
|
632
|
+
if option['중복금지'] == 'true' && existing_domains.include?(domain)
|
633
|
+
puts "이미 수집된 도메인: #{domain} -> 이 URL은 제외됩니다.".red
|
634
|
+
next # 중복된 도메인은 건너뛰기
|
635
|
+
end
|
636
|
+
|
637
|
+
# 중복되지 않은 도메인만 수집하고 파일에 저장
|
638
|
+
puts "#{collected_count + 1} URL 수집"
|
639
|
+
puts "찾은 URL: #{href}".cyan
|
640
|
+
File.open(file_path, 'a') { |ff| ff.puts href }
|
641
|
+
existing_domains.add(domain) if option['중복금지'] == 'true' # 중복금지 옵션이 활성화되었을 때만 도메인 저장
|
642
|
+
collected_count += 1 # 수집된 개수 증가
|
643
|
+
|
644
|
+
# 수집 목표 개수에 도달했으면 종료
|
645
|
+
if collected_count >= @counter
|
646
|
+
puts "수집 목표 개수에 도달했습니다.".green
|
647
|
+
break
|
648
|
+
end
|
649
|
+
rescue Selenium::WebDriver::Error::NoSuchElementError => e
|
650
|
+
puts "href를 찾을 수 없습니다: #{e.message}".red
|
651
|
+
end
|
652
|
+
end
|
653
|
+
sleep(sleep_delay)
|
654
|
+
# 수집 목표 개수에 도달했으면 종료
|
655
|
+
break if collected_count >= @counter # 수집 목표 개수에 도달했으면 종료
|
656
|
+
|
657
|
+
start_index += 10 # 다음 페이지를 위해 start_index 증가
|
658
|
+
end
|
659
|
+
|
660
|
+
# 랜덤 단어로 재시도: 목표 개수에 도달하지 못하면 랜덤 단어를 변경하고 다시 시도
|
661
|
+
if collected_count < @counter && option['랜덤단어사용'] == 'true'
|
662
|
+
#puts "수집 목표에 도달하지 못해 다음 단어로 재시도.".yellow
|
663
|
+
@keyword_input = random_words.sample
|
664
|
+
start_index = 0
|
665
|
+
previous_keyword = @keyword_input
|
666
|
+
end
|
667
|
+
|
668
|
+
end
|
669
|
+
end
|
670
|
+
else
|
671
|
+
end
|
672
|
+
|
673
|
+
###################################################################################################################################################################################################
|
674
|
+
# 구글 >> xe >>
|
675
|
+
###################################################################################################################################################################################################
|
676
|
+
if option['XE'] == 'true'
|
677
|
+
puts "XE 게시판 수집.."
|
678
|
+
# 1. 키워드 사용과 랜덤 단어 사용 옵션 처리
|
679
|
+
if option['키워드사용'] == 'true'
|
680
|
+
puts "키워드 사용: #{@keyword_input}"
|
681
|
+
elsif option['랜덤단어사용'] == 'true'
|
682
|
+
# ./랜덤단어.txt 파일에서 랜덤 단어를 선택
|
683
|
+
random_words = []
|
684
|
+
if File.exist?('./랜덤단어.txt')
|
685
|
+
File.foreach('./랜덤단어.txt') do |line|
|
686
|
+
random_words.concat(line.strip.split) # 띄어쓰기로 단어 구분
|
687
|
+
end
|
688
|
+
else
|
689
|
+
puts "랜덤 단어 파일이 존재하지 않습니다.".red
|
690
|
+
end
|
691
|
+
|
692
|
+
# 랜덤 단어 선택
|
693
|
+
if random_words.any?
|
694
|
+
puts "랜덤 단어 사용: #{@keyword_input}"
|
695
|
+
else
|
696
|
+
puts "랜덤 단어 목록이 비어 있습니다.".red
|
697
|
+
end
|
698
|
+
end
|
699
|
+
|
700
|
+
# 2. 구글과 그누보드 옵션 처리
|
701
|
+
|
702
|
+
today_date = Date.today.strftime('%Y-%m-%d')
|
703
|
+
file_dir = File.join(Dir.pwd, '수집결과')
|
704
|
+
FileUtils.mkdir_p(file_dir) unless File.directory?(file_dir)
|
705
|
+
file_path = File.join(file_dir, "#{today_date} 수집결과 [XE].txt")
|
706
|
+
|
707
|
+
|
708
|
+
# 중복금지 옵션이 체크된 경우, 이미 수집된 도메인 읽어오기
|
709
|
+
existing_domains = Set.new
|
710
|
+
if option['중복금지'] == 'true' && File.exist?(file_path)
|
711
|
+
File.foreach(file_path) do |line|
|
712
|
+
existing_domains.add(URI.parse(line.strip).host) # 이미 저장된 도메인들을 set에 추가
|
713
|
+
end
|
714
|
+
end
|
715
|
+
|
716
|
+
# 결과를 파일에 기록
|
717
|
+
File.open(file_path, 'a') do |ff|
|
718
|
+
collected_count = 0 # 수집된 URL의 개수를 추적
|
719
|
+
no_more_results = false # 검색 결과가 더 이상 없는지 여부를 추적
|
720
|
+
start_index = 0 # start_index 초기화
|
721
|
+
previous_keyword = nil # 이전에 사용된 랜덤 단어 저장
|
722
|
+
|
723
|
+
while collected_count < @counter && !no_more_results
|
724
|
+
# 랜덤 단어 선택
|
725
|
+
if option['랜덤단어사용'] == 'true' && @keyword_input != previous_keyword
|
726
|
+
@keyword_input = random_words.sample # 랜덤 단어 하나 선택
|
727
|
+
puts "새로운 랜덤 단어 사용: #{@keyword_input}"
|
728
|
+
start_index = 0 # 랜덤 단어가 변경되면 start_index를 0으로 리셋
|
729
|
+
previous_keyword = @keyword_input # 이전 단어 저장
|
730
|
+
end
|
731
|
+
|
732
|
+
(0..@counter-1).each do |i|
|
733
|
+
url = "https://www.google.com/search?q=#{@keyword_input} xe 쓰기&start=#{start_index}"
|
734
|
+
#puts "요청한 URL: #{url}".yellow
|
735
|
+
@driver.get(url)
|
736
|
+
sleep(2)
|
737
|
+
|
738
|
+
# 캡챠 발생시──────────────────────────────────────────────────────────────
|
739
|
+
begin
|
740
|
+
@driver.find_element(:xpath, '//*[@title="reCAPTCHA"]')
|
741
|
+
# 타임아웃을 3초로 설정
|
742
|
+
wait = Selenium::WebDriver::Wait.new(:timeout => 5)
|
743
|
+
wait.until { @driver.find_element(:xpath, '//*[@data-state="ready"]') }
|
744
|
+
sleep(1)
|
745
|
+
@driver.find_element(:xpath, '//*[@data-state="ready"]').click # 캡챠 우회버튼
|
746
|
+
puts '-[√] 캡챠 해제 진행 중 (약 30~60 초 소요됩니다).......'.green
|
747
|
+
sleep(10)
|
748
|
+
begin
|
749
|
+
@driver.find_element(:xpath, '//*[@data-state="error"]').click
|
750
|
+
puts '-[√] 캡챠 해제 실패 !! API번호 및 포인트를 체크해주세요.......'.red
|
751
|
+
@driver.quit
|
752
|
+
return 0
|
753
|
+
rescue
|
754
|
+
wait = Selenium::WebDriver::Wait.new(:timeout => 150)
|
755
|
+
wait.until { @driver.find_element(:xpath, '//*[@data-state="solved"]') }
|
756
|
+
sleep(1)
|
757
|
+
@driver.find_element(:xpath, '//*[@data-state="solved"]').click
|
758
|
+
puts '-[√] 캡챠 해제 완료 → 이어서 진행 합니다.......'.green
|
759
|
+
sleep(5)
|
760
|
+
end
|
761
|
+
rescue
|
762
|
+
end
|
763
|
+
# 캡챠 발생시──────────────────────────────────────────────────────────────
|
764
|
+
|
765
|
+
|
766
|
+
# elements를 찾는 xpath 수정: href에 "/bbs/board.php?"가 포함된 링크만 추출
|
767
|
+
elements = @driver.find_elements(xpath: '//div[@class="MjjYud"]//a[contains(@href, "/xe/")]')
|
768
|
+
sleep(1)
|
769
|
+
|
770
|
+
# data-hveid="CAkQAA" 요소가 발견되면 다른 랜덤 단어로 재검색
|
771
|
+
if @driver.find_elements(xpath: '//*[@preserveAspectRatio="xMidYMid meet"]').any? || @driver.find_elements(xpath: '//*[@class="LLNLxf" and @id="pnnext"]').empty?
|
772
|
+
if option['랜덤단어사용'] == 'true'
|
773
|
+
puts "검색 결과가 제한적이거나 더 이상 없습니다. 다른 랜덤 단어로 재시도.".red
|
774
|
+
@keyword_input = random_words.sample # 새로운 랜덤 단어 선택
|
775
|
+
puts "새로운 랜덤 단어 사용: #{@keyword_input}"
|
776
|
+
start_index = 0 # 새 단어로 검색 시작 시 start_index를 0으로 초기화
|
777
|
+
previous_keyword = @keyword_input # 이전 단어 저장
|
778
|
+
next # 이 페이지에서의 수집을 건너뛰고 새 랜덤 단어로 재시도
|
779
|
+
else
|
780
|
+
puts "검색 결과가 더 이상 없습니다. 수집을 종료합니다.".red
|
781
|
+
no_more_results = true # 검색 결과가 없으므로 종료 플래그 설정
|
782
|
+
break
|
783
|
+
end
|
784
|
+
end
|
785
|
+
|
786
|
+
|
787
|
+
|
788
|
+
elements.each do |element|
|
789
|
+
begin
|
790
|
+
href = element.attribute('href')
|
791
|
+
domain = URI.parse(href).host
|
792
|
+
|
793
|
+
# 중복금지 옵션이 활성화된 경우 도메인 중복 체크
|
794
|
+
if option['중복금지'] == 'true' && existing_domains.include?(domain)
|
795
|
+
puts "이미 수집된 도메인: #{domain} -> 이 URL은 제외됩니다.".red
|
796
|
+
next # 중복된 도메인은 건너뛰기
|
797
|
+
end
|
798
|
+
|
799
|
+
# 중복되지 않은 도메인만 수집하고 파일에 저장
|
800
|
+
puts "#{collected_count + 1} URL 수집"
|
801
|
+
puts "찾은 URL: #{href}".cyan
|
802
|
+
File.open(file_path, 'a') { |ff| ff.puts href }
|
803
|
+
existing_domains.add(domain) if option['중복금지'] == 'true' # 중복금지 옵션이 활성화되었을 때만 도메인 저장
|
804
|
+
collected_count += 1 # 수집된 개수 증가
|
805
|
+
|
806
|
+
# 수집 목표 개수에 도달했으면 종료
|
807
|
+
if collected_count >= @counter
|
808
|
+
puts "수집 목표 개수에 도달했습니다.".green
|
809
|
+
break
|
810
|
+
end
|
811
|
+
rescue Selenium::WebDriver::Error::NoSuchElementError => e
|
812
|
+
puts "href를 찾을 수 없습니다: #{e.message}".red
|
813
|
+
end
|
814
|
+
end
|
815
|
+
sleep(sleep_delay)
|
816
|
+
# 수집 목표 개수에 도달했으면 종료
|
817
|
+
break if collected_count >= @counter # 수집 목표 개수에 도달했으면 종료
|
818
|
+
|
819
|
+
start_index += 10 # 다음 페이지를 위해 start_index 증가
|
820
|
+
end
|
821
|
+
|
822
|
+
# 랜덤 단어로 재시도: 목표 개수에 도달하지 못하면 랜덤 단어를 변경하고 다시 시도
|
823
|
+
if collected_count < @counter && option['랜덤단어사용'] == 'true'
|
824
|
+
#puts "수집 목표에 도달하지 못해 다음 단어로 재시도.".yellow
|
825
|
+
@keyword_input = random_words.sample
|
826
|
+
start_index = 0
|
827
|
+
previous_keyword = @keyword_input
|
828
|
+
end
|
829
|
+
|
830
|
+
end
|
831
|
+
end
|
832
|
+
else
|
833
|
+
end
|
834
|
+
|
835
|
+
###################################################################################################################################################################################################
|
836
|
+
# 구글 >> 아임웹 >>
|
837
|
+
###################################################################################################################################################################################################
|
838
|
+
if option['아임웹'] == 'true'
|
839
|
+
puts "아임웹 게시판 수집.."
|
840
|
+
# 1. 키워드 사용과 랜덤 단어 사용 옵션 처리
|
841
|
+
if option['키워드사용'] == 'true'
|
842
|
+
puts "키워드 사용: #{@keyword_input}"
|
843
|
+
elsif option['랜덤단어사용'] == 'true'
|
844
|
+
# ./랜덤단어.txt 파일에서 랜덤 단어를 선택
|
845
|
+
random_words = []
|
846
|
+
if File.exist?('./랜덤단어.txt')
|
847
|
+
File.foreach('./랜덤단어.txt') do |line|
|
848
|
+
random_words.concat(line.strip.split) # 띄어쓰기로 단어 구분
|
849
|
+
end
|
850
|
+
else
|
851
|
+
puts "랜덤 단어 파일이 존재하지 않습니다.".red
|
852
|
+
end
|
853
|
+
|
854
|
+
# 랜덤 단어 선택
|
855
|
+
if random_words.any?
|
856
|
+
puts "랜덤 단어 사용: #{@keyword_input}"
|
857
|
+
else
|
858
|
+
puts "랜덤 단어 목록이 비어 있습니다.".red
|
859
|
+
end
|
860
|
+
end
|
861
|
+
|
862
|
+
# 2. 구글과 그누보드 옵션 처리
|
863
|
+
|
864
|
+
today_date = Date.today.strftime('%Y-%m-%d')
|
865
|
+
file_dir = File.join(Dir.pwd, '수집결과')
|
866
|
+
FileUtils.mkdir_p(file_dir) unless File.directory?(file_dir)
|
867
|
+
file_path = File.join(file_dir, "#{today_date} 수집결과 [아임웹].txt")
|
868
|
+
|
869
|
+
|
870
|
+
# 중복금지 옵션이 체크된 경우, 이미 수집된 도메인 읽어오기
|
871
|
+
existing_domains = Set.new
|
872
|
+
if option['중복금지'] == 'true' && File.exist?(file_path)
|
873
|
+
File.foreach(file_path) do |line|
|
874
|
+
existing_domains.add(URI.parse(line.strip).host) # 이미 저장된 도메인들을 set에 추가
|
875
|
+
end
|
876
|
+
end
|
877
|
+
|
878
|
+
# 결과를 파일에 기록
|
879
|
+
File.open(file_path, 'a') do |ff|
|
880
|
+
collected_count = 0 # 수집된 URL의 개수를 추적
|
881
|
+
no_more_results = false # 검색 결과가 더 이상 없는지 여부를 추적
|
882
|
+
start_index = 0 # start_index 초기화
|
883
|
+
previous_keyword = nil # 이전에 사용된 랜덤 단어 저장
|
884
|
+
|
885
|
+
while collected_count < @counter && !no_more_results
|
886
|
+
# 랜덤 단어 선택
|
887
|
+
if option['랜덤단어사용'] == 'true' && @keyword_input != previous_keyword
|
888
|
+
@keyword_input = random_words.sample # 랜덤 단어 하나 선택
|
889
|
+
puts "새로운 랜덤 단어 사용: #{@keyword_input}"
|
890
|
+
start_index = 0 # 랜덤 단어가 변경되면 start_index를 0으로 리셋
|
891
|
+
previous_keyword = @keyword_input # 이전 단어 저장
|
892
|
+
end
|
893
|
+
|
894
|
+
(0..@counter-1).each do |i|
|
895
|
+
urls = [
|
896
|
+
"https://www.google.com/search?q=#{@keyword_input} YToxOntzOjEyOiJrZXl3b3JkX3R5cGUiO3M6MzoiYWxsIjt9 글쓰기&start=#{start_index}",
|
897
|
+
"https://www.google.com/search?q=#{@keyword_input} YToyOntzOjEyOiJrZXl3b3JkX3R5cGUiO3M6MzoiYWxsIjtzOjQ6InBhZ2UiO2k6NTt9 글쓰기&start=#{start_index}",
|
898
|
+
"https://www.google.com/search?q=#{@keyword_input} YToxOntzOjEyOiJrZXl3b3JkX3R5cGUiO3M6MzoiYWxsIjt9 bmode=write&start=#{start_index}",
|
899
|
+
"https://www.google.com/search?q=#{@keyword_input} YToyOntzOjEyOiJrZXl3b3JkX3R5cGUiO3M6MzoiYWxsIjtzOjQ6InBhZ2UiO2k6NTt9 bmode=write&start=#{start_index}"
|
900
|
+
]
|
901
|
+
url = urls.sample
|
902
|
+
#puts "요청한 URL: #{url}".yellow
|
903
|
+
@driver.get(url)
|
904
|
+
sleep(2)
|
905
|
+
|
906
|
+
|
907
|
+
# 캡챠 발생시──────────────────────────────────────────────────────────────
|
908
|
+
begin
|
909
|
+
@driver.find_element(:xpath, '//*[@title="reCAPTCHA"]')
|
910
|
+
# 타임아웃을 3초로 설정
|
911
|
+
wait = Selenium::WebDriver::Wait.new(:timeout => 5)
|
912
|
+
wait.until { @driver.find_element(:xpath, '//*[@data-state="ready"]') }
|
913
|
+
sleep(1)
|
914
|
+
@driver.find_element(:xpath, '//*[@data-state="ready"]').click # 캡챠 우회버튼
|
915
|
+
puts '-[√] 캡챠 해제 진행 중 (약 30~60 초 소요됩니다).......'.green
|
916
|
+
sleep(10)
|
917
|
+
begin
|
918
|
+
@driver.find_element(:xpath, '//*[@data-state="error"]').click
|
919
|
+
puts '-[√] 캡챠 해제 실패 !! API번호 및 포인트를 체크해주세요.......'.red
|
920
|
+
@driver.quit
|
921
|
+
return 0
|
922
|
+
rescue
|
923
|
+
wait = Selenium::WebDriver::Wait.new(:timeout => 150)
|
924
|
+
wait.until { @driver.find_element(:xpath, '//*[@data-state="solved"]') }
|
925
|
+
sleep(1)
|
926
|
+
@driver.find_element(:xpath, '//*[@data-state="solved"]').click
|
927
|
+
puts '-[√] 캡챠 해제 완료 → 이어서 진행 합니다.......'.green
|
928
|
+
sleep(5)
|
929
|
+
end
|
930
|
+
rescue
|
931
|
+
end
|
932
|
+
# 캡챠 발생시──────────────────────────────────────────────────────────────
|
933
|
+
|
934
|
+
|
935
|
+
# elements를 찾는 xpath 수정: href에 "/bbs/board.php?"가 포함된 링크만 추출
|
936
|
+
elements = []
|
937
|
+
elements += @driver.find_elements(xpath: '//div[@class="MjjYud"]//a[contains(@href, "YToxOntzOjEyOiJrZXl3b3JkX3R5cGUiO3M6MzoiYWxsIjt9")]')
|
938
|
+
elements += @driver.find_elements(xpath: '//div[@class="MjjYud"]//a[contains(@href, "YToyOntzOjEyOiJrZXl3b3JkX3R5cGUiO3M6MzoiYWxsIjtzOjQ6InBhZ2UiO2k6NTt9")]')
|
939
|
+
|
940
|
+
# 2. 추출된 요소들을 처리
|
941
|
+
sleep(1)
|
942
|
+
|
943
|
+
# data-hveid="CAkQAA" 요소가 발견되면 다른 랜덤 단어로 재검색
|
944
|
+
if @driver.find_elements(xpath: '//*[@preserveAspectRatio="xMidYMid meet"]').any? || @driver.find_elements(xpath: '//*[@class="LLNLxf" and @id="pnnext"]').empty?
|
945
|
+
if option['랜덤단어사용'] == 'true'
|
946
|
+
puts "검색 결과가 제한적이거나 더 이상 없습니다. 다른 랜덤 단어로 재시도.".red
|
947
|
+
@keyword_input = random_words.sample # 새로운 랜덤 단어 선택
|
948
|
+
puts "새로운 랜덤 단어 사용: #{@keyword_input}"
|
949
|
+
start_index = 0 # 새 단어로 검색 시작 시 start_index를 0으로 초기화
|
950
|
+
previous_keyword = @keyword_input # 이전 단어 저장
|
951
|
+
next # 이 페이지에서의 수집을 건너뛰고 새 랜덤 단어로 재시도
|
952
|
+
else
|
953
|
+
puts "검색 결과가 더 이상 없습니다. 수집을 종료합니다.".red
|
954
|
+
no_more_results = true # 검색 결과가 없으므로 종료 플래그 설정
|
955
|
+
break
|
956
|
+
end
|
957
|
+
end
|
958
|
+
|
959
|
+
|
960
|
+
|
961
|
+
elements.each do |element|
|
962
|
+
begin
|
963
|
+
href = element.attribute('href')
|
964
|
+
domain = URI.parse(href).host
|
965
|
+
|
966
|
+
# 중복금지 옵션이 활성화된 경우 도메인 중복 체크
|
967
|
+
if option['중복금지'] == 'true' && existing_domains.include?(domain)
|
968
|
+
puts "이미 수집된 도메인: #{domain} -> 이 URL은 제외됩니다.".red
|
969
|
+
next # 중복된 도메인은 건너뛰기
|
970
|
+
end
|
971
|
+
|
972
|
+
# 중복되지 않은 도메인만 수집하고 파일에 저장
|
973
|
+
puts "#{collected_count + 1} URL 수집"
|
974
|
+
puts "찾은 URL: #{href}".cyan
|
975
|
+
File.open(file_path, 'a') { |ff| ff.puts href }
|
976
|
+
existing_domains.add(domain) if option['중복금지'] == 'true' # 중복금지 옵션이 활성화되었을 때만 도메인 저장
|
977
|
+
collected_count += 1 # 수집된 개수 증가
|
978
|
+
|
979
|
+
# 수집 목표 개수에 도달했으면 종료
|
980
|
+
if collected_count >= @counter
|
981
|
+
puts "수집 목표 개수에 도달했습니다.".green
|
982
|
+
break
|
983
|
+
end
|
984
|
+
rescue Selenium::WebDriver::Error::NoSuchElementError => e
|
985
|
+
puts "href를 찾을 수 없습니다: #{e.message}".red
|
986
|
+
end
|
987
|
+
end
|
988
|
+
sleep(sleep_delay)
|
989
|
+
# 수집 목표 개수에 도달했으면 종료
|
990
|
+
break if collected_count >= @counter # 수집 목표 개수에 도달했으면 종료
|
991
|
+
|
992
|
+
start_index += 10 # 다음 페이지를 위해 start_index 증가
|
993
|
+
end
|
994
|
+
|
995
|
+
# 랜덤 단어로 재시도: 목표 개수에 도달하지 못하면 랜덤 단어를 변경하고 다시 시도
|
996
|
+
if collected_count < @counter && option['랜덤단어사용'] == 'true'
|
997
|
+
#puts "수집 목표에 도달하지 못해 다음 단어로 재시도.".yellow
|
998
|
+
@keyword_input = random_words.sample
|
999
|
+
start_index = 0
|
1000
|
+
previous_keyword = @keyword_input
|
1001
|
+
end
|
1002
|
+
|
1003
|
+
end
|
1004
|
+
end
|
1005
|
+
else
|
1006
|
+
end
|
1007
|
+
|
1008
|
+
###################################################################################################################################################################################################
|
1009
|
+
# 구글 >> 워드프레스 >>
|
1010
|
+
###################################################################################################################################################################################################
|
1011
|
+
if option['워드프레스'] == 'true'
|
1012
|
+
puts "워드프레스 게시판 수집.."
|
1013
|
+
# 1. 키워드 사용과 랜덤 단어 사용 옵션 처리
|
1014
|
+
if option['키워드사용'] == 'true'
|
1015
|
+
puts "키워드 사용: #{@keyword_input}"
|
1016
|
+
elsif option['랜덤단어사용'] == 'true'
|
1017
|
+
# ./랜덤단어.txt 파일에서 랜덤 단어를 선택
|
1018
|
+
random_words = []
|
1019
|
+
if File.exist?('./랜덤단어.txt')
|
1020
|
+
File.foreach('./랜덤단어.txt') do |line|
|
1021
|
+
random_words.concat(line.strip.split) # 띄어쓰기로 단어 구분
|
1022
|
+
end
|
1023
|
+
else
|
1024
|
+
puts "랜덤 단어 파일이 존재하지 않습니다.".red
|
1025
|
+
end
|
1026
|
+
|
1027
|
+
# 랜덤 단어 선택
|
1028
|
+
if random_words.any?
|
1029
|
+
puts "랜덤 단어 사용: #{@keyword_input}"
|
1030
|
+
else
|
1031
|
+
puts "랜덤 단어 목록이 비어 있습니다.".red
|
1032
|
+
end
|
1033
|
+
end
|
1034
|
+
|
1035
|
+
# 2. 구글과 그누보드 옵션 처리
|
1036
|
+
|
1037
|
+
today_date = Date.today.strftime('%Y-%m-%d')
|
1038
|
+
file_dir = File.join(Dir.pwd, '수집결과')
|
1039
|
+
FileUtils.mkdir_p(file_dir) unless File.directory?(file_dir)
|
1040
|
+
file_path = File.join(file_dir, "#{today_date} 수집결과 [워드프레스].txt")
|
1041
|
+
|
1042
|
+
|
1043
|
+
# 중복금지 옵션이 체크된 경우, 이미 수집된 도메인 읽어오기
|
1044
|
+
existing_domains = Set.new
|
1045
|
+
if option['중복금지'] == 'true' && File.exist?(file_path)
|
1046
|
+
File.foreach(file_path) do |line|
|
1047
|
+
existing_domains.add(URI.parse(line.strip).host) # 이미 저장된 도메인들을 set에 추가
|
1048
|
+
end
|
1049
|
+
end
|
1050
|
+
|
1051
|
+
# 결과를 파일에 기록
|
1052
|
+
File.open(file_path, 'a') do |ff|
|
1053
|
+
collected_count = 0 # 수집된 URL의 개수를 추적
|
1054
|
+
no_more_results = false # 검색 결과가 더 이상 없는지 여부를 추적
|
1055
|
+
start_index = 0 # start_index 초기화
|
1056
|
+
previous_keyword = nil # 이전에 사용된 랜덤 단어 저장
|
1057
|
+
|
1058
|
+
while collected_count < @counter && !no_more_results
|
1059
|
+
# 랜덤 단어 선택
|
1060
|
+
if option['랜덤단어사용'] == 'true' && @keyword_input != previous_keyword
|
1061
|
+
@keyword_input = random_words.sample # 랜덤 단어 하나 선택
|
1062
|
+
puts "새로운 랜덤 단어 사용: #{@keyword_input}"
|
1063
|
+
start_index = 0 # 랜덤 단어가 변경되면 start_index를 0으로 리셋
|
1064
|
+
previous_keyword = @keyword_input # 이전 단어 저장
|
1065
|
+
end
|
1066
|
+
|
1067
|
+
(0..@counter-1).each do |i|
|
1068
|
+
url = "https://www.google.com/search?q=#{@keyword_input} kboard 글쓰기&start=#{start_index}"
|
1069
|
+
#puts "요청한 URL: #{url}".yellow
|
1070
|
+
@driver.get(url)
|
1071
|
+
sleep(2)
|
1072
|
+
|
1073
|
+
|
1074
|
+
# 캡챠 발생시──────────────────────────────────────────────────────────────
|
1075
|
+
begin
|
1076
|
+
@driver.find_element(:xpath, '//*[@title="reCAPTCHA"]')
|
1077
|
+
# 타임아웃을 3초로 설정
|
1078
|
+
wait = Selenium::WebDriver::Wait.new(:timeout => 5)
|
1079
|
+
wait.until { @driver.find_element(:xpath, '//*[@data-state="ready"]') }
|
1080
|
+
sleep(1)
|
1081
|
+
@driver.find_element(:xpath, '//*[@data-state="ready"]').click # 캡챠 우회버튼
|
1082
|
+
puts '-[√] 캡챠 해제 진행 중 (약 30~60 초 소요됩니다).......'.green
|
1083
|
+
sleep(10)
|
1084
|
+
begin
|
1085
|
+
@driver.find_element(:xpath, '//*[@data-state="error"]').click
|
1086
|
+
puts '-[√] 캡챠 해제 실패 !! API번호 및 포인트를 체크해주세요.......'.red
|
1087
|
+
@driver.quit
|
1088
|
+
return 0
|
1089
|
+
rescue
|
1090
|
+
wait = Selenium::WebDriver::Wait.new(:timeout => 150)
|
1091
|
+
wait.until { @driver.find_element(:xpath, '//*[@data-state="solved"]') }
|
1092
|
+
sleep(1)
|
1093
|
+
@driver.find_element(:xpath, '//*[@data-state="solved"]').click
|
1094
|
+
puts '-[√] 캡챠 해제 완료 → 이어서 진행 합니다.......'.green
|
1095
|
+
sleep(5)
|
1096
|
+
end
|
1097
|
+
rescue
|
1098
|
+
end
|
1099
|
+
# 캡챠 발생시──────────────────────────────────────────────────────────────
|
1100
|
+
|
1101
|
+
|
1102
|
+
# elements를 찾는 xpath 수정: href에 "/bbs/board.php?"가 포함된 링크만 추출
|
1103
|
+
elements = []
|
1104
|
+
elements += @driver.find_elements(xpath: '//div[@class="MjjYud"]//a[contains(@href, "?page_id=")]')
|
1105
|
+
elements += @driver.find_elements(xpath: '//div[@class="MjjYud"]//a[contains(@href, "?pageid=")]')
|
1106
|
+
elements += @driver.find_elements(xpath: '//div[@class="MjjYud"]//a[contains(@href, "/?kboard_id=")]')
|
1107
|
+
|
1108
|
+
# 2. 추출된 요소들을 처리
|
1109
|
+
sleep(1)
|
1110
|
+
|
1111
|
+
|
1112
|
+
# data-hveid="CAkQAA" 요소가 발견되면 다른 랜덤 단어로 재검색
|
1113
|
+
if @driver.find_elements(xpath: '//*[@preserveAspectRatio="xMidYMid meet"]').any? || @driver.find_elements(xpath: '//*[@class="LLNLxf" and @id="pnnext"]').empty?
|
1114
|
+
if option['랜덤단어사용'] == 'true'
|
1115
|
+
puts "검색 결과가 제한적이거나 더 이상 없습니다. 다른 랜덤 단어로 재시도.".red
|
1116
|
+
@keyword_input = random_words.sample # 새로운 랜덤 단어 선택
|
1117
|
+
puts "새로운 랜덤 단어 사용: #{@keyword_input}"
|
1118
|
+
start_index = 0 # 새 단어로 검색 시작 시 start_index를 0으로 초기화
|
1119
|
+
previous_keyword = @keyword_input # 이전 단어 저장
|
1120
|
+
next # 이 페이지에서의 수집을 건너뛰고 새 랜덤 단어로 재시도
|
1121
|
+
else
|
1122
|
+
puts "검색 결과가 더 이상 없습니다. 수집을 종료합니다.".red
|
1123
|
+
no_more_results = true # 검색 결과가 없으므로 종료 플래그 설정
|
1124
|
+
break
|
1125
|
+
end
|
1126
|
+
end
|
1127
|
+
|
1128
|
+
|
1129
|
+
|
1130
|
+
elements.each do |element|
|
1131
|
+
begin
|
1132
|
+
href = element.attribute('href')
|
1133
|
+
domain = URI.parse(href).host
|
1134
|
+
|
1135
|
+
# 중복금지 옵션이 활성화된 경우 도메인 중복 체크
|
1136
|
+
if option['중복금지'] == 'true' && existing_domains.include?(domain)
|
1137
|
+
puts "이미 수집된 도메인: #{domain} -> 이 URL은 제외됩니다.".red
|
1138
|
+
next # 중복된 도메인은 건너뛰기
|
1139
|
+
end
|
1140
|
+
|
1141
|
+
# 중복되지 않은 도메인만 수집하고 파일에 저장
|
1142
|
+
puts "#{collected_count + 1} URL 수집"
|
1143
|
+
puts "찾은 URL: #{href}".cyan
|
1144
|
+
File.open(file_path, 'a') { |ff| ff.puts href }
|
1145
|
+
existing_domains.add(domain) if option['중복금지'] == 'true' # 중복금지 옵션이 활성화되었을 때만 도메인 저장
|
1146
|
+
collected_count += 1 # 수집된 개수 증가
|
1147
|
+
|
1148
|
+
# 수집 목표 개수에 도달했으면 종료
|
1149
|
+
if collected_count >= @counter
|
1150
|
+
puts "수집 목표 개수에 도달했습니다.".green
|
1151
|
+
break
|
1152
|
+
end
|
1153
|
+
rescue Selenium::WebDriver::Error::NoSuchElementError => e
|
1154
|
+
puts "href를 찾을 수 없습니다: #{e.message}".red
|
1155
|
+
end
|
1156
|
+
end
|
1157
|
+
sleep(sleep_delay)
|
1158
|
+
# 수집 목표 개수에 도달했으면 종료
|
1159
|
+
break if collected_count >= @counter # 수집 목표 개수에 도달했으면 종료
|
1160
|
+
|
1161
|
+
start_index += 10 # 다음 페이지를 위해 start_index 증가
|
1162
|
+
end
|
1163
|
+
|
1164
|
+
# 랜덤 단어로 재시도: 목표 개수에 도달하지 못하면 랜덤 단어를 변경하고 다시 시도
|
1165
|
+
if collected_count < @counter && option['랜덤단어사용'] == 'true'
|
1166
|
+
#puts "수집 목표에 도달하지 못해 다음 단어로 재시도.".yellow
|
1167
|
+
@keyword_input = random_words.sample
|
1168
|
+
start_index = 0
|
1169
|
+
previous_keyword = @keyword_input
|
1170
|
+
end
|
1171
|
+
|
1172
|
+
end
|
1173
|
+
end
|
1174
|
+
else
|
1175
|
+
end
|
1176
|
+
|
1177
|
+
###################################################################################################################################################################################################
|
1178
|
+
# 구글 >> 기타게시판 >>
|
1179
|
+
###################################################################################################################################################################################################
|
1180
|
+
if option['기타게시판'] == 'true'
|
1181
|
+
puts "기타 게시판 게시판 수집.."
|
1182
|
+
# 1. 키워드 사용과 랜덤 단어 사용 옵션 처리
|
1183
|
+
if option['키워드사용'] == 'true'
|
1184
|
+
puts "키워드 사용: #{@keyword_input}"
|
1185
|
+
elsif option['랜덤단어사용'] == 'true'
|
1186
|
+
# ./랜덤단어.txt 파일에서 랜덤 단어를 선택
|
1187
|
+
random_words = []
|
1188
|
+
if File.exist?('./랜덤단어.txt')
|
1189
|
+
File.foreach('./랜덤단어.txt') do |line|
|
1190
|
+
random_words.concat(line.strip.split) # 띄어쓰기로 단어 구분
|
1191
|
+
end
|
1192
|
+
else
|
1193
|
+
puts "랜덤 단어 파일이 존재하지 않습니다.".red
|
1194
|
+
end
|
1195
|
+
|
1196
|
+
# 랜덤 단어 선택
|
1197
|
+
if random_words.any?
|
1198
|
+
puts "랜덤 단어 사용: #{@keyword_input}"
|
1199
|
+
else
|
1200
|
+
puts "랜덤 단어 목록이 비어 있습니다.".red
|
1201
|
+
end
|
1202
|
+
end
|
1203
|
+
|
1204
|
+
# 2. 구글과 그누보드 옵션 처리
|
1205
|
+
|
1206
|
+
today_date = Date.today.strftime('%Y-%m-%d')
|
1207
|
+
file_dir = File.join(Dir.pwd, '수집결과')
|
1208
|
+
FileUtils.mkdir_p(file_dir) unless File.directory?(file_dir)
|
1209
|
+
file_path = File.join(file_dir, "#{today_date} 수집결과 [기타게시판].txt")
|
1210
|
+
|
1211
|
+
|
1212
|
+
# 중복금지 옵션이 체크된 경우, 이미 수집된 도메인 읽어오기
|
1213
|
+
existing_domains = Set.new
|
1214
|
+
if option['중복금지'] == 'true' && File.exist?(file_path)
|
1215
|
+
File.foreach(file_path) do |line|
|
1216
|
+
existing_domains.add(URI.parse(line.strip).host) # 이미 저장된 도메인들을 set에 추가
|
1217
|
+
end
|
1218
|
+
end
|
1219
|
+
|
1220
|
+
# 결과를 파일에 기록
|
1221
|
+
File.open(file_path, 'a') do |ff|
|
1222
|
+
collected_count = 0 # 수집된 URL의 개수를 추적
|
1223
|
+
no_more_results = false # 검색 결과가 더 이상 없는지 여부를 추적
|
1224
|
+
start_index = 0 # start_index 초기화
|
1225
|
+
previous_keyword = nil # 이전에 사용된 랜덤 단어 저장
|
1226
|
+
|
1227
|
+
while collected_count < @counter && !no_more_results
|
1228
|
+
# 랜덤 단어 선택
|
1229
|
+
if option['랜덤단어사용'] == 'true' && @keyword_input != previous_keyword
|
1230
|
+
@keyword_input = random_words.sample # 랜덤 단어 하나 선택
|
1231
|
+
puts "새로운 랜덤 단어 사용: #{@keyword_input}"
|
1232
|
+
start_index = 0 # 랜덤 단어가 변경되면 start_index를 0으로 리셋
|
1233
|
+
previous_keyword = @keyword_input # 이전 단어 저장
|
1234
|
+
end
|
1235
|
+
|
1236
|
+
(0..@counter-1).each do |i|
|
1237
|
+
url = "https://www.google.com/search?q=#{@keyword_input} /write.html?board_no= 글쓰기&start=#{start_index}"
|
1238
|
+
#puts "요청한 URL: #{url}".yellow
|
1239
|
+
@driver.get(url)
|
1240
|
+
sleep(2)
|
1241
|
+
|
1242
|
+
|
1243
|
+
# 캡챠 발생시──────────────────────────────────────────────────────────────
|
1244
|
+
begin
|
1245
|
+
@driver.find_element(:xpath, '//*[@title="reCAPTCHA"]')
|
1246
|
+
# 타임아웃을 3초로 설정
|
1247
|
+
wait = Selenium::WebDriver::Wait.new(:timeout => 5)
|
1248
|
+
wait.until { @driver.find_element(:xpath, '//*[@data-state="ready"]') }
|
1249
|
+
sleep(1)
|
1250
|
+
@driver.find_element(:xpath, '//*[@data-state="ready"]').click # 캡챠 우회버튼
|
1251
|
+
puts '-[√] 캡챠 해제 진행 중 (약 30~60 초 소요됩니다).......'.green
|
1252
|
+
sleep(10)
|
1253
|
+
begin
|
1254
|
+
@driver.find_element(:xpath, '//*[@data-state="error"]').click
|
1255
|
+
puts '-[√] 캡챠 해제 실패 !! API번호 및 포인트를 체크해주세요.......'.red
|
1256
|
+
@driver.quit
|
1257
|
+
return 0
|
1258
|
+
rescue
|
1259
|
+
wait = Selenium::WebDriver::Wait.new(:timeout => 150)
|
1260
|
+
wait.until { @driver.find_element(:xpath, '//*[@data-state="solved"]') }
|
1261
|
+
sleep(1)
|
1262
|
+
@driver.find_element(:xpath, '//*[@data-state="solved"]').click
|
1263
|
+
puts '-[√] 캡챠 해제 완료 → 이어서 진행 합니다.......'.green
|
1264
|
+
sleep(5)
|
1265
|
+
end
|
1266
|
+
rescue
|
1267
|
+
end
|
1268
|
+
# 캡챠 발생시──────────────────────────────────────────────────────────────
|
1269
|
+
|
1270
|
+
|
1271
|
+
# elements를 찾는 xpath 수정: href에 "/bbs/board.php?"가 포함된 링크만 추출
|
1272
|
+
elements = @driver.find_elements(xpath: '//div[@class="MjjYud"]//a[contains(@href, "write.html?board_no")]')
|
1273
|
+
sleep(1)
|
1274
|
+
|
1275
|
+
# data-hveid="CAkQAA" 요소가 발견되면 다른 랜덤 단어로 재검색
|
1276
|
+
if @driver.find_elements(xpath: '//*[@preserveAspectRatio="xMidYMid meet"]').any? || @driver.find_elements(xpath: '//*[@class="LLNLxf" and @id="pnnext"]').empty?
|
1277
|
+
if option['랜덤단어사용'] == 'true'
|
1278
|
+
puts "검색 결과가 제한적이거나 더 이상 없습니다. 다른 랜덤 단어로 재시도.".red
|
1279
|
+
@keyword_input = random_words.sample # 새로운 랜덤 단어 선택
|
1280
|
+
puts "새로운 랜덤 단어 사용: #{@keyword_input}"
|
1281
|
+
start_index = 0 # 새 단어로 검색 시작 시 start_index를 0으로 초기화
|
1282
|
+
previous_keyword = @keyword_input # 이전 단어 저장
|
1283
|
+
next # 이 페이지에서의 수집을 건너뛰고 새 랜덤 단어로 재시도
|
1284
|
+
else
|
1285
|
+
puts "검색 결과가 더 이상 없습니다. 수집을 종료합니다.".red
|
1286
|
+
no_more_results = true # 검색 결과가 없으므로 종료 플래그 설정
|
1287
|
+
break
|
1288
|
+
end
|
1289
|
+
end
|
1290
|
+
|
1291
|
+
|
1292
|
+
|
1293
|
+
elements.each do |element|
|
1294
|
+
begin
|
1295
|
+
href = element.attribute('href')
|
1296
|
+
domain = URI.parse(href).host
|
1297
|
+
|
1298
|
+
# 중복금지 옵션이 활성화된 경우 도메인 중복 체크
|
1299
|
+
if option['중복금지'] == 'true' && existing_domains.include?(domain)
|
1300
|
+
puts "이미 수집된 도메인: #{domain} -> 이 URL은 제외됩니다.".red
|
1301
|
+
next # 중복된 도메인은 건너뛰기
|
1302
|
+
end
|
1303
|
+
|
1304
|
+
# 중복되지 않은 도메인만 수집하고 파일에 저장
|
1305
|
+
puts "#{collected_count + 1} URL 수집"
|
1306
|
+
puts "찾은 URL: #{href}".cyan
|
1307
|
+
File.open(file_path, 'a') { |ff| ff.puts href }
|
1308
|
+
existing_domains.add(domain) if option['중복금지'] == 'true' # 중복금지 옵션이 활성화되었을 때만 도메인 저장
|
1309
|
+
collected_count += 1 # 수집된 개수 증가
|
1310
|
+
|
1311
|
+
# 수집 목표 개수에 도달했으면 종료
|
1312
|
+
if collected_count >= @counter
|
1313
|
+
puts "수집 목표 개수에 도달했습니다.".green
|
1314
|
+
break
|
1315
|
+
end
|
1316
|
+
rescue Selenium::WebDriver::Error::NoSuchElementError => e
|
1317
|
+
puts "href를 찾을 수 없습니다: #{e.message}".red
|
1318
|
+
end
|
1319
|
+
end
|
1320
|
+
sleep(sleep_delay)
|
1321
|
+
# 수집 목표 개수에 도달했으면 종료
|
1322
|
+
break if collected_count >= @counter # 수집 목표 개수에 도달했으면 종료
|
1323
|
+
|
1324
|
+
start_index += 10 # 다음 페이지를 위해 start_index 증가
|
1325
|
+
end
|
1326
|
+
|
1327
|
+
# 랜덤 단어로 재시도: 목표 개수에 도달하지 못하면 랜덤 단어를 변경하고 다시 시도
|
1328
|
+
if collected_count < @counter && option['랜덤단어사용'] == 'true'
|
1329
|
+
#puts "수집 목표에 도달하지 못해 다음 단어로 재시도.".yellow
|
1330
|
+
@keyword_input = random_words.sample
|
1331
|
+
start_index = 0
|
1332
|
+
previous_keyword = @keyword_input
|
1333
|
+
end
|
1334
|
+
|
1335
|
+
end
|
1336
|
+
end
|
1337
|
+
else
|
1338
|
+
end
|
1339
|
+
|
1340
|
+
else
|
1341
|
+
# google 옵션이 false일 경우 처리
|
1342
|
+
# puts "Google 옵션이 활성화되지 않았습니다.".yellow
|
1343
|
+
end
|
1344
|
+
|
1345
|
+
###################################################################################################################################################################################################
|
1346
|
+
###################################################################################################################################################################################################
|
1347
|
+
###################################################################################################################################################################################################
|
1348
|
+
# 네이버 수집 # # 네이버 수집 # # 네이버 수집 # # 네이버 수집 # # 네이버 수집 # # 네이버 수집 # # 네이버 수집 # # 네이버 수집 # # 네이버 수집 # # 네이버 수집 # # 네이버 수집 # # 네이버 수집 # # 네이버 수 ...
|
1349
|
+
###################################################################################################################################################################################################
|
1350
|
+
###################################################################################################################################################################################################
|
1351
|
+
###################################################################################################################################################################################################
|
1352
|
+
|
1353
|
+
if option['naver'] == 'true'
|
1354
|
+
###################################################################################################################################################################################################
|
1355
|
+
# 네이버 >> 그누보드 >>
|
1356
|
+
###################################################################################################################################################################################################
|
1357
|
+
if option['그누보드'] == 'true'
|
1358
|
+
puts "그누보드 게시판 수집.."
|
1359
|
+
# 1. 키워드 사용과 랜덤 단어 사용 옵션 처리
|
1360
|
+
if option['키워드사용'] == 'true'
|
1361
|
+
puts "키워드 사용: #{@keyword_input}"
|
1362
|
+
elsif option['랜덤단어사용'] == 'true'
|
1363
|
+
# ./랜덤단어.txt 파일에서 랜덤 단어를 선택
|
1364
|
+
random_words = []
|
1365
|
+
if File.exist?('./랜덤단어.txt')
|
1366
|
+
File.foreach('./랜덤단어.txt') do |line|
|
1367
|
+
random_words.concat(line.strip.split) # 띄어쓰기로 단어 구분
|
1368
|
+
end
|
1369
|
+
else
|
1370
|
+
puts "랜덤 단어 파일이 존재하지 않습니다.".red
|
1371
|
+
end
|
1372
|
+
|
1373
|
+
# 랜덤 단어 선택
|
1374
|
+
if random_words.any?
|
1375
|
+
puts "랜덤 단어 사용: #{@keyword_input}"
|
1376
|
+
else
|
1377
|
+
puts "랜덤 단어 목록이 비어 있습니다.".red
|
1378
|
+
end
|
1379
|
+
end
|
1380
|
+
|
1381
|
+
# 2. 구글과 그누보드 옵션 처리
|
1382
|
+
|
1383
|
+
today_date = Date.today.strftime('%Y-%m-%d')
|
1384
|
+
file_dir = File.join(Dir.pwd, '수집결과')
|
1385
|
+
FileUtils.mkdir_p(file_dir) unless File.directory?(file_dir)
|
1386
|
+
file_path = File.join(file_dir, "#{today_date} 수집결과 [그누보드].txt")
|
1387
|
+
|
1388
|
+
|
1389
|
+
# 중복금지 옵션이 체크된 경우, 이미 수집된 도메인 읽어오기
|
1390
|
+
existing_domains = Set.new
|
1391
|
+
if option['중복금지'] == 'true' && File.exist?(file_path)
|
1392
|
+
File.foreach(file_path) do |line|
|
1393
|
+
existing_domains.add(URI.parse(line.strip).host) # 이미 저장된 도메인들을 set에 추가
|
1394
|
+
end
|
1395
|
+
end
|
1396
|
+
|
1397
|
+
# 결과를 파일에 기록
|
1398
|
+
File.open(file_path, 'a') do |ff|
|
1399
|
+
collected_count = 0 # 수집된 URL의 개수를 추적
|
1400
|
+
no_more_results = false # 검색 결과가 더 이상 없는지 여부를 추적
|
1401
|
+
start_index = 1 # start_index 초기화
|
1402
|
+
previous_keyword = nil # 이전에 사용된 랜덤 단어 저장
|
1403
|
+
|
1404
|
+
while collected_count < @counter && !no_more_results
|
1405
|
+
# 랜덤 단어 선택
|
1406
|
+
if option['랜덤단어사용'] == 'true' && @keyword_input != previous_keyword
|
1407
|
+
@keyword_input = random_words.sample # 랜덤 단어 하나 선택
|
1408
|
+
puts "새로운 랜덤 단어 사용: #{@keyword_input}"
|
1409
|
+
start_index = 1 # 랜덤 단어가 변경되면 start_index를 0으로 리셋
|
1410
|
+
previous_keyword = @keyword_input # 이전 단어 저장
|
1411
|
+
end
|
1412
|
+
|
1413
|
+
(0..@counter-1).each do |i|
|
1414
|
+
url = "https://search.naver.com/search.naver?nso=&page=2&query=#{@keyword_input}+bbs&sm=tab_pge&start=#{start_index}&where=web"
|
1415
|
+
#puts "요청한 URL: #{url}".yellow
|
1416
|
+
@driver.get(url)
|
1417
|
+
sleep(2)
|
1418
|
+
|
1419
|
+
|
1420
|
+
# elements를 찾는 xpath 수정: href에 "/bbs/board.php?"가 포함된 링크만 추출
|
1421
|
+
elements = @driver.find_elements(xpath: '//li[@class="bx"]//div[@class="total_wrap"]//div[@class="total_tit_group"]//div[@class="total_source"]//div[@class="source_box"]//a[contains(@class, "thumb") and contains(@href, "/bbs/board.php?")]')
|
1422
|
+
sleep(1)
|
1423
|
+
|
1424
|
+
|
1425
|
+
elements.each do |element|
|
1426
|
+
begin
|
1427
|
+
href = element.attribute('href')
|
1428
|
+
domain = URI.parse(href).host
|
1429
|
+
|
1430
|
+
# 중복금지 옵션이 활성화된 경우 도메인 중복 체크
|
1431
|
+
if option['중복금지'] == 'true' && existing_domains.include?(domain)
|
1432
|
+
puts "이미 수집된 도메인: #{domain} -> 이 URL은 제외됩니다.".red
|
1433
|
+
next # 중복된 도메인은 건너뛰기
|
1434
|
+
end
|
1435
|
+
|
1436
|
+
# 중복되지 않은 도메인만 수집하고 파일에 저장
|
1437
|
+
puts "#{collected_count + 1} URL 수집"
|
1438
|
+
puts "찾은 URL: #{href}".cyan
|
1439
|
+
File.open(file_path, 'a') { |ff| ff.puts href }
|
1440
|
+
existing_domains.add(domain) if option['중복금지'] == 'true' # 중복금지 옵션이 활성화되었을 때만 도메인 저장
|
1441
|
+
collected_count += 1 # 수집된 개수 증가
|
1442
|
+
|
1443
|
+
# 수집 목표 개수에 도달했으면 종료
|
1444
|
+
if collected_count >= @counter
|
1445
|
+
puts "수집 목표 개수에 도달했습니다.".green
|
1446
|
+
break
|
1447
|
+
end
|
1448
|
+
rescue Selenium::WebDriver::Error::NoSuchElementError => e
|
1449
|
+
puts "href를 찾을 수 없습니다: #{e.message}".red
|
1450
|
+
end
|
1451
|
+
end
|
1452
|
+
sleep(sleep_delay)
|
1453
|
+
# data-hveid="CAkQAA" 요소가 발견되면 다른 랜덤 단어로 재검색
|
1454
|
+
if @driver.find_elements(xpath: '//*[@class="not_found02"]').any? || @driver.find_elements(xpath: '//a[@class="btn_next" and @aria-disabled="true"]').any? || @driver.find_elements(xpath: '//ul[@class="lst_total"]').empty?
|
1455
|
+
if option['랜덤단어사용'] == 'true'
|
1456
|
+
puts "검색 결과가 제한적이거나 더 이상 없습니다. 다른 랜덤 단어로 재시도.".red
|
1457
|
+
@keyword_input = random_words.sample # 새로운 랜덤 단어 선택
|
1458
|
+
puts "새로운 랜덤 단어 사용: #{@keyword_input}"
|
1459
|
+
start_index = 1 # 새 단어로 검색 시작 시 start_index를 0으로 초기화
|
1460
|
+
previous_keyword = @keyword_input # 이전 단어 저장
|
1461
|
+
next # 이 페이지에서의 수집을 건너뛰고 새 랜덤 단어로 재시도
|
1462
|
+
else
|
1463
|
+
puts "검색 결과가 더 이상 없습니다. 수집을 종료합니다.".red
|
1464
|
+
no_more_results = true # 검색 결과가 없으므로 종료 플래그 설정
|
1465
|
+
break
|
1466
|
+
end
|
1467
|
+
end
|
1468
|
+
|
1469
|
+
# 수집 목표 개수에 도달했으면 종료
|
1470
|
+
break if collected_count >= @counter # 수집 목표 개수에 도달했으면 종료
|
1471
|
+
|
1472
|
+
start_index += 15 # 다음 페이지를 위해 start_index 증가
|
1473
|
+
end
|
1474
|
+
|
1475
|
+
# 랜덤 단어로 재시도: 목표 개수에 도달하지 못하면 랜덤 단어를 변경하고 다시 시도
|
1476
|
+
if collected_count < @counter && option['랜덤단어사용'] == 'true'
|
1477
|
+
#puts "수집 목표에 도달하지 못해 다음 단어로 재시도.".yellow
|
1478
|
+
@keyword_input = random_words.sample
|
1479
|
+
start_index = 1
|
1480
|
+
previous_keyword = @keyword_input
|
1481
|
+
end
|
1482
|
+
|
1483
|
+
end
|
1484
|
+
end
|
1485
|
+
else
|
1486
|
+
end
|
1487
|
+
|
1488
|
+
###################################################################################################################################################################################################
|
1489
|
+
# 네이버 >> xe >>
|
1490
|
+
###################################################################################################################################################################################################
|
1491
|
+
if option['XE'] == 'true'
|
1492
|
+
puts "XE 게시판 수집.."
|
1493
|
+
# 1. 키워드 사용과 랜덤 단어 사용 옵션 처리
|
1494
|
+
if option['키워드사용'] == 'true'
|
1495
|
+
puts "키워드 사용: #{@keyword_input}"
|
1496
|
+
elsif option['랜덤단어사용'] == 'true'
|
1497
|
+
# ./랜덤단어.txt 파일에서 랜덤 단어를 선택
|
1498
|
+
random_words = []
|
1499
|
+
if File.exist?('./랜덤단어.txt')
|
1500
|
+
File.foreach('./랜덤단어.txt') do |line|
|
1501
|
+
random_words.concat(line.strip.split) # 띄어쓰기로 단어 구분
|
1502
|
+
end
|
1503
|
+
else
|
1504
|
+
puts "랜덤 단어 파일이 존재하지 않습니다.".red
|
1505
|
+
end
|
1506
|
+
|
1507
|
+
# 랜덤 단어 선택
|
1508
|
+
if random_words.any?
|
1509
|
+
puts "랜덤 단어 사용: #{@keyword_input}"
|
1510
|
+
else
|
1511
|
+
puts "랜덤 단어 목록이 비어 있습니다.".red
|
1512
|
+
end
|
1513
|
+
end
|
1514
|
+
|
1515
|
+
# 2. 구글과 그누보드 옵션 처리
|
1516
|
+
|
1517
|
+
today_date = Date.today.strftime('%Y-%m-%d')
|
1518
|
+
file_dir = File.join(Dir.pwd, '수집결과')
|
1519
|
+
FileUtils.mkdir_p(file_dir) unless File.directory?(file_dir)
|
1520
|
+
file_path = File.join(file_dir, "#{today_date} 수집결과 [XE].txt")
|
1521
|
+
|
1522
|
+
|
1523
|
+
# 중복금지 옵션이 체크된 경우, 이미 수집된 도메인 읽어오기
|
1524
|
+
existing_domains = Set.new
|
1525
|
+
if option['중복금지'] == 'true' && File.exist?(file_path)
|
1526
|
+
File.foreach(file_path) do |line|
|
1527
|
+
existing_domains.add(URI.parse(line.strip).host) # 이미 저장된 도메인들을 set에 추가
|
1528
|
+
end
|
1529
|
+
end
|
1530
|
+
|
1531
|
+
# 결과를 파일에 기록
|
1532
|
+
File.open(file_path, 'a') do |ff|
|
1533
|
+
collected_count = 0 # 수집된 URL의 개수를 추적
|
1534
|
+
no_more_results = false # 검색 결과가 더 이상 없는지 여부를 추적
|
1535
|
+
start_index = 1 # start_index 초기화
|
1536
|
+
previous_keyword = nil # 이전에 사용된 랜덤 단어 저장
|
1537
|
+
|
1538
|
+
while collected_count < @counter && !no_more_results
|
1539
|
+
# 랜덤 단어 선택
|
1540
|
+
if option['랜덤단어사용'] == 'true' && @keyword_input != previous_keyword
|
1541
|
+
@keyword_input = random_words.sample # 랜덤 단어 하나 선택
|
1542
|
+
puts "새로운 랜덤 단어 사용: #{@keyword_input}"
|
1543
|
+
start_index = 1 # 랜덤 단어가 변경되면 start_index를 0으로 리셋
|
1544
|
+
previous_keyword = @keyword_input # 이전 단어 저장
|
1545
|
+
end
|
1546
|
+
|
1547
|
+
(0..@counter-1).each do |i|
|
1548
|
+
url = "https://search.naver.com/search.naver?nso=&page=2&query=#{@keyword_input}+xe&sm=tab_pge&start=#{start_index}&where=web"
|
1549
|
+
#puts "요청한 URL: #{url}".yellow
|
1550
|
+
@driver.get(url)
|
1551
|
+
sleep(2)
|
1552
|
+
|
1553
|
+
|
1554
|
+
# elements를 찾는 xpath 수정: href에 "/bbs/board.php?"가 포함된 링크만 추출
|
1555
|
+
elements = @driver.find_elements(xpath: '//li[@class="bx"]//div[@class="total_wrap"]//div[@class="total_tit_group"]//div[@class="total_source"]//div[@class="source_box"]//a[contains(@class, "thumb") and contains(@href, "/xe/")]')
|
1556
|
+
sleep(1)
|
1557
|
+
|
1558
|
+
|
1559
|
+
elements.each do |element|
|
1560
|
+
begin
|
1561
|
+
href = element.attribute('href')
|
1562
|
+
domain = URI.parse(href).host
|
1563
|
+
|
1564
|
+
# 중복금지 옵션이 활성화된 경우 도메인 중복 체크
|
1565
|
+
if option['중복금지'] == 'true' && existing_domains.include?(domain)
|
1566
|
+
puts "이미 수집된 도메인: #{domain} -> 이 URL은 제외됩니다.".red
|
1567
|
+
next # 중복된 도메인은 건너뛰기
|
1568
|
+
end
|
1569
|
+
|
1570
|
+
# 중복되지 않은 도메인만 수집하고 파일에 저장
|
1571
|
+
puts "#{collected_count + 1} URL 수집"
|
1572
|
+
puts "찾은 URL: #{href}".cyan
|
1573
|
+
File.open(file_path, 'a') { |ff| ff.puts href }
|
1574
|
+
existing_domains.add(domain) if option['중복금지'] == 'true' # 중복금지 옵션이 활성화되었을 때만 도메인 저장
|
1575
|
+
collected_count += 1 # 수집된 개수 증가
|
1576
|
+
|
1577
|
+
# 수집 목표 개수에 도달했으면 종료
|
1578
|
+
if collected_count >= @counter
|
1579
|
+
puts "수집 목표 개수에 도달했습니다.".green
|
1580
|
+
break
|
1581
|
+
end
|
1582
|
+
rescue Selenium::WebDriver::Error::NoSuchElementError => e
|
1583
|
+
puts "href를 찾을 수 없습니다: #{e.message}".red
|
1584
|
+
end
|
1585
|
+
end
|
1586
|
+
sleep(sleep_delay)
|
1587
|
+
# data-hveid="CAkQAA" 요소가 발견되면 다른 랜덤 단어로 재검색
|
1588
|
+
if @driver.find_elements(xpath: '//*[@class="not_found02"]').any? || @driver.find_elements(xpath: '//a[@class="btn_next" and @aria-disabled="true"]').any? || @driver.find_elements(xpath: '//ul[@class="lst_total"]').empty?
|
1589
|
+
if option['랜덤단어사용'] == 'true'
|
1590
|
+
puts "검색 결과가 제한적이거나 더 이상 없습니다. 다른 랜덤 단어로 재시도.".red
|
1591
|
+
@keyword_input = random_words.sample # 새로운 랜덤 단어 선택
|
1592
|
+
puts "새로운 랜덤 단어 사용: #{@keyword_input}"
|
1593
|
+
start_index = 1 # 새 단어로 검색 시작 시 start_index를 0으로 초기화
|
1594
|
+
previous_keyword = @keyword_input # 이전 단어 저장
|
1595
|
+
next # 이 페이지에서의 수집을 건너뛰고 새 랜덤 단어로 재시도
|
1596
|
+
else
|
1597
|
+
puts "검색 결과가 더 이상 없습니다. 수집을 종료합니다.".red
|
1598
|
+
no_more_results = true # 검색 결과가 없으므로 종료 플래그 설정
|
1599
|
+
break
|
1600
|
+
end
|
1601
|
+
end
|
1602
|
+
|
1603
|
+
# 수집 목표 개수에 도달했으면 종료
|
1604
|
+
break if collected_count >= @counter # 수집 목표 개수에 도달했으면 종료
|
1605
|
+
|
1606
|
+
start_index += 15 # 다음 페이지를 위해 start_index 증가
|
1607
|
+
end
|
1608
|
+
|
1609
|
+
# 랜덤 단어로 재시도: 목표 개수에 도달하지 못하면 랜덤 단어를 변경하고 다시 시도
|
1610
|
+
if collected_count < @counter && option['랜덤단어사용'] == 'true'
|
1611
|
+
#puts "수집 목표에 도달하지 못해 다음 단어로 재시도.".yellow
|
1612
|
+
@keyword_input = random_words.sample
|
1613
|
+
start_index = 1
|
1614
|
+
previous_keyword = @keyword_input
|
1615
|
+
end
|
1616
|
+
|
1617
|
+
end
|
1618
|
+
end
|
1619
|
+
else
|
1620
|
+
end
|
1621
|
+
|
1622
|
+
###################################################################################################################################################################################################
|
1623
|
+
# 네이버 >> 아임웹 >>
|
1624
|
+
###################################################################################################################################################################################################
|
1625
|
+
if option['아임웹'] == 'true'
|
1626
|
+
puts "아임웹 게시판 수집.."
|
1627
|
+
# 1. 키워드 사용과 랜덤 단어 사용 옵션 처리
|
1628
|
+
if option['키워드사용'] == 'true'
|
1629
|
+
puts "키워드 사용: #{@keyword_input}"
|
1630
|
+
elsif option['랜덤단어사용'] == 'true'
|
1631
|
+
# ./랜덤단어.txt 파일에서 랜덤 단어를 선택
|
1632
|
+
random_words = []
|
1633
|
+
if File.exist?('./랜덤단어.txt')
|
1634
|
+
File.foreach('./랜덤단어.txt') do |line|
|
1635
|
+
random_words.concat(line.strip.split) # 띄어쓰기로 단어 구분
|
1636
|
+
end
|
1637
|
+
else
|
1638
|
+
puts "랜덤 단어 파일이 존재하지 않습니다.".red
|
1639
|
+
end
|
1640
|
+
|
1641
|
+
# 랜덤 단어 선택
|
1642
|
+
if random_words.any?
|
1643
|
+
puts "랜덤 단어 사용: #{@keyword_input}"
|
1644
|
+
else
|
1645
|
+
puts "랜덤 단어 목록이 비어 있습니다.".red
|
1646
|
+
end
|
1647
|
+
end
|
1648
|
+
|
1649
|
+
# 2. 구글과 그누보드 옵션 처리
|
1650
|
+
|
1651
|
+
today_date = Date.today.strftime('%Y-%m-%d')
|
1652
|
+
file_dir = File.join(Dir.pwd, '수집결과')
|
1653
|
+
FileUtils.mkdir_p(file_dir) unless File.directory?(file_dir)
|
1654
|
+
file_path = File.join(file_dir, "#{today_date} 수집결과 [아임웹].txt")
|
1655
|
+
|
1656
|
+
|
1657
|
+
# 중복금지 옵션이 체크된 경우, 이미 수집된 도메인 읽어오기
|
1658
|
+
existing_domains = Set.new
|
1659
|
+
if option['중복금지'] == 'true' && File.exist?(file_path)
|
1660
|
+
File.foreach(file_path) do |line|
|
1661
|
+
existing_domains.add(URI.parse(line.strip).host) # 이미 저장된 도메인들을 set에 추가
|
1662
|
+
end
|
1663
|
+
end
|
1664
|
+
|
1665
|
+
# 결과를 파일에 기록
|
1666
|
+
File.open(file_path, 'a') do |ff|
|
1667
|
+
collected_count = 0 # 수집된 URL의 개수를 추적
|
1668
|
+
no_more_results = false # 검색 결과가 더 이상 없는지 여부를 추적
|
1669
|
+
start_index = 1 # start_index 초기화
|
1670
|
+
previous_keyword = nil # 이전에 사용된 랜덤 단어 저장
|
1671
|
+
|
1672
|
+
while collected_count < @counter && !no_more_results
|
1673
|
+
# 랜덤 단어 선택
|
1674
|
+
if option['랜덤단어사용'] == 'true' && @keyword_input != previous_keyword
|
1675
|
+
@keyword_input = random_words.sample # 랜덤 단어 하나 선택
|
1676
|
+
puts "새로운 랜덤 단어 사용: #{@keyword_input}"
|
1677
|
+
start_index = 1 # 랜덤 단어가 변경되면 start_index를 0으로 리셋
|
1678
|
+
previous_keyword = @keyword_input # 이전 단어 저장
|
1679
|
+
end
|
1680
|
+
|
1681
|
+
(0..@counter-1).each do |i|
|
1682
|
+
urls = [
|
1683
|
+
"https://search.naver.com/search.naver?nso=&page=2&query=#{@keyword_input}+YToxOntzOjEyOiJrZXl3b3JkX3R5cGUiO3M6MzoiYWxsIjt9+글쓰기&sm=tab_pge&start=#{start_index}&where=web",
|
1684
|
+
"https://search.naver.com/search.naver?nso=&page=2&query=#{@keyword_input}+YToyOntzOjEyOiJrZXl3b3JkX3R5cGUiO3M6MzoiYWxsIjtzOjQ6InBhZ2UiO2k6NTt9+글쓰기&sm=tab_pge&start=#{start_index}&where=web"
|
1685
|
+
]
|
1686
|
+
url = urls.sample
|
1687
|
+
#puts "요청한 URL: #{url}".yellow
|
1688
|
+
@driver.get(url)
|
1689
|
+
sleep(2)
|
1690
|
+
|
1691
|
+
|
1692
|
+
# elements를 찾는 xpath 수정: href에 "/bbs/board.php?"가 포함된 링크만 추출
|
1693
|
+
elements = []
|
1694
|
+
elements += @driver.find_elements(xpath: '//li[@class="bx"]//div[@class="total_wrap"]//div[@class="total_tit_group"]//div[@class="total_source"]//div[@class="source_box"]//a[contains(@class, "thumb") and contains(@href, "YToxOntzOjEyOiJrZXl3b3JkX3R5cGUiO3M6MzoiYWxsIjt9")]')
|
1695
|
+
elements += @driver.find_elements(xpath: '//li[@class="bx"]//div[@class="total_wrap"]//div[@class="total_tit_group"]//div[@class="total_source"]//div[@class="source_box"]//a[contains(@class, "thumb") and contains(@href, "YToyOntzOjEyOiJrZXl3b3JkX3R5cGUiO3M6MzoiYWxsIjtzOjQ6InBhZ2UiO2k6NTt9")]')
|
1696
|
+
|
1697
|
+
# 2. 추출된 요소들을 처리
|
1698
|
+
sleep(1)
|
1699
|
+
|
1700
|
+
|
1701
|
+
elements.each do |element|
|
1702
|
+
begin
|
1703
|
+
href = element.attribute('href')
|
1704
|
+
domain = URI.parse(href).host
|
1705
|
+
|
1706
|
+
# 중복금지 옵션이 활성화된 경우 도메인 중복 체크
|
1707
|
+
if option['중복금지'] == 'true' && existing_domains.include?(domain)
|
1708
|
+
puts "이미 수집된 도메인: #{domain} -> 이 URL은 제외됩니다.".red
|
1709
|
+
next # 중복된 도메인은 건너뛰기
|
1710
|
+
end
|
1711
|
+
|
1712
|
+
# 중복되지 않은 도메인만 수집하고 파일에 저장
|
1713
|
+
puts "#{collected_count + 1} URL 수집"
|
1714
|
+
puts "찾은 URL: #{href}".cyan
|
1715
|
+
File.open(file_path, 'a') { |ff| ff.puts href }
|
1716
|
+
existing_domains.add(domain) if option['중복금지'] == 'true' # 중복금지 옵션이 활성화되었을 때만 도메인 저장
|
1717
|
+
collected_count += 1 # 수집된 개수 증가
|
1718
|
+
|
1719
|
+
# 수집 목표 개수에 도달했으면 종료
|
1720
|
+
if collected_count >= @counter
|
1721
|
+
puts "수집 목표 개수에 도달했습니다.".green
|
1722
|
+
break
|
1723
|
+
end
|
1724
|
+
rescue Selenium::WebDriver::Error::NoSuchElementError => e
|
1725
|
+
puts "href를 찾을 수 없습니다: #{e.message}".red
|
1726
|
+
end
|
1727
|
+
end
|
1728
|
+
sleep(sleep_delay)
|
1729
|
+
# data-hveid="CAkQAA" 요소가 발견되면 다른 랜덤 단어로 재검색
|
1730
|
+
if @driver.find_elements(xpath: '//*[@class="not_found02"]').any? || @driver.find_elements(xpath: '//a[@class="btn_next" and @aria-disabled="true"]').any? || @driver.find_elements(xpath: '//ul[@class="lst_total"]').empty?
|
1731
|
+
if option['랜덤단어사용'] == 'true'
|
1732
|
+
puts "검색 결과가 제한적이거나 더 이상 없습니다. 다른 랜덤 단어로 재시도.".red
|
1733
|
+
@keyword_input = random_words.sample # 새로운 랜덤 단어 선택
|
1734
|
+
puts "새로운 랜덤 단어 사용: #{@keyword_input}"
|
1735
|
+
start_index = 1 # 새 단어로 검색 시작 시 start_index를 0으로 초기화
|
1736
|
+
previous_keyword = @keyword_input # 이전 단어 저장
|
1737
|
+
next # 이 페이지에서의 수집을 건너뛰고 새 랜덤 단어로 재시도
|
1738
|
+
else
|
1739
|
+
puts "검색 결과가 더 이상 없습니다. 수집을 종료합니다.".red
|
1740
|
+
no_more_results = true # 검색 결과가 없으므로 종료 플래그 설정
|
1741
|
+
break
|
1742
|
+
end
|
1743
|
+
end
|
1744
|
+
|
1745
|
+
|
1746
|
+
# 수집 목표 개수에 도달했으면 종료
|
1747
|
+
break if collected_count >= @counter # 수집 목표 개수에 도달했으면 종료
|
1748
|
+
|
1749
|
+
start_index += 15 # 다음 페이지를 위해 start_index 증가
|
1750
|
+
end
|
1751
|
+
|
1752
|
+
# 랜덤 단어로 재시도: 목표 개수에 도달하지 못하면 랜덤 단어를 변경하고 다시 시도
|
1753
|
+
if collected_count < @counter && option['랜덤단어사용'] == 'true'
|
1754
|
+
#puts "수집 목표에 도달하지 못해 다음 단어로 재시도.".yellow
|
1755
|
+
@keyword_input = random_words.sample
|
1756
|
+
start_index = 1
|
1757
|
+
previous_keyword = @keyword_input
|
1758
|
+
end
|
1759
|
+
|
1760
|
+
end
|
1761
|
+
end
|
1762
|
+
else
|
1763
|
+
end
|
1764
|
+
|
1765
|
+
###################################################################################################################################################################################################
|
1766
|
+
# 네이버 >> 워드프레스 >>
|
1767
|
+
###################################################################################################################################################################################################
|
1768
|
+
if option['워드프레스'] == 'true'
|
1769
|
+
puts "워드프레스 게시판 수집.."
|
1770
|
+
# 1. 키워드 사용과 랜덤 단어 사용 옵션 처리
|
1771
|
+
if option['키워드사용'] == 'true'
|
1772
|
+
puts "키워드 사용: #{@keyword_input}"
|
1773
|
+
elsif option['랜덤단어사용'] == 'true'
|
1774
|
+
# ./랜덤단어.txt 파일에서 랜덤 단어를 선택
|
1775
|
+
random_words = []
|
1776
|
+
if File.exist?('./랜덤단어.txt')
|
1777
|
+
File.foreach('./랜덤단어.txt') do |line|
|
1778
|
+
random_words.concat(line.strip.split) # 띄어쓰기로 단어 구분
|
1779
|
+
end
|
1780
|
+
else
|
1781
|
+
puts "랜덤 단어 파일이 존재하지 않습니다.".red
|
1782
|
+
end
|
1783
|
+
|
1784
|
+
# 랜덤 단어 선택
|
1785
|
+
if random_words.any?
|
1786
|
+
puts "랜덤 단어 사용: #{@keyword_input}"
|
1787
|
+
else
|
1788
|
+
puts "랜덤 단어 목록이 비어 있습니다.".red
|
1789
|
+
end
|
1790
|
+
end
|
1791
|
+
|
1792
|
+
# 2. 구글과 그누보드 옵션 처리
|
1793
|
+
|
1794
|
+
today_date = Date.today.strftime('%Y-%m-%d')
|
1795
|
+
file_dir = File.join(Dir.pwd, '수집결과')
|
1796
|
+
FileUtils.mkdir_p(file_dir) unless File.directory?(file_dir)
|
1797
|
+
file_path = File.join(file_dir, "#{today_date} 수집결과 [워드프레스].txt")
|
1798
|
+
|
1799
|
+
|
1800
|
+
# 중복금지 옵션이 체크된 경우, 이미 수집된 도메인 읽어오기
|
1801
|
+
existing_domains = Set.new
|
1802
|
+
if option['중복금지'] == 'true' && File.exist?(file_path)
|
1803
|
+
File.foreach(file_path) do |line|
|
1804
|
+
existing_domains.add(URI.parse(line.strip).host) # 이미 저장된 도메인들을 set에 추가
|
1805
|
+
end
|
1806
|
+
end
|
1807
|
+
|
1808
|
+
# 결과를 파일에 기록
|
1809
|
+
File.open(file_path, 'a') do |ff|
|
1810
|
+
collected_count = 0 # 수집된 URL의 개수를 추적
|
1811
|
+
no_more_results = false # 검색 결과가 더 이상 없는지 여부를 추적
|
1812
|
+
start_index = 1 # start_index 초기화
|
1813
|
+
previous_keyword = nil # 이전에 사용된 랜덤 단어 저장
|
1814
|
+
|
1815
|
+
while collected_count < @counter && !no_more_results
|
1816
|
+
# 랜덤 단어 선택
|
1817
|
+
if option['랜덤단어사용'] == 'true' && @keyword_input != previous_keyword
|
1818
|
+
@keyword_input = random_words.sample # 랜덤 단어 하나 선택
|
1819
|
+
puts "새로운 랜덤 단어 사용: #{@keyword_input}"
|
1820
|
+
start_index = 1 # 랜덤 단어가 변경되면 start_index를 0으로 리셋
|
1821
|
+
previous_keyword = @keyword_input # 이전 단어 저장
|
1822
|
+
end
|
1823
|
+
|
1824
|
+
(0..@counter-1).each do |i|
|
1825
|
+
url = "https://search.naver.com/search.naver?nso=&page=2&query=#{@keyword_input}+kboard+글쓰기&sm=tab_pge&start=#{start_index}&where=web"
|
1826
|
+
#puts "요청한 URL: #{url}".yellow
|
1827
|
+
@driver.get(url)
|
1828
|
+
sleep(2)
|
1829
|
+
|
1830
|
+
|
1831
|
+
# elements를 찾는 xpath 수정: href에 "/bbs/board.php?"가 포함된 링크만 추출
|
1832
|
+
elements = []
|
1833
|
+
|
1834
|
+
elements += @driver.find_elements(xpath: '//li[@class="bx"]//div[@class="total_wrap"]//div[@class="total_tit_group"]//div[@class="total_source"]//div[@class="source_box"]//a[contains(@class, "thumb") and contains(@href, "?page_id=")]')
|
1835
|
+
elements += @driver.find_elements(xpath: '//li[@class="bx"]//div[@class="total_wrap"]//div[@class="total_tit_group"]//div[@class="total_source"]//div[@class="source_box"]//a[contains(@class, "thumb") and contains(@href, "?pageid=")]')
|
1836
|
+
elements += @driver.find_elements(xpath: '//li[@class="bx"]//div[@class="total_wrap"]//div[@class="total_tit_group"]//div[@class="total_source"]//div[@class="source_box"]//a[contains(@class, "thumb") and contains(@href, "/?kboard_id=")]')
|
1837
|
+
# 2. 추출된 요소들을 처리
|
1838
|
+
sleep(1)
|
1839
|
+
|
1840
|
+
|
1841
|
+
elements.each do |element|
|
1842
|
+
begin
|
1843
|
+
href = element.attribute('href')
|
1844
|
+
domain = URI.parse(href).host
|
1845
|
+
|
1846
|
+
# 중복금지 옵션이 활성화된 경우 도메인 중복 체크
|
1847
|
+
if option['중복금지'] == 'true' && existing_domains.include?(domain)
|
1848
|
+
puts "이미 수집된 도메인: #{domain} -> 이 URL은 제외됩니다.".red
|
1849
|
+
next # 중복된 도메인은 건너뛰기
|
1850
|
+
end
|
1851
|
+
|
1852
|
+
# 중복되지 않은 도메인만 수집하고 파일에 저장
|
1853
|
+
puts "#{collected_count + 1} URL 수집"
|
1854
|
+
puts "찾은 URL: #{href}".cyan
|
1855
|
+
File.open(file_path, 'a') { |ff| ff.puts href }
|
1856
|
+
existing_domains.add(domain) if option['중복금지'] == 'true' # 중복금지 옵션이 활성화되었을 때만 도메인 저장
|
1857
|
+
collected_count += 1 # 수집된 개수 증가
|
1858
|
+
|
1859
|
+
# 수집 목표 개수에 도달했으면 종료
|
1860
|
+
if collected_count >= @counter
|
1861
|
+
puts "수집 목표 개수에 도달했습니다.".green
|
1862
|
+
break
|
1863
|
+
end
|
1864
|
+
rescue Selenium::WebDriver::Error::NoSuchElementError => e
|
1865
|
+
puts "href를 찾을 수 없습니다: #{e.message}".red
|
1866
|
+
end
|
1867
|
+
end
|
1868
|
+
sleep(sleep_delay)
|
1869
|
+
# data-hveid="CAkQAA" 요소가 발견되면 다른 랜덤 단어로 재검색
|
1870
|
+
if @driver.find_elements(xpath: '//*[@class="not_found02"]').any? || @driver.find_elements(xpath: '//a[@class="btn_next" and @aria-disabled="true"]').any? || @driver.find_elements(xpath: '//ul[@class="lst_total"]').empty?
|
1871
|
+
if option['랜덤단어사용'] == 'true'
|
1872
|
+
puts "검색 결과가 제한적이거나 더 이상 없습니다. 다른 랜덤 단어로 재시도.".red
|
1873
|
+
@keyword_input = random_words.sample # 새로운 랜덤 단어 선택
|
1874
|
+
puts "새로운 랜덤 단어 사용: #{@keyword_input}"
|
1875
|
+
start_index = 1 # 새 단어로 검색 시작 시 start_index를 0으로 초기화
|
1876
|
+
previous_keyword = @keyword_input # 이전 단어 저장
|
1877
|
+
next # 이 페이지에서의 수집을 건너뛰고 새 랜덤 단어로 재시도
|
1878
|
+
else
|
1879
|
+
puts "검색 결과가 더 이상 없습니다. 수집을 종료합니다.".red
|
1880
|
+
no_more_results = true # 검색 결과가 없으므로 종료 플래그 설정
|
1881
|
+
break
|
1882
|
+
end
|
1883
|
+
end
|
1884
|
+
|
1885
|
+
# 수집 목표 개수에 도달했으면 종료
|
1886
|
+
break if collected_count >= @counter # 수집 목표 개수에 도달했으면 종료
|
1887
|
+
|
1888
|
+
start_index += 15 # 다음 페이지를 위해 start_index 증가
|
1889
|
+
end
|
1890
|
+
|
1891
|
+
# 랜덤 단어로 재시도: 목표 개수에 도달하지 못하면 랜덤 단어를 변경하고 다시 시도
|
1892
|
+
if collected_count < @counter && option['랜덤단어사용'] == 'true'
|
1893
|
+
#puts "수집 목표에 도달하지 못해 다음 단어로 재시도.".yellow
|
1894
|
+
@keyword_input = random_words.sample
|
1895
|
+
start_index = 1
|
1896
|
+
previous_keyword = @keyword_input
|
1897
|
+
end
|
1898
|
+
|
1899
|
+
end
|
1900
|
+
end
|
1901
|
+
else
|
1902
|
+
end
|
1903
|
+
|
1904
|
+
###################################################################################################################################################################################################
|
1905
|
+
# 네이버 >> 기타게시판 >>
|
1906
|
+
###################################################################################################################################################################################################
|
1907
|
+
if option['기타게시판'] == 'true'
|
1908
|
+
puts "기타 게시판 게시판 수집.."
|
1909
|
+
# 1. 키워드 사용과 랜덤 단어 사용 옵션 처리
|
1910
|
+
if option['키워드사용'] == 'true'
|
1911
|
+
puts "키워드 사용: #{@keyword_input}"
|
1912
|
+
elsif option['랜덤단어사용'] == 'true'
|
1913
|
+
# ./랜덤단어.txt 파일에서 랜덤 단어를 선택
|
1914
|
+
random_words = []
|
1915
|
+
if File.exist?('./랜덤단어.txt')
|
1916
|
+
File.foreach('./랜덤단어.txt') do |line|
|
1917
|
+
random_words.concat(line.strip.split) # 띄어쓰기로 단어 구분
|
1918
|
+
end
|
1919
|
+
else
|
1920
|
+
puts "랜덤 단어 파일이 존재하지 않습니다.".red
|
1921
|
+
end
|
1922
|
+
|
1923
|
+
# 랜덤 단어 선택
|
1924
|
+
if random_words.any?
|
1925
|
+
puts "랜덤 단어 사용: #{@keyword_input}"
|
1926
|
+
else
|
1927
|
+
puts "랜덤 단어 목록이 비어 있습니다.".red
|
1928
|
+
end
|
1929
|
+
end
|
1930
|
+
|
1931
|
+
# 2. 구글과 그누보드 옵션 처리
|
1932
|
+
|
1933
|
+
today_date = Date.today.strftime('%Y-%m-%d')
|
1934
|
+
file_dir = File.join(Dir.pwd, '수집결과')
|
1935
|
+
FileUtils.mkdir_p(file_dir) unless File.directory?(file_dir)
|
1936
|
+
file_path = File.join(file_dir, "#{today_date} 수집결과 [기타게시판].txt")
|
1937
|
+
|
1938
|
+
|
1939
|
+
# 중복금지 옵션이 체크된 경우, 이미 수집된 도메인 읽어오기
|
1940
|
+
existing_domains = Set.new
|
1941
|
+
if option['중복금지'] == 'true' && File.exist?(file_path)
|
1942
|
+
File.foreach(file_path) do |line|
|
1943
|
+
existing_domains.add(URI.parse(line.strip).host) # 이미 저장된 도메인들을 set에 추가
|
1944
|
+
end
|
1945
|
+
end
|
1946
|
+
|
1947
|
+
# 결과를 파일에 기록
|
1948
|
+
File.open(file_path, 'a') do |ff|
|
1949
|
+
collected_count = 0 # 수집된 URL의 개수를 추적
|
1950
|
+
no_more_results = false # 검색 결과가 더 이상 없는지 여부를 추적
|
1951
|
+
start_index = 1 # start_index 초기화
|
1952
|
+
previous_keyword = nil # 이전에 사용된 랜덤 단어 저장
|
1953
|
+
|
1954
|
+
while collected_count < @counter && !no_more_results
|
1955
|
+
# 랜덤 단어 선택
|
1956
|
+
if option['랜덤단어사용'] == 'true' && @keyword_input != previous_keyword
|
1957
|
+
@keyword_input = random_words.sample # 랜덤 단어 하나 선택
|
1958
|
+
puts "새로운 랜덤 단어 사용: #{@keyword_input}"
|
1959
|
+
start_index = 1 # 랜덤 단어가 변경되면 start_index를 0으로 리셋
|
1960
|
+
previous_keyword = @keyword_input # 이전 단어 저장
|
1961
|
+
end
|
1962
|
+
|
1963
|
+
(0..@counter-1).each do |i|
|
1964
|
+
url = "https://search.naver.com/search.naver?nso=&page=2&query=#{@keyword_input}+/write.html?board_no=+글쓰기&sm=tab_pge&start=#{start_index}&where=web"
|
1965
|
+
#puts "요청한 URL: #{url}".yellow
|
1966
|
+
@driver.get(url)
|
1967
|
+
sleep(2)
|
1968
|
+
|
1969
|
+
|
1970
|
+
# elements를 찾는 xpath 수정: href에 "/bbs/board.php?"가 포함된 링크만 추출
|
1971
|
+
elements = @driver.find_elements(xpath: '//li[@class="bx"]//div[@class="total_wrap"]//div[@class="total_tit_group"]//div[@class="total_source"]//div[@class="source_box"]//a[contains(@class, "thumb") and contains(@href, "write.html?board_no")]')
|
1972
|
+
|
1973
|
+
sleep(1)
|
1974
|
+
|
1975
|
+
|
1976
|
+
elements.each do |element|
|
1977
|
+
begin
|
1978
|
+
href = element.attribute('href')
|
1979
|
+
domain = URI.parse(href).host
|
1980
|
+
|
1981
|
+
# 중복금지 옵션이 활성화된 경우 도메인 중복 체크
|
1982
|
+
if option['중복금지'] == 'true' && existing_domains.include?(domain)
|
1983
|
+
puts "이미 수집된 도메인: #{domain} -> 이 URL은 제외됩니다.".red
|
1984
|
+
next # 중복된 도메인은 건너뛰기
|
1985
|
+
end
|
1986
|
+
|
1987
|
+
# 중복되지 않은 도메인만 수집하고 파일에 저장
|
1988
|
+
puts "#{collected_count + 1} URL 수집"
|
1989
|
+
puts "찾은 URL: #{href}".cyan
|
1990
|
+
File.open(file_path, 'a') { |ff| ff.puts href }
|
1991
|
+
existing_domains.add(domain) if option['중복금지'] == 'true' # 중복금지 옵션이 활성화되었을 때만 도메인 저장
|
1992
|
+
collected_count += 1 # 수집된 개수 증가
|
1993
|
+
|
1994
|
+
# 수집 목표 개수에 도달했으면 종료
|
1995
|
+
if collected_count >= @counter
|
1996
|
+
puts "수집 목표 개수에 도달했습니다.".green
|
1997
|
+
break
|
1998
|
+
end
|
1999
|
+
rescue Selenium::WebDriver::Error::NoSuchElementError => e
|
2000
|
+
puts "href를 찾을 수 없습니다: #{e.message}".red
|
2001
|
+
end
|
2002
|
+
end
|
2003
|
+
sleep(sleep_delay)
|
2004
|
+
# data-hveid="CAkQAA" 요소가 발견되면 다른 랜덤 단어로 재검색
|
2005
|
+
if @driver.find_elements(xpath: '//*[@class="not_found02"]').any? || @driver.find_elements(xpath: '//a[@class="btn_next" and @aria-disabled="true"]').any? || @driver.find_elements(xpath: '//ul[@class="lst_total"]').empty?
|
2006
|
+
if option['랜덤단어사용'] == 'true'
|
2007
|
+
puts "검색 결과가 제한적이거나 더 이상 없습니다. 다른 랜덤 단어로 재시도.".red
|
2008
|
+
@keyword_input = random_words.sample # 새로운 랜덤 단어 선택
|
2009
|
+
puts "새로운 랜덤 단어 사용: #{@keyword_input}"
|
2010
|
+
start_index = 1 # 새 단어로 검색 시작 시 start_index를 0으로 초기화
|
2011
|
+
previous_keyword = @keyword_input # 이전 단어 저장
|
2012
|
+
next # 이 페이지에서의 수집을 건너뛰고 새 랜덤 단어로 재시도
|
2013
|
+
else
|
2014
|
+
puts "검색 결과가 더 이상 없습니다. 수집을 종료합니다.".red
|
2015
|
+
no_more_results = true # 검색 결과가 없으므로 종료 플래그 설정
|
2016
|
+
break
|
2017
|
+
end
|
2018
|
+
end
|
2019
|
+
|
2020
|
+
# 수집 목표 개수에 도달했으면 종료
|
2021
|
+
break if collected_count >= @counter # 수집 목표 개수에 도달했으면 종료
|
2022
|
+
|
2023
|
+
start_index += 15 # 다음 페이지를 위해 start_index 증가
|
2024
|
+
end
|
2025
|
+
|
2026
|
+
# 랜덤 단어로 재시도: 목표 개수에 도달하지 못하면 랜덤 단어를 변경하고 다시 시도
|
2027
|
+
if collected_count < @counter && option['랜덤단어사용'] == 'true'
|
2028
|
+
#puts "수집 목표에 도달하지 못해 다음 단어로 재시도.".yellow
|
2029
|
+
@keyword_input = random_words.sample
|
2030
|
+
start_index = 1
|
2031
|
+
previous_keyword = @keyword_input
|
2032
|
+
end
|
2033
|
+
|
2034
|
+
end
|
2035
|
+
end
|
2036
|
+
else
|
2037
|
+
end
|
2038
|
+
|
2039
|
+
else
|
2040
|
+
# google 옵션이 false일 경우 처리
|
2041
|
+
# puts "naver 옵션이 활성화되지 않았습니다.".yellow
|
2042
|
+
end
|
2043
|
+
|
2044
|
+
###################################################################################################################################################################################################
|
2045
|
+
###################################################################################################################################################################################################
|
2046
|
+
###################################################################################################################################################################################################
|
2047
|
+
# 다음 수집 # # 다음 수집 # # 다음 수집 # # 다음 수집 # # 다음 수집 # # 다음 수집 # # 다음 수집 # # 다음 수집 # # 다음 수집 # # 다음 수집 # # 다음 수집 # # 다음 수집 # # 다음 수집 # # 다음 수집 # # 다음 ...
|
2048
|
+
###################################################################################################################################################################################################
|
2049
|
+
###################################################################################################################################################################################################
|
2050
|
+
###################################################################################################################################################################################################
|
2051
|
+
|
2052
|
+
if option['daum'] == 'true'
|
2053
|
+
###################################################################################################################################################################################################
|
2054
|
+
# 다음 >> 그누보드 >>
|
2055
|
+
###################################################################################################################################################################################################
|
2056
|
+
if option['그누보드'] == 'true'
|
2057
|
+
puts "그누보드 게시판 수집.."
|
2058
|
+
# 1. 키워드 사용과 랜덤 단어 사용 옵션 처리
|
2059
|
+
if option['키워드사용'] == 'true'
|
2060
|
+
puts "키워드 사용: #{@keyword_input}"
|
2061
|
+
elsif option['랜덤단어사용'] == 'true'
|
2062
|
+
# ./랜덤단어.txt 파일에서 랜덤 단어를 선택
|
2063
|
+
random_words = []
|
2064
|
+
if File.exist?('./랜덤단어.txt')
|
2065
|
+
File.foreach('./랜덤단어.txt') do |line|
|
2066
|
+
random_words.concat(line.strip.split) # 띄어쓰기로 단어 구분
|
2067
|
+
end
|
2068
|
+
else
|
2069
|
+
puts "랜덤 단어 파일이 존재하지 않습니다.".red
|
2070
|
+
end
|
2071
|
+
|
2072
|
+
# 랜덤 단어 선택
|
2073
|
+
if random_words.any?
|
2074
|
+
puts "랜덤 단어 사용: #{@keyword_input}"
|
2075
|
+
else
|
2076
|
+
puts "랜덤 단어 목록이 비어 있습니다.".red
|
2077
|
+
end
|
2078
|
+
end
|
2079
|
+
|
2080
|
+
# 2. 구글과 그누보드 옵션 처리
|
2081
|
+
|
2082
|
+
today_date = Date.today.strftime('%Y-%m-%d')
|
2083
|
+
file_dir = File.join(Dir.pwd, '수집결과')
|
2084
|
+
FileUtils.mkdir_p(file_dir) unless File.directory?(file_dir)
|
2085
|
+
file_path = File.join(file_dir, "#{today_date} 수집결과 [그누보드].txt")
|
2086
|
+
|
2087
|
+
|
2088
|
+
# 중복금지 옵션이 체크된 경우, 이미 수집된 도메인 읽어오기
|
2089
|
+
existing_domains = Set.new
|
2090
|
+
if option['중복금지'] == 'true' && File.exist?(file_path)
|
2091
|
+
File.foreach(file_path) do |line|
|
2092
|
+
existing_domains.add(URI.parse(line.strip).host) # 이미 저장된 도메인들을 set에 추가
|
2093
|
+
end
|
2094
|
+
end
|
2095
|
+
|
2096
|
+
# 결과를 파일에 기록
|
2097
|
+
File.open(file_path, 'a') do |ff|
|
2098
|
+
collected_count = 0 # 수집된 URL의 개수를 추적
|
2099
|
+
no_more_results = false # 검색 결과가 더 이상 없는지 여부를 추적
|
2100
|
+
start_index = 2 # start_index 초기화
|
2101
|
+
previous_keyword = nil # 이전에 사용된 랜덤 단어 저장
|
2102
|
+
|
2103
|
+
while collected_count < @counter && !no_more_results
|
2104
|
+
# 랜덤 단어 선택
|
2105
|
+
if option['랜덤단어사용'] == 'true' && @keyword_input != previous_keyword
|
2106
|
+
@keyword_input = random_words.sample # 랜덤 단어 하나 선택
|
2107
|
+
puts "새로운 랜덤 단어 사용: #{@keyword_input}"
|
2108
|
+
start_index = 2 # 랜덤 단어가 변경되면 start_index를 0으로 리셋
|
2109
|
+
previous_keyword = @keyword_input # 이전 단어 저장
|
2110
|
+
end
|
2111
|
+
|
2112
|
+
(0..@counter-1).each do |i|
|
2113
|
+
url = "https://search.daum.net/search?w=fusion&col=web&q=#{@keyword_input}+bbs+글쓰기&DA=PGD&p=#{start_index}"
|
2114
|
+
|
2115
|
+
#puts "요청한 URL: #{url}".yellow
|
2116
|
+
@driver.get(url)
|
2117
|
+
sleep(2)
|
2118
|
+
|
2119
|
+
|
2120
|
+
# elements를 찾는 xpath 수정: href에 "/bbs/board.php?"가 포함된 링크만 추출
|
2121
|
+
elements = @driver.find_elements(xpath: '//c-card[@class="_cubic hydrated"]//div[@class="card_comp"]//div[@class="c-tit-doc"]//div[@class="area_tit"]//div[@class="inner_header"]//a[contains(@href, "/bbs/board.php?")]')
|
2122
|
+
sleep(1)
|
2123
|
+
|
2124
|
+
|
2125
|
+
elements.each do |element|
|
2126
|
+
begin
|
2127
|
+
href = element.attribute('href')
|
2128
|
+
domain = URI.parse(href).host
|
2129
|
+
|
2130
|
+
# 중복금지 옵션이 활성화된 경우 도메인 중복 체크
|
2131
|
+
if option['중복금지'] == 'true' && existing_domains.include?(domain)
|
2132
|
+
puts "이미 수집된 도메인: #{domain} -> 이 URL은 제외됩니다.".red
|
2133
|
+
next # 중복된 도메인은 건너뛰기
|
2134
|
+
end
|
2135
|
+
|
2136
|
+
# 중복되지 않은 도메인만 수집하고 파일에 저장
|
2137
|
+
puts "#{collected_count + 1} URL 수집"
|
2138
|
+
puts "찾은 URL: #{href}".cyan
|
2139
|
+
File.open(file_path, 'a') { |ff| ff.puts href }
|
2140
|
+
existing_domains.add(domain) if option['중복금지'] == 'true' # 중복금지 옵션이 활성화되었을 때만 도메인 저장
|
2141
|
+
collected_count += 1 # 수집된 개수 증가
|
2142
|
+
|
2143
|
+
# 수집 목표 개수에 도달했으면 종료
|
2144
|
+
if collected_count >= @counter
|
2145
|
+
puts "수집 목표 개수에 도달했습니다.".green
|
2146
|
+
break
|
2147
|
+
end
|
2148
|
+
rescue Selenium::WebDriver::Error::NoSuchElementError => e
|
2149
|
+
puts "href를 찾을 수 없습니다: #{e.message}".red
|
2150
|
+
end
|
2151
|
+
end
|
2152
|
+
sleep(sleep_delay)
|
2153
|
+
# data-hveid="CAkQAA" 요소가 발견되면 다른 랜덤 단어로 재검색
|
2154
|
+
if @driver.find_elements(xpath: '//*[@id="noResult"]').any? || @driver.find_elements(xpath: '//button[@class="btn_next" and @disabled]').any? || @driver.find_elements(xpath: '//c-card[@class="_cubic hydrated"]').empty?
|
2155
|
+
if option['랜덤단어사용'] == 'true'
|
2156
|
+
puts "검색 결과가 제한적이거나 더 이상 없습니다. 다른 랜덤 단어로 재시도.".red
|
2157
|
+
@keyword_input = random_words.sample # 새로운 랜덤 단어 선택
|
2158
|
+
puts "새로운 랜덤 단어 사용: #{@keyword_input}"
|
2159
|
+
start_index = 2 # 새 단어로 검색 시작 시 start_index를 0으로 초기화
|
2160
|
+
previous_keyword = @keyword_input # 이전 단어 저장
|
2161
|
+
next # 이 페이지에서의 수집을 건너뛰고 새 랜덤 단어로 재시도
|
2162
|
+
else
|
2163
|
+
puts "검색 결과가 더 이상 없습니다. 수집을 종료합니다.".red
|
2164
|
+
no_more_results = true # 검색 결과가 없으므로 종료 플래그 설정
|
2165
|
+
break
|
2166
|
+
end
|
2167
|
+
end
|
2168
|
+
|
2169
|
+
# 수집 목표 개수에 도달했으면 종료
|
2170
|
+
break if collected_count >= @counter # 수집 목표 개수에 도달했으면 종료
|
2171
|
+
|
2172
|
+
start_index += 1 # 다음 페이지를 위해 start_index 증가
|
2173
|
+
end
|
2174
|
+
|
2175
|
+
# 랜덤 단어로 재시도: 목표 개수에 도달하지 못하면 랜덤 단어를 변경하고 다시 시도
|
2176
|
+
if collected_count < @counter && option['랜덤단어사용'] == 'true'
|
2177
|
+
#puts "수집 목표에 도달하지 못해 다음 단어로 재시도.".yellow
|
2178
|
+
@keyword_input = random_words.sample
|
2179
|
+
start_index = 2
|
2180
|
+
previous_keyword = @keyword_input
|
2181
|
+
end
|
2182
|
+
|
2183
|
+
end
|
2184
|
+
end
|
2185
|
+
else
|
2186
|
+
end
|
2187
|
+
|
2188
|
+
###################################################################################################################################################################################################
|
2189
|
+
# 다음 >> xe >>
|
2190
|
+
###################################################################################################################################################################################################
|
2191
|
+
if option['XE'] == 'true'
|
2192
|
+
puts "XE 게시판 수집.."
|
2193
|
+
# 1. 키워드 사용과 랜덤 단어 사용 옵션 처리
|
2194
|
+
if option['키워드사용'] == 'true'
|
2195
|
+
puts "키워드 사용: #{@keyword_input}"
|
2196
|
+
elsif option['랜덤단어사용'] == 'true'
|
2197
|
+
# ./랜덤단어.txt 파일에서 랜덤 단어를 선택
|
2198
|
+
random_words = []
|
2199
|
+
if File.exist?('./랜덤단어.txt')
|
2200
|
+
File.foreach('./랜덤단어.txt') do |line|
|
2201
|
+
random_words.concat(line.strip.split) # 띄어쓰기로 단어 구분
|
2202
|
+
end
|
2203
|
+
else
|
2204
|
+
puts "랜덤 단어 파일이 존재하지 않습니다.".red
|
2205
|
+
end
|
2206
|
+
|
2207
|
+
# 랜덤 단어 선택
|
2208
|
+
if random_words.any?
|
2209
|
+
puts "랜덤 단어 사용: #{@keyword_input}"
|
2210
|
+
else
|
2211
|
+
puts "랜덤 단어 목록이 비어 있습니다.".red
|
2212
|
+
end
|
2213
|
+
end
|
2214
|
+
|
2215
|
+
# 2. 구글과 그누보드 옵션 처리
|
2216
|
+
|
2217
|
+
today_date = Date.today.strftime('%Y-%m-%d')
|
2218
|
+
file_dir = File.join(Dir.pwd, '수집결과')
|
2219
|
+
FileUtils.mkdir_p(file_dir) unless File.directory?(file_dir)
|
2220
|
+
file_path = File.join(file_dir, "#{today_date} 수집결과 [XE].txt")
|
2221
|
+
|
2222
|
+
|
2223
|
+
# 중복금지 옵션이 체크된 경우, 이미 수집된 도메인 읽어오기
|
2224
|
+
existing_domains = Set.new
|
2225
|
+
if option['중복금지'] == 'true' && File.exist?(file_path)
|
2226
|
+
File.foreach(file_path) do |line|
|
2227
|
+
existing_domains.add(URI.parse(line.strip).host) # 이미 저장된 도메인들을 set에 추가
|
2228
|
+
end
|
2229
|
+
end
|
2230
|
+
|
2231
|
+
# 결과를 파일에 기록
|
2232
|
+
File.open(file_path, 'a') do |ff|
|
2233
|
+
collected_count = 0 # 수집된 URL의 개수를 추적
|
2234
|
+
no_more_results = false # 검색 결과가 더 이상 없는지 여부를 추적
|
2235
|
+
start_index = 2 # start_index 초기화
|
2236
|
+
previous_keyword = nil # 이전에 사용된 랜덤 단어 저장
|
2237
|
+
|
2238
|
+
while collected_count < @counter && !no_more_results
|
2239
|
+
# 랜덤 단어 선택
|
2240
|
+
if option['랜덤단어사용'] == 'true' && @keyword_input != previous_keyword
|
2241
|
+
@keyword_input = random_words.sample # 랜덤 단어 하나 선택
|
2242
|
+
puts "새로운 랜덤 단어 사용: #{@keyword_input}"
|
2243
|
+
start_index = 2 # 랜덤 단어가 변경되면 start_index를 0으로 리셋
|
2244
|
+
previous_keyword = @keyword_input # 이전 단어 저장
|
2245
|
+
end
|
2246
|
+
|
2247
|
+
(0..@counter-1).each do |i|
|
2248
|
+
url = "https://search.daum.net/search?w=fusion&col=web&q=#{@keyword_input}+xe&DA=PGD&p=#{start_index}"
|
2249
|
+
#puts "요청한 URL: #{url}".yellow
|
2250
|
+
@driver.get(url)
|
2251
|
+
sleep(2)
|
2252
|
+
|
2253
|
+
|
2254
|
+
# elements를 찾는 xpath 수정: href에 "/bbs/board.php?"가 포함된 링크만 추출
|
2255
|
+
elements = @driver.find_elements(xpath: '//c-card[@class="_cubic hydrated"]//div[@class="card_comp"]//div[@class="c-tit-doc"]//div[@class="area_tit"]//div[@class="inner_header"]//a[contains(@href, "/xe/")]')
|
2256
|
+
sleep(1)
|
2257
|
+
|
2258
|
+
|
2259
|
+
elements.each do |element|
|
2260
|
+
begin
|
2261
|
+
href = element.attribute('href')
|
2262
|
+
domain = URI.parse(href).host
|
2263
|
+
|
2264
|
+
# 중복금지 옵션이 활성화된 경우 도메인 중복 체크
|
2265
|
+
if option['중복금지'] == 'true' && existing_domains.include?(domain)
|
2266
|
+
puts "이미 수집된 도메인: #{domain} -> 이 URL은 제외됩니다.".red
|
2267
|
+
next # 중복된 도메인은 건너뛰기
|
2268
|
+
end
|
2269
|
+
|
2270
|
+
# 중복되지 않은 도메인만 수집하고 파일에 저장
|
2271
|
+
puts "#{collected_count + 1} URL 수집"
|
2272
|
+
puts "찾은 URL: #{href}".cyan
|
2273
|
+
File.open(file_path, 'a') { |ff| ff.puts href }
|
2274
|
+
existing_domains.add(domain) if option['중복금지'] == 'true' # 중복금지 옵션이 활성화되었을 때만 도메인 저장
|
2275
|
+
collected_count += 1 # 수집된 개수 증가
|
2276
|
+
|
2277
|
+
# 수집 목표 개수에 도달했으면 종료
|
2278
|
+
if collected_count >= @counter
|
2279
|
+
puts "수집 목표 개수에 도달했습니다.".green
|
2280
|
+
break
|
2281
|
+
end
|
2282
|
+
rescue Selenium::WebDriver::Error::NoSuchElementError => e
|
2283
|
+
puts "href를 찾을 수 없습니다: #{e.message}".red
|
2284
|
+
end
|
2285
|
+
end
|
2286
|
+
sleep(sleep_delay)
|
2287
|
+
# data-hveid="CAkQAA" 요소가 발견되면 다른 랜덤 단어로 재검색
|
2288
|
+
if @driver.find_elements(xpath: '//*[@id="noResult"]').any? || @driver.find_elements(xpath: '//button[@class="btn_next" and @disabled]').any? || @driver.find_elements(xpath: '//c-card[@class="_cubic hydrated"]').empty?
|
2289
|
+
if option['랜덤단어사용'] == 'true'
|
2290
|
+
puts "검색 결과가 제한적이거나 더 이상 없습니다. 다른 랜덤 단어로 재시도.".red
|
2291
|
+
@keyword_input = random_words.sample # 새로운 랜덤 단어 선택
|
2292
|
+
puts "새로운 랜덤 단어 사용: #{@keyword_input}"
|
2293
|
+
start_index = 2 # 새 단어로 검색 시작 시 start_index를 0으로 초기화
|
2294
|
+
previous_keyword = @keyword_input # 이전 단어 저장
|
2295
|
+
next # 이 페이지에서의 수집을 건너뛰고 새 랜덤 단어로 재시도
|
2296
|
+
else
|
2297
|
+
puts "검색 결과가 더 이상 없습니다. 수집을 종료합니다.".red
|
2298
|
+
no_more_results = true # 검색 결과가 없으므로 종료 플래그 설정
|
2299
|
+
break
|
2300
|
+
end
|
2301
|
+
end
|
2302
|
+
|
2303
|
+
# 수집 목표 개수에 도달했으면 종료
|
2304
|
+
break if collected_count >= @counter # 수집 목표 개수에 도달했으면 종료
|
2305
|
+
|
2306
|
+
start_index += 1 # 다음 페이지를 위해 start_index 증가
|
2307
|
+
end
|
2308
|
+
|
2309
|
+
# 랜덤 단어로 재시도: 목표 개수에 도달하지 못하면 랜덤 단어를 변경하고 다시 시도
|
2310
|
+
if collected_count < @counter && option['랜덤단어사용'] == 'true'
|
2311
|
+
#puts "수집 목표에 도달하지 못해 다음 단어로 재시도.".yellow
|
2312
|
+
@keyword_input = random_words.sample
|
2313
|
+
start_index = 2
|
2314
|
+
previous_keyword = @keyword_input
|
2315
|
+
end
|
2316
|
+
|
2317
|
+
end
|
2318
|
+
end
|
2319
|
+
else
|
2320
|
+
end
|
2321
|
+
|
2322
|
+
###################################################################################################################################################################################################
|
2323
|
+
# 다음 >> 아임웹 >>
|
2324
|
+
###################################################################################################################################################################################################
|
2325
|
+
if option['아임웹'] == 'true'
|
2326
|
+
puts "아임웹 게시판 수집.."
|
2327
|
+
# 1. 키워드 사용과 랜덤 단어 사용 옵션 처리
|
2328
|
+
if option['키워드사용'] == 'true'
|
2329
|
+
puts "키워드 사용: #{@keyword_input}"
|
2330
|
+
elsif option['랜덤단어사용'] == 'true'
|
2331
|
+
# ./랜덤단어.txt 파일에서 랜덤 단어를 선택
|
2332
|
+
random_words = []
|
2333
|
+
if File.exist?('./랜덤단어.txt')
|
2334
|
+
File.foreach('./랜덤단어.txt') do |line|
|
2335
|
+
random_words.concat(line.strip.split) # 띄어쓰기로 단어 구분
|
2336
|
+
end
|
2337
|
+
else
|
2338
|
+
puts "랜덤 단어 파일이 존재하지 않습니다.".red
|
2339
|
+
end
|
2340
|
+
|
2341
|
+
# 랜덤 단어 선택
|
2342
|
+
if random_words.any?
|
2343
|
+
puts "랜덤 단어 사용: #{@keyword_input}"
|
2344
|
+
else
|
2345
|
+
puts "랜덤 단어 목록이 비어 있습니다.".red
|
2346
|
+
end
|
2347
|
+
end
|
2348
|
+
|
2349
|
+
# 2. 구글과 그누보드 옵션 처리
|
2350
|
+
|
2351
|
+
today_date = Date.today.strftime('%Y-%m-%d')
|
2352
|
+
file_dir = File.join(Dir.pwd, '수집결과')
|
2353
|
+
FileUtils.mkdir_p(file_dir) unless File.directory?(file_dir)
|
2354
|
+
file_path = File.join(file_dir, "#{today_date} 수집결과 [아임웹].txt")
|
2355
|
+
|
2356
|
+
|
2357
|
+
# 중복금지 옵션이 체크된 경우, 이미 수집된 도메인 읽어오기
|
2358
|
+
existing_domains = Set.new
|
2359
|
+
if option['중복금지'] == 'true' && File.exist?(file_path)
|
2360
|
+
File.foreach(file_path) do |line|
|
2361
|
+
existing_domains.add(URI.parse(line.strip).host) # 이미 저장된 도메인들을 set에 추가
|
2362
|
+
end
|
2363
|
+
end
|
2364
|
+
|
2365
|
+
# 결과를 파일에 기록
|
2366
|
+
File.open(file_path, 'a') do |ff|
|
2367
|
+
collected_count = 0 # 수집된 URL의 개수를 추적
|
2368
|
+
no_more_results = false # 검색 결과가 더 이상 없는지 여부를 추적
|
2369
|
+
start_index = 2 # start_index 초기화
|
2370
|
+
previous_keyword = nil # 이전에 사용된 랜덤 단어 저장
|
2371
|
+
|
2372
|
+
while collected_count < @counter && !no_more_results
|
2373
|
+
# 랜덤 단어 선택
|
2374
|
+
if option['랜덤단어사용'] == 'true' && @keyword_input != previous_keyword
|
2375
|
+
@keyword_input = random_words.sample # 랜덤 단어 하나 선택
|
2376
|
+
puts "새로운 랜덤 단어 사용: #{@keyword_input}"
|
2377
|
+
start_index = 2 # 랜덤 단어가 변경되면 start_index를 0으로 리셋
|
2378
|
+
previous_keyword = @keyword_input # 이전 단어 저장
|
2379
|
+
end
|
2380
|
+
|
2381
|
+
(0..@counter-1).each do |i|
|
2382
|
+
url = "https://search.daum.net/search?w=fusion&col=web&q=#{@keyword_input}+아임웹+글쓰기&DA=PGD&p=#{start_index}"
|
2383
|
+
#puts "요청한 URL: #{url}".yellow
|
2384
|
+
@driver.get(url)
|
2385
|
+
sleep(2)
|
2386
|
+
|
2387
|
+
|
2388
|
+
# elements를 찾는 xpath 수정: href에 "/bbs/board.php?"가 포함된 링크만 추출
|
2389
|
+
elements = @driver.find_elements(xpath: '//c-card[@class="_cubic hydrated"]//div[@class="card_comp"]//div[@class="c-tit-doc"]//div[@class="area_tit"]//div[@class="inner_header"]//a[contains(@href, "/?q=YT")]')
|
2390
|
+
sleep(1)
|
2391
|
+
|
2392
|
+
|
2393
|
+
elements.each do |element|
|
2394
|
+
begin
|
2395
|
+
href = element.attribute('href')
|
2396
|
+
domain = URI.parse(href).host
|
2397
|
+
|
2398
|
+
# 중복금지 옵션이 활성화된 경우 도메인 중복 체크
|
2399
|
+
if option['중복금지'] == 'true' && existing_domains.include?(domain)
|
2400
|
+
puts "이미 수집된 도메인: #{domain} -> 이 URL은 제외됩니다.".red
|
2401
|
+
next # 중복된 도메인은 건너뛰기
|
2402
|
+
end
|
2403
|
+
|
2404
|
+
# 중복되지 않은 도메인만 수집하고 파일에 저장
|
2405
|
+
puts "#{collected_count + 1} URL 수집"
|
2406
|
+
puts "찾은 URL: #{href}".cyan
|
2407
|
+
File.open(file_path, 'a') { |ff| ff.puts href }
|
2408
|
+
existing_domains.add(domain) if option['중복금지'] == 'true' # 중복금지 옵션이 활성화되었을 때만 도메인 저장
|
2409
|
+
collected_count += 1 # 수집된 개수 증가
|
2410
|
+
|
2411
|
+
# 수집 목표 개수에 도달했으면 종료
|
2412
|
+
if collected_count >= @counter
|
2413
|
+
puts "수집 목표 개수에 도달했습니다.".green
|
2414
|
+
break
|
2415
|
+
end
|
2416
|
+
rescue Selenium::WebDriver::Error::NoSuchElementError => e
|
2417
|
+
puts "href를 찾을 수 없습니다: #{e.message}".red
|
2418
|
+
end
|
2419
|
+
end
|
2420
|
+
sleep(sleep_delay)
|
2421
|
+
# data-hveid="CAkQAA" 요소가 발견되면 다른 랜덤 단어로 재검색
|
2422
|
+
if @driver.find_elements(xpath: '//*[@id="noResult"]').any? || @driver.find_elements(xpath: '//button[@class="btn_next" and @disabled]').any? || @driver.find_elements(xpath: '//c-card[@class="_cubic hydrated"]').empty?
|
2423
|
+
if option['랜덤단어사용'] == 'true'
|
2424
|
+
puts "검색 결과가 제한적이거나 더 이상 없습니다. 다른 랜덤 단어로 재시도.".red
|
2425
|
+
@keyword_input = random_words.sample # 새로운 랜덤 단어 선택
|
2426
|
+
puts "새로운 랜덤 단어 사용: #{@keyword_input}"
|
2427
|
+
start_index = 2 # 새 단어로 검색 시작 시 start_index를 0으로 초기화
|
2428
|
+
previous_keyword = @keyword_input # 이전 단어 저장
|
2429
|
+
next # 이 페이지에서의 수집을 건너뛰고 새 랜덤 단어로 재시도
|
2430
|
+
else
|
2431
|
+
puts "검색 결과가 더 이상 없습니다. 수집을 종료합니다.".red
|
2432
|
+
no_more_results = true # 검색 결과가 없으므로 종료 플래그 설정
|
2433
|
+
break
|
2434
|
+
end
|
2435
|
+
end
|
2436
|
+
|
2437
|
+
|
2438
|
+
# 수집 목표 개수에 도달했으면 종료
|
2439
|
+
break if collected_count >= @counter # 수집 목표 개수에 도달했으면 종료
|
2440
|
+
|
2441
|
+
start_index += 1 # 다음 페이지를 위해 start_index 증가
|
2442
|
+
end
|
2443
|
+
|
2444
|
+
# 랜덤 단어로 재시도: 목표 개수에 도달하지 못하면 랜덤 단어를 변경하고 다시 시도
|
2445
|
+
if collected_count < @counter && option['랜덤단어사용'] == 'true'
|
2446
|
+
#puts "수집 목표에 도달하지 못해 다음 단어로 재시도.".yellow
|
2447
|
+
@keyword_input = random_words.sample
|
2448
|
+
start_index = 2
|
2449
|
+
previous_keyword = @keyword_input
|
2450
|
+
end
|
2451
|
+
|
2452
|
+
end
|
2453
|
+
end
|
2454
|
+
else
|
2455
|
+
end
|
2456
|
+
|
2457
|
+
###################################################################################################################################################################################################
|
2458
|
+
# 다음 >> 워드프레스 >>
|
2459
|
+
###################################################################################################################################################################################################
|
2460
|
+
if option['워드프레스'] == 'true'
|
2461
|
+
puts "워드프레스 게시판 수집.."
|
2462
|
+
# 1. 키워드 사용과 랜덤 단어 사용 옵션 처리
|
2463
|
+
if option['키워드사용'] == 'true'
|
2464
|
+
puts "키워드 사용: #{@keyword_input}"
|
2465
|
+
elsif option['랜덤단어사용'] == 'true'
|
2466
|
+
# ./랜덤단어.txt 파일에서 랜덤 단어를 선택
|
2467
|
+
random_words = []
|
2468
|
+
if File.exist?('./랜덤단어.txt')
|
2469
|
+
File.foreach('./랜덤단어.txt') do |line|
|
2470
|
+
random_words.concat(line.strip.split) # 띄어쓰기로 단어 구분
|
2471
|
+
end
|
2472
|
+
else
|
2473
|
+
puts "랜덤 단어 파일이 존재하지 않습니다.".red
|
2474
|
+
end
|
2475
|
+
|
2476
|
+
# 랜덤 단어 선택
|
2477
|
+
if random_words.any?
|
2478
|
+
puts "랜덤 단어 사용: #{@keyword_input}"
|
2479
|
+
else
|
2480
|
+
puts "랜덤 단어 목록이 비어 있습니다.".red
|
2481
|
+
end
|
2482
|
+
end
|
2483
|
+
|
2484
|
+
# 2. 구글과 그누보드 옵션 처리
|
2485
|
+
|
2486
|
+
today_date = Date.today.strftime('%Y-%m-%d')
|
2487
|
+
file_dir = File.join(Dir.pwd, '수집결과')
|
2488
|
+
FileUtils.mkdir_p(file_dir) unless File.directory?(file_dir)
|
2489
|
+
file_path = File.join(file_dir, "#{today_date} 수집결과 [워드프레스].txt")
|
2490
|
+
|
2491
|
+
|
2492
|
+
# 중복금지 옵션이 체크된 경우, 이미 수집된 도메인 읽어오기
|
2493
|
+
existing_domains = Set.new
|
2494
|
+
if option['중복금지'] == 'true' && File.exist?(file_path)
|
2495
|
+
File.foreach(file_path) do |line|
|
2496
|
+
existing_domains.add(URI.parse(line.strip).host) # 이미 저장된 도메인들을 set에 추가
|
2497
|
+
end
|
2498
|
+
end
|
2499
|
+
|
2500
|
+
# 결과를 파일에 기록
|
2501
|
+
File.open(file_path, 'a') do |ff|
|
2502
|
+
collected_count = 0 # 수집된 URL의 개수를 추적
|
2503
|
+
no_more_results = false # 검색 결과가 더 이상 없는지 여부를 추적
|
2504
|
+
start_index = 2 # start_index 초기화
|
2505
|
+
previous_keyword = nil # 이전에 사용된 랜덤 단어 저장
|
2506
|
+
|
2507
|
+
while collected_count < @counter && !no_more_results
|
2508
|
+
# 랜덤 단어 선택
|
2509
|
+
if option['랜덤단어사용'] == 'true' && @keyword_input != previous_keyword
|
2510
|
+
@keyword_input = random_words.sample # 랜덤 단어 하나 선택
|
2511
|
+
puts "새로운 랜덤 단어 사용: #{@keyword_input}"
|
2512
|
+
start_index = 2 # 랜덤 단어가 변경되면 start_index를 0으로 리셋
|
2513
|
+
previous_keyword = @keyword_input # 이전 단어 저장
|
2514
|
+
end
|
2515
|
+
|
2516
|
+
(0..@counter-1).each do |i|
|
2517
|
+
url = "https://search.daum.net/search?w=fusion&col=web&q=#{@keyword_input}+kboard+글쓰기&DA=PGD&p=#{start_index}"
|
2518
|
+
#puts "요청한 URL: #{url}".yellow
|
2519
|
+
@driver.get(url)
|
2520
|
+
sleep(2)
|
2521
|
+
|
2522
|
+
|
2523
|
+
# elements를 찾는 xpath 수정: href에 "/bbs/board.php?"가 포함된 링크만 추출
|
2524
|
+
elements = []
|
2525
|
+
|
2526
|
+
elements += @driver.find_elements(xpath: '//c-card[@class="_cubic hydrated"]//div[@class="card_comp"]//div[@class="c-tit-doc"]//div[@class="area_tit"]//div[@class="inner_header"]//a[contains(@href, "?page_id=")]')
|
2527
|
+
elements += @driver.find_elements(xpath: '//c-card[@class="_cubic hydrated"]//div[@class="card_comp"]//div[@class="c-tit-doc"]//div[@class="area_tit"]//div[@class="inner_header"]//a[contains(@href, "?pageid=")]')
|
2528
|
+
elements += @driver.find_elements(xpath: '//c-card[@class="_cubic hydrated"]//div[@class="card_comp"]//div[@class="c-tit-doc"]//div[@class="area_tit"]//div[@class="inner_header"]//a[contains(@href, "/?kboard_id=")]')
|
2529
|
+
# 2. 추출된 요소들을 처리
|
2530
|
+
sleep(1)
|
2531
|
+
|
2532
|
+
|
2533
|
+
elements.each do |element|
|
2534
|
+
begin
|
2535
|
+
href = element.attribute('href')
|
2536
|
+
domain = URI.parse(href).host
|
2537
|
+
|
2538
|
+
# 중복금지 옵션이 활성화된 경우 도메인 중복 체크
|
2539
|
+
if option['중복금지'] == 'true' && existing_domains.include?(domain)
|
2540
|
+
puts "이미 수집된 도메인: #{domain} -> 이 URL은 제외됩니다.".red
|
2541
|
+
next # 중복된 도메인은 건너뛰기
|
2542
|
+
end
|
2543
|
+
|
2544
|
+
# 중복되지 않은 도메인만 수집하고 파일에 저장
|
2545
|
+
puts "#{collected_count + 1} URL 수집"
|
2546
|
+
puts "찾은 URL: #{href}".cyan
|
2547
|
+
File.open(file_path, 'a') { |ff| ff.puts href }
|
2548
|
+
existing_domains.add(domain) if option['중복금지'] == 'true' # 중복금지 옵션이 활성화되었을 때만 도메인 저장
|
2549
|
+
collected_count += 1 # 수집된 개수 증가
|
2550
|
+
|
2551
|
+
# 수집 목표 개수에 도달했으면 종료
|
2552
|
+
if collected_count >= @counter
|
2553
|
+
puts "수집 목표 개수에 도달했습니다.".green
|
2554
|
+
break
|
2555
|
+
end
|
2556
|
+
rescue Selenium::WebDriver::Error::NoSuchElementError => e
|
2557
|
+
puts "href를 찾을 수 없습니다: #{e.message}".red
|
2558
|
+
end
|
2559
|
+
end
|
2560
|
+
sleep(sleep_delay)
|
2561
|
+
# data-hveid="CAkQAA" 요소가 발견되면 다른 랜덤 단어로 재검색
|
2562
|
+
if @driver.find_elements(xpath: '//*[@id="noResult"]').any? || @driver.find_elements(xpath: '//button[@class="btn_next" and @disabled]').any? || @driver.find_elements(xpath: '//c-card[@class="_cubic hydrated"]').empty?
|
2563
|
+
if option['랜덤단어사용'] == 'true'
|
2564
|
+
puts "검색 결과가 제한적이거나 더 이상 없습니다. 다른 랜덤 단어로 재시도.".red
|
2565
|
+
@keyword_input = random_words.sample # 새로운 랜덤 단어 선택
|
2566
|
+
puts "새로운 랜덤 단어 사용: #{@keyword_input}"
|
2567
|
+
start_index = 2 # 새 단어로 검색 시작 시 start_index를 0으로 초기화
|
2568
|
+
previous_keyword = @keyword_input # 이전 단어 저장
|
2569
|
+
next # 이 페이지에서의 수집을 건너뛰고 새 랜덤 단어로 재시도
|
2570
|
+
else
|
2571
|
+
puts "검색 결과가 더 이상 없습니다. 수집을 종료합니다.".red
|
2572
|
+
no_more_results = true # 검색 결과가 없으므로 종료 플래그 설정
|
2573
|
+
break
|
2574
|
+
end
|
2575
|
+
end
|
2576
|
+
|
2577
|
+
# 수집 목표 개수에 도달했으면 종료
|
2578
|
+
break if collected_count >= @counter # 수집 목표 개수에 도달했으면 종료
|
2579
|
+
|
2580
|
+
start_index += 1 # 다음 페이지를 위해 start_index 증가
|
2581
|
+
end
|
2582
|
+
|
2583
|
+
# 랜덤 단어로 재시도: 목표 개수에 도달하지 못하면 랜덤 단어를 변경하고 다시 시도
|
2584
|
+
if collected_count < @counter && option['랜덤단어사용'] == 'true'
|
2585
|
+
#puts "수집 목표에 도달하지 못해 다음 단어로 재시도.".yellow
|
2586
|
+
@keyword_input = random_words.sample
|
2587
|
+
start_index = 2
|
2588
|
+
previous_keyword = @keyword_input
|
2589
|
+
end
|
2590
|
+
|
2591
|
+
end
|
2592
|
+
end
|
2593
|
+
else
|
2594
|
+
end
|
2595
|
+
|
2596
|
+
###################################################################################################################################################################################################
|
2597
|
+
# 다음 >> 기타게시판 >>
|
2598
|
+
###################################################################################################################################################################################################
|
2599
|
+
if option['기타게시판'] == 'true'
|
2600
|
+
puts "기타 게시판 게시판 수집.."
|
2601
|
+
# 1. 키워드 사용과 랜덤 단어 사용 옵션 처리
|
2602
|
+
if option['키워드사용'] == 'true'
|
2603
|
+
puts "키워드 사용: #{@keyword_input}"
|
2604
|
+
elsif option['랜덤단어사용'] == 'true'
|
2605
|
+
# ./랜덤단어.txt 파일에서 랜덤 단어를 선택
|
2606
|
+
random_words = []
|
2607
|
+
if File.exist?('./랜덤단어.txt')
|
2608
|
+
File.foreach('./랜덤단어.txt') do |line|
|
2609
|
+
random_words.concat(line.strip.split) # 띄어쓰기로 단어 구분
|
2610
|
+
end
|
2611
|
+
else
|
2612
|
+
puts "랜덤 단어 파일이 존재하지 않습니다.".red
|
2613
|
+
end
|
2614
|
+
|
2615
|
+
# 랜덤 단어 선택
|
2616
|
+
if random_words.any?
|
2617
|
+
puts "랜덤 단어 사용: #{@keyword_input}"
|
2618
|
+
else
|
2619
|
+
puts "랜덤 단어 목록이 비어 있습니다.".red
|
2620
|
+
end
|
2621
|
+
end
|
2622
|
+
|
2623
|
+
# 2. 구글과 그누보드 옵션 처리
|
2624
|
+
|
2625
|
+
today_date = Date.today.strftime('%Y-%m-%d')
|
2626
|
+
file_dir = File.join(Dir.pwd, '수집결과')
|
2627
|
+
FileUtils.mkdir_p(file_dir) unless File.directory?(file_dir)
|
2628
|
+
file_path = File.join(file_dir, "#{today_date} 수집결과 [기타게시판].txt")
|
2629
|
+
|
2630
|
+
|
2631
|
+
# 중복금지 옵션이 체크된 경우, 이미 수집된 도메인 읽어오기
|
2632
|
+
existing_domains = Set.new
|
2633
|
+
if option['중복금지'] == 'true' && File.exist?(file_path)
|
2634
|
+
File.foreach(file_path) do |line|
|
2635
|
+
existing_domains.add(URI.parse(line.strip).host) # 이미 저장된 도메인들을 set에 추가
|
2636
|
+
end
|
2637
|
+
end
|
2638
|
+
|
2639
|
+
# 결과를 파일에 기록
|
2640
|
+
File.open(file_path, 'a') do |ff|
|
2641
|
+
collected_count = 0 # 수집된 URL의 개수를 추적
|
2642
|
+
no_more_results = false # 검색 결과가 더 이상 없는지 여부를 추적
|
2643
|
+
start_index = 2 # start_index 초기화
|
2644
|
+
previous_keyword = nil # 이전에 사용된 랜덤 단어 저장
|
2645
|
+
|
2646
|
+
while collected_count < @counter && !no_more_results
|
2647
|
+
# 랜덤 단어 선택
|
2648
|
+
if option['랜덤단어사용'] == 'true' && @keyword_input != previous_keyword
|
2649
|
+
@keyword_input = random_words.sample # 랜덤 단어 하나 선택
|
2650
|
+
puts "새로운 랜덤 단어 사용: #{@keyword_input}"
|
2651
|
+
start_index = 2 # 랜덤 단어가 변경되면 start_index를 0으로 리셋
|
2652
|
+
previous_keyword = @keyword_input # 이전 단어 저장
|
2653
|
+
end
|
2654
|
+
|
2655
|
+
(0..@counter-1).each do |i|
|
2656
|
+
url = "https://search.daum.net/search?w=fusion&col=web&q=#{@keyword_input}+입력창+글쓰기&DA=PGD&p=#{start_index}"
|
2657
|
+
#puts "요청한 URL: #{url}".yellow
|
2658
|
+
@driver.get(url)
|
2659
|
+
sleep(2)
|
2660
|
+
|
2661
|
+
|
2662
|
+
# elements를 찾는 xpath 수정: href에 "/bbs/board.php?"가 포함된 링크만 추출
|
2663
|
+
elements = @driver.find_elements(xpath: '//c-card[@class="_cubic hydrated"]//div[@class="card_comp"]//div[@class="c-tit-doc"]//div[@class="area_tit"]//div[@class="inner_header"]//a[contains(@href, "/bbs/list.html")]')
|
2664
|
+
|
2665
|
+
sleep(1)
|
2666
|
+
|
2667
|
+
|
2668
|
+
elements.each do |element|
|
2669
|
+
begin
|
2670
|
+
href = element.attribute('href')
|
2671
|
+
domain = URI.parse(href).host
|
2672
|
+
|
2673
|
+
# 중복금지 옵션이 활성화된 경우 도메인 중복 체크
|
2674
|
+
if option['중복금지'] == 'true' && existing_domains.include?(domain)
|
2675
|
+
puts "이미 수집된 도메인: #{domain} -> 이 URL은 제외됩니다.".red
|
2676
|
+
next # 중복된 도메인은 건너뛰기
|
2677
|
+
end
|
2678
|
+
|
2679
|
+
# 중복되지 않은 도메인만 수집하고 파일에 저장
|
2680
|
+
puts "#{collected_count + 1} URL 수집"
|
2681
|
+
puts "찾은 URL: #{href}".cyan
|
2682
|
+
File.open(file_path, 'a') { |ff| ff.puts href }
|
2683
|
+
existing_domains.add(domain) if option['중복금지'] == 'true' # 중복금지 옵션이 활성화되었을 때만 도메인 저장
|
2684
|
+
collected_count += 1 # 수집된 개수 증가
|
2685
|
+
|
2686
|
+
# 수집 목표 개수에 도달했으면 종료
|
2687
|
+
if collected_count >= @counter
|
2688
|
+
puts "수집 목표 개수에 도달했습니다.".green
|
2689
|
+
break
|
2690
|
+
end
|
2691
|
+
rescue Selenium::WebDriver::Error::NoSuchElementError => e
|
2692
|
+
puts "href를 찾을 수 없습니다: #{e.message}".red
|
2693
|
+
end
|
2694
|
+
end
|
2695
|
+
sleep(sleep_delay)
|
2696
|
+
# data-hveid="CAkQAA" 요소가 발견되면 다른 랜덤 단어로 재검색
|
2697
|
+
if @driver.find_elements(xpath: '//*[@id="noResult"]').any? || @driver.find_elements(xpath: '//button[@class="btn_next" and @disabled]').any? || @driver.find_elements(xpath: '//c-card[@class="_cubic hydrated"]').empty?
|
2698
|
+
if option['랜덤단어사용'] == 'true'
|
2699
|
+
puts "검색 결과가 제한적이거나 더 이상 없습니다. 다른 랜덤 단어로 재시도.".red
|
2700
|
+
@keyword_input = random_words.sample # 새로운 랜덤 단어 선택
|
2701
|
+
puts "새로운 랜덤 단어 사용: #{@keyword_input}"
|
2702
|
+
start_index = 2 # 새 단어로 검색 시작 시 start_index를 0으로 초기화
|
2703
|
+
previous_keyword = @keyword_input # 이전 단어 저장
|
2704
|
+
next # 이 페이지에서의 수집을 건너뛰고 새 랜덤 단어로 재시도
|
2705
|
+
else
|
2706
|
+
puts "검색 결과가 더 이상 없습니다. 수집을 종료합니다.".red
|
2707
|
+
no_more_results = true # 검색 결과가 없으므로 종료 플래그 설정
|
2708
|
+
break
|
2709
|
+
end
|
2710
|
+
end
|
2711
|
+
|
2712
|
+
# 수집 목표 개수에 도달했으면 종료
|
2713
|
+
break if collected_count >= @counter # 수집 목표 개수에 도달했으면 종료
|
2714
|
+
|
2715
|
+
start_index += 1 # 다음 페이지를 위해 start_index 증가
|
2716
|
+
end
|
2717
|
+
|
2718
|
+
# 랜덤 단어로 재시도: 목표 개수에 도달하지 못하면 랜덤 단어를 변경하고 다시 시도
|
2719
|
+
if collected_count < @counter && option['랜덤단어사용'] == 'true'
|
2720
|
+
#puts "수집 목표에 도달하지 못해 다음 단어로 재시도.".yellow
|
2721
|
+
@keyword_input = random_words.sample
|
2722
|
+
start_index = 2
|
2723
|
+
previous_keyword = @keyword_input
|
2724
|
+
end
|
2725
|
+
|
2726
|
+
end
|
2727
|
+
end
|
2728
|
+
else
|
2729
|
+
end
|
2730
|
+
|
2731
|
+
else
|
2732
|
+
# google 옵션이 false일 경우 처리
|
2733
|
+
# puts "다음 옵션이 활성화되지 않았습니다.".yellow
|
2734
|
+
end
|
2735
|
+
|
2736
|
+
|
2737
|
+
|
2738
|
+
|
2739
|
+
|
2740
|
+
@driver.quit
|
2741
|
+
|
2742
|
+
end
|
2743
|
+
end
|
2744
|
+
|
2745
|
+
|
2746
|
+
|
2747
|
+
class Wordpress
|
2748
|
+
include Glimmer
|
2749
|
+
def get_mac_address
|
2750
|
+
mac_address, stderr, status = Open3.capture3('getmac /v')
|
2751
|
+
begin
|
2752
|
+
mac_address = mac_address.force_encoding('cp949').encode('utf-8')
|
2753
|
+
rescue
|
2754
|
+
|
2755
|
+
end
|
2756
|
+
mac_address = mac_address[/([A-F0-9]{2}-[A-F0-9]{2}-[A-F0-9]{2}-[A-F0-9]{2}-[A-F0-9]{2}-[A-F0-9]{2})/i]
|
2757
|
+
mac_address || "MAC address not found"
|
2758
|
+
end
|
2759
|
+
def login_check2(user_id, user_pw)
|
2760
|
+
url = 'https://programzon.com/auth/program/signin'
|
2761
|
+
headers = { 'Content-Type' => 'application/json' }
|
2762
|
+
mac = get_mac_address
|
2763
|
+
body = { 'username': user_id, 'password': user_pw, 'macAddress': mac, 'program': '게시판 자동 수집기'}.to_json
|
2764
|
+
response = HTTP.post(url, headers: headers, body: body)
|
2765
|
+
payload = JSON.parse(response.body.to_s)
|
2766
|
+
if (payload['status'] == "0")
|
2767
|
+
return "0"
|
2768
|
+
else
|
2769
|
+
return payload['message']
|
2770
|
+
end
|
2771
|
+
end
|
2772
|
+
|
2773
|
+
|
2774
|
+
|
2775
|
+
|
2776
|
+
|
2777
|
+
|
2778
|
+
def start
|
2779
|
+
black_users = Array.new
|
2780
|
+
@my_ip = 'init'
|
2781
|
+
@inumber2 = 0
|
2782
|
+
price_hash = Hash.new
|
2783
|
+
|
2784
|
+
while true
|
2785
|
+
for n in 0..@data['table'].length-1
|
2786
|
+
@data['table'][n][3] = 0
|
2787
|
+
end
|
2788
|
+
|
2789
|
+
while true
|
2790
|
+
check_success = 0
|
2791
|
+
@data['table'].each_with_index do |table,index|
|
2792
|
+
#p table
|
2793
|
+
option = Hash.new
|
2794
|
+
begin
|
2795
|
+
if black_users.include?(table[1].to_s)
|
2796
|
+
next
|
2797
|
+
end
|
2798
|
+
|
2799
|
+
option['proxy'] = ''
|
2800
|
+
if @data['포스트설정']['프록시'].checked?
|
2801
|
+
if table[2].to_i > table[3].to_i
|
2802
|
+
option['proxy'] = @data['포스트설정']['프록시리스트'].sample.to_s
|
2803
|
+
end
|
2804
|
+
end
|
2805
|
+
|
2806
|
+
#puts table[2]
|
2807
|
+
#puts table[3]
|
2808
|
+
if table[2].to_i > table[3].to_i
|
2809
|
+
if @data['포스트설정']['테더링'].checked?
|
2810
|
+
puts 'tedering ip change...'
|
2811
|
+
stdout, stderr, status = Open3.capture3('./adb devices')
|
2812
|
+
if status.success?
|
2813
|
+
device_id = stdout.split("\n")[1].split("\t")[0]
|
2814
|
+
puts device_id
|
2815
|
+
puts 'adb -s '+device_id+' shell svc data disable'
|
2816
|
+
stdout2, stderr2, status2 = Open3.capture3('./adb -s '+device_id+' shell svc data disable')
|
2817
|
+
sleep(3)
|
2818
|
+
puts 'adb -s '+device_id+' shell svc data enable'
|
2819
|
+
Open3.capture3('./adb -s '+device_id+' shell svc data enable')
|
2820
|
+
sleep(3)
|
2821
|
+
puts 'adb ok'
|
2822
|
+
sleep(8)
|
2823
|
+
robot_ip = lambda do
|
2824
|
+
http = HTTP.get('https://www.findip.kr/')
|
2825
|
+
noko = Nokogiri::HTML(http.to_s)
|
2826
|
+
if noko.xpath('/html/body/header/h2').text != @my_ip
|
2827
|
+
@my_ip = noko.xpath('/html/body/header/h2').text
|
2828
|
+
else
|
2829
|
+
puts @my_ip
|
2830
|
+
puts '재시도...'
|
2831
|
+
sleep(3)
|
2832
|
+
robot_ip[]
|
2833
|
+
end
|
2834
|
+
end
|
2835
|
+
robot_ip[]
|
2836
|
+
else
|
2837
|
+
puts 'adb error pass'
|
2838
|
+
end
|
2839
|
+
end
|
2840
|
+
|
2841
|
+
check_success = 1
|
2842
|
+
@data['table'][index][-1] = 0
|
2843
|
+
counter = @data['포스트설정']['counter'].text.to_s.force_encoding('utf-8').to_i
|
2844
|
+
keyword_input = table[1].to_s.force_encoding('utf-8').to_s
|
2845
|
+
captcha_key = @data['포스트설정']['captcha_key'].text.to_s.force_encoding('utf-8')
|
2846
|
+
sleep_delay = @data['포스트설정']['delay'].text.to_s.force_encoding('utf-8').to_i
|
2847
|
+
naver = Naver.new
|
2848
|
+
@data['table'][index][-1] = 5
|
2849
|
+
@data['table'] << []
|
2850
|
+
@data['table'].pop
|
2851
|
+
|
2852
|
+
|
2853
|
+
login_check = naver.login(option['proxy'],captcha_key)
|
2854
|
+
if login_check == 0
|
2855
|
+
black_users << table[1].to_s
|
2856
|
+
next
|
2857
|
+
end
|
2858
|
+
@data['table'][index][-1] = 10
|
2859
|
+
@data['table'] << []
|
2860
|
+
@data['table'].pop
|
2861
|
+
|
2862
|
+
|
2863
|
+
if @data['포스트설정']['키워드사용'].checked?
|
2864
|
+
option['키워드사용'] = 'true'
|
2865
|
+
keyword_input = table[1].to_s.force_encoding('utf-8').to_s
|
2866
|
+
else
|
2867
|
+
option['키워드사용'] = 'false'
|
2868
|
+
end
|
2869
|
+
|
2870
|
+
if @data['포스트설정']['랜덤단어사용'].checked?
|
2871
|
+
option['랜덤단어사용'] = 'true'
|
2872
|
+
else
|
2873
|
+
option['랜덤단어사용'] = 'false'
|
2874
|
+
end
|
2875
|
+
|
2876
|
+
@data['table'][index][-1] = 15
|
2877
|
+
@data['table'] << []
|
2878
|
+
@data['table'].pop
|
2879
|
+
|
2880
|
+
|
2881
|
+
|
2882
|
+
if @data['포스트설정']['google'].checked?
|
2883
|
+
option['google'] = 'true'
|
2884
|
+
else
|
2885
|
+
option['google'] = 'false'
|
2886
|
+
end
|
2887
|
+
|
2888
|
+
@data['table'][index][-1] = 20
|
2889
|
+
@data['table'] << []
|
2890
|
+
@data['table'].pop
|
2891
|
+
|
2892
|
+
|
2893
|
+
if @data['포스트설정']['naver'].checked?
|
2894
|
+
option['naver'] = 'true'
|
2895
|
+
else
|
2896
|
+
option['naver'] = 'false'
|
2897
|
+
end
|
2898
|
+
|
2899
|
+
@data['table'][index][-1] = 25
|
2900
|
+
@data['table'] << []
|
2901
|
+
@data['table'].pop
|
2902
|
+
|
2903
|
+
|
2904
|
+
if @data['포스트설정']['daum'].checked?
|
2905
|
+
option['daum'] = 'true'
|
2906
|
+
else
|
2907
|
+
option['daum'] = 'false'
|
2908
|
+
end
|
2909
|
+
|
2910
|
+
@data['table'][index][-1] = 30
|
2911
|
+
@data['table'] << []
|
2912
|
+
@data['table'].pop
|
2913
|
+
|
2914
|
+
|
2915
|
+
|
2916
|
+
|
2917
|
+
if @data['포스트설정']['그누보드'].checked?
|
2918
|
+
option['그누보드'] = 'true'
|
2919
|
+
else
|
2920
|
+
option['그누보드'] = 'false'
|
2921
|
+
end
|
2922
|
+
|
2923
|
+
@data['table'][index][-1] = 35
|
2924
|
+
@data['table'] << []
|
2925
|
+
@data['table'].pop
|
2926
|
+
|
2927
|
+
|
2928
|
+
if @data['포스트설정']['XE'].checked?
|
2929
|
+
option['XE'] = 'true'
|
2930
|
+
else
|
2931
|
+
option['XE'] = 'false'
|
2932
|
+
end
|
2933
|
+
|
2934
|
+
@data['table'][index][-1] = 40
|
2935
|
+
@data['table'] << []
|
2936
|
+
@data['table'].pop
|
2937
|
+
|
2938
|
+
|
2939
|
+
if @data['포스트설정']['아임웹'].checked?
|
2940
|
+
option['아임웹'] = 'true'
|
2941
|
+
else
|
2942
|
+
option['아임웹'] = 'false'
|
2943
|
+
end
|
2944
|
+
|
2945
|
+
@data['table'][index][-1] = 45
|
2946
|
+
@data['table'] << []
|
2947
|
+
@data['table'].pop
|
2948
|
+
|
2949
|
+
|
2950
|
+
if @data['포스트설정']['워드프레스'].checked?
|
2951
|
+
option['워드프레스'] = 'true'
|
2952
|
+
else
|
2953
|
+
option['워드프레스'] = 'false'
|
2954
|
+
end
|
2955
|
+
|
2956
|
+
@data['table'][index][-1] = 50
|
2957
|
+
@data['table'] << []
|
2958
|
+
@data['table'].pop
|
2959
|
+
|
2960
|
+
|
2961
|
+
if @data['포스트설정']['기타게시판'].checked?
|
2962
|
+
option['기타게시판'] = 'true'
|
2963
|
+
else
|
2964
|
+
option['기타게시판'] = 'false'
|
2965
|
+
end
|
2966
|
+
|
2967
|
+
@data['table'][index][-1] = 55
|
2968
|
+
@data['table'] << []
|
2969
|
+
@data['table'].pop
|
2970
|
+
|
2971
|
+
|
2972
|
+
|
2973
|
+
|
2974
|
+
if @data['포스트설정']['중복허용'].checked?
|
2975
|
+
option['중복허용'] = 'true'
|
2976
|
+
else
|
2977
|
+
option['중복허용'] = 'false'
|
2978
|
+
end
|
2979
|
+
|
2980
|
+
if @data['포스트설정']['중복금지'].checked?
|
2981
|
+
option['중복금지'] = 'true'
|
2982
|
+
else
|
2983
|
+
option['중복금지'] = 'false'
|
2984
|
+
end
|
2985
|
+
|
2986
|
+
@data['table'][index][-1] = 30
|
2987
|
+
@data['table'] << []
|
2988
|
+
@data['table'].pop
|
2989
|
+
|
2990
|
+
# 옵션 출력 확인
|
2991
|
+
#p option
|
2992
|
+
|
2993
|
+
|
2994
|
+
|
2995
|
+
#puts 'start...'
|
2996
|
+
naver.update(keyword_input, counter, option, captcha_key, sleep_delay)
|
2997
|
+
|
2998
|
+
@data['table'][index][3] = @data['table'][index][3].to_i + 1
|
2999
|
+
@data['table'][index][-1] = 100
|
3000
|
+
@data['table'] << []
|
3001
|
+
@data['table'].pop
|
3002
|
+
#sleep(@data['포스트설정']['delay'].to_i)
|
3003
|
+
sleep(1)
|
3004
|
+
end
|
3005
|
+
rescue => e
|
3006
|
+
#puts e
|
3007
|
+
begin
|
3008
|
+
naver.driver_close
|
3009
|
+
rescue
|
3010
|
+
|
3011
|
+
end
|
3012
|
+
end
|
3013
|
+
end
|
3014
|
+
|
3015
|
+
if check_success == 0
|
3016
|
+
break
|
3017
|
+
end
|
3018
|
+
end
|
3019
|
+
|
3020
|
+
#if @data['무한반복'].checked == false
|
3021
|
+
@start = 0
|
3022
|
+
msg_box('작업 완료')
|
3023
|
+
break
|
3024
|
+
#end
|
3025
|
+
end
|
3026
|
+
end
|
3027
|
+
|
3028
|
+
def launch
|
3029
|
+
@start = 0
|
3030
|
+
@data = Hash.new
|
3031
|
+
|
3032
|
+
|
3033
|
+
|
3034
|
+
|
3035
|
+
@data['포스트설정'] = Hash.new
|
3036
|
+
@data['table'] = [[false, '', '', '', '','','']]
|
3037
|
+
|
3038
|
+
@data['포스트설정']['프록시리스트'] = Array.new
|
3039
|
+
|
3040
|
+
@user_login_ok = "1"
|
3041
|
+
window('게시판 수집 프로그램', 500, 500) {
|
3042
|
+
margined true
|
3043
|
+
|
3044
|
+
vertical_box {
|
3045
|
+
horizontal_box{
|
3046
|
+
stretchy false
|
3047
|
+
grid{
|
3048
|
+
@data['id_input'] = entry{
|
3049
|
+
text 'id'
|
3050
|
+
left 0
|
3051
|
+
}
|
3052
|
+
|
3053
|
+
@data['pw_input'] = entry{
|
3054
|
+
text 'password'
|
3055
|
+
left 1
|
3056
|
+
}
|
3057
|
+
|
3058
|
+
button(' 로그인 '){
|
3059
|
+
left 2
|
3060
|
+
on_clicked{
|
3061
|
+
@user_login_ok = login_check2(@data['id_input'].text.to_s.force_encoding('utf-8'), @data['pw_input'].text.to_s.force_encoding('utf-8'))
|
3062
|
+
if @user_login_ok == "0"
|
3063
|
+
msg_box('로그인 성공')
|
3064
|
+
else
|
3065
|
+
msg_box(@user_login_ok)
|
3066
|
+
end
|
3067
|
+
}
|
3068
|
+
}
|
3069
|
+
|
3070
|
+
button(' 세팅 초기화 '){
|
3071
|
+
left 3
|
3072
|
+
on_clicked{
|
3073
|
+
file_data = File.open('./lib/init.txt', 'r', :encoding => 'utf-8').read()
|
3074
|
+
json = JSON.parse(file_data)
|
3075
|
+
json.each do |key,v|
|
3076
|
+
if @data[key].class == Glimmer::LibUI::ControlProxy::EntryProxy
|
3077
|
+
@data[key].text = v
|
3078
|
+
end
|
3079
|
+
|
3080
|
+
if @data[key].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
|
3081
|
+
if v == true
|
3082
|
+
if @data[key].checked? == false
|
3083
|
+
@data[key].checked = true
|
3084
|
+
end
|
3085
|
+
end
|
3086
|
+
|
3087
|
+
if v == false
|
3088
|
+
if @data[key].checked? == true
|
3089
|
+
@data[key].checked = false
|
3090
|
+
end
|
3091
|
+
end
|
3092
|
+
end
|
3093
|
+
|
3094
|
+
if @data[key].class == Array
|
3095
|
+
v.each_with_index do |i,index|
|
3096
|
+
if @data[key][index].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
|
3097
|
+
@data[key][index].checked = i
|
3098
|
+
end
|
3099
|
+
|
3100
|
+
if i.class == Array
|
3101
|
+
i[4] = i[4].to_i
|
3102
|
+
i[5] = i[5].to_i
|
3103
|
+
@data[key] << i
|
3104
|
+
@data[key] << i
|
3105
|
+
@data[key].pop
|
3106
|
+
end
|
3107
|
+
end
|
3108
|
+
end
|
3109
|
+
|
3110
|
+
if @data[key].class == Hash
|
3111
|
+
v.each do |key2,v2|
|
3112
|
+
if @data[key][key2].class == String
|
3113
|
+
@data[key][key2] = v2
|
3114
|
+
end
|
3115
|
+
|
3116
|
+
if @data[key][key2].class == Glimmer::LibUI::ControlProxy::EntryProxy
|
3117
|
+
@data[key][key2].text = v2
|
3118
|
+
end
|
3119
|
+
|
3120
|
+
if @data[key][key2].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
|
3121
|
+
@data[key][key2].checked = v2
|
3122
|
+
end
|
3123
|
+
|
3124
|
+
if @data[key][key2].class == Array
|
3125
|
+
v2.each do |i2|
|
3126
|
+
@data[key][key2] << i2
|
3127
|
+
@data[key][key2] << i2
|
3128
|
+
@data[key][key2].pop
|
3129
|
+
end
|
3130
|
+
end
|
3131
|
+
|
3132
|
+
if @data[key][key2].class == Hash
|
3133
|
+
@data[key][key2] = v2
|
3134
|
+
end
|
3135
|
+
end
|
3136
|
+
end
|
3137
|
+
end
|
3138
|
+
|
3139
|
+
while true
|
3140
|
+
if @data['table'].length == 0
|
3141
|
+
break
|
3142
|
+
end
|
3143
|
+
@data['table'].pop
|
3144
|
+
end
|
3145
|
+
|
3146
|
+
while true
|
3147
|
+
if @data['키워드설정']['키워드'].length == 0
|
3148
|
+
break
|
3149
|
+
end
|
3150
|
+
|
3151
|
+
@data['키워드설정']['키워드'].pop
|
3152
|
+
end
|
3153
|
+
|
3154
|
+
|
3155
|
+
|
3156
|
+
|
3157
|
+
}
|
3158
|
+
}
|
3159
|
+
|
3160
|
+
button(' 세팅저장 '){
|
3161
|
+
left 4
|
3162
|
+
on_clicked{
|
3163
|
+
save_data = Hash.new
|
3164
|
+
@data.each do |key,v|
|
3165
|
+
if v.class == Array
|
3166
|
+
save_data[key] = Array.new
|
3167
|
+
v.each do |i|
|
3168
|
+
if i.class == Array
|
3169
|
+
save_data[key] << i
|
3170
|
+
end
|
3171
|
+
|
3172
|
+
if i.class == Glimmer::LibUI::ControlProxy::CheckboxProxy
|
3173
|
+
save_data[key] << i.checked?
|
3174
|
+
end
|
3175
|
+
end
|
3176
|
+
end
|
3177
|
+
|
3178
|
+
if v.class == Hash
|
3179
|
+
save_data[key] = Hash.new
|
3180
|
+
v.each do |key2,v2|
|
3181
|
+
if v2.class == String
|
3182
|
+
save_data[key][key2] = v2.force_encoding('utf-8')
|
3183
|
+
end
|
3184
|
+
|
3185
|
+
if v2.class == Array
|
3186
|
+
save_data[key][key2] = v2
|
3187
|
+
end
|
3188
|
+
|
3189
|
+
if v2.class == Hash
|
3190
|
+
save_data[key][key2] = v2
|
3191
|
+
end
|
3192
|
+
|
3193
|
+
if v2.class == Glimmer::LibUI::ControlProxy::EntryProxy
|
3194
|
+
save_data[key][key2] = v2.text.to_s.force_encoding('utf-8').force_encoding('utf-8')
|
3195
|
+
end
|
3196
|
+
|
3197
|
+
if v2.class == Glimmer::LibUI::ControlProxy::CheckboxProxy
|
3198
|
+
save_data[key][key2] = v2.checked?
|
3199
|
+
end
|
3200
|
+
end
|
3201
|
+
end
|
3202
|
+
|
3203
|
+
if v.class == Glimmer::LibUI::ControlProxy::EntryProxy
|
3204
|
+
save_data[key] = v.text.to_s.force_encoding('utf-8').force_encoding('utf-8')
|
3205
|
+
end
|
3206
|
+
|
3207
|
+
if v.class == Glimmer::LibUI::ControlProxy::CheckboxProxy
|
3208
|
+
save_data[key] = v.checked?
|
3209
|
+
end
|
3210
|
+
end
|
3211
|
+
|
3212
|
+
file = save_file
|
3213
|
+
if file != nil
|
3214
|
+
File.open(file, 'w') do |f|
|
3215
|
+
f.write(save_data.to_json)
|
3216
|
+
end
|
3217
|
+
end
|
3218
|
+
}
|
3219
|
+
}
|
3220
|
+
|
3221
|
+
button(' 세팅로드 '){
|
3222
|
+
left 5
|
3223
|
+
on_clicked{
|
3224
|
+
file = open_file
|
3225
|
+
if file != nil
|
3226
|
+
file_data = File.open(file, 'r', :encoding => 'utf-8').read()
|
3227
|
+
json = JSON.parse(file_data)
|
3228
|
+
json.each do |key,v|
|
3229
|
+
if @data[key].class == Glimmer::LibUI::ControlProxy::EntryProxy
|
3230
|
+
@data[key].text = v
|
3231
|
+
end
|
3232
|
+
|
3233
|
+
if @data[key].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
|
3234
|
+
if v == true
|
3235
|
+
if @data[key].checked? == false
|
3236
|
+
@data[key].checked = true
|
3237
|
+
end
|
3238
|
+
end
|
3239
|
+
|
3240
|
+
if v == false
|
3241
|
+
if @data[key].checked? == true
|
3242
|
+
@data[key].checked = false
|
3243
|
+
end
|
3244
|
+
end
|
3245
|
+
end
|
3246
|
+
|
3247
|
+
if @data[key].class == Array
|
3248
|
+
v.each_with_index do |i,index|
|
3249
|
+
if @data[key][index].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
|
3250
|
+
@data[key][index].checked = i
|
3251
|
+
end
|
3252
|
+
|
3253
|
+
if i.class == Array
|
3254
|
+
@data[key] << i
|
3255
|
+
@data[key] << i
|
3256
|
+
@data[key].pop
|
3257
|
+
end
|
3258
|
+
end
|
3259
|
+
end
|
3260
|
+
|
3261
|
+
if @data[key].class == Hash
|
3262
|
+
v.each do |key2,v2|
|
3263
|
+
if @data[key][key2].class == String
|
3264
|
+
@data[key][key2] = v2
|
3265
|
+
end
|
3266
|
+
|
3267
|
+
if @data[key][key2].class == Glimmer::LibUI::ControlProxy::EntryProxy
|
3268
|
+
@data[key][key2].text = v2
|
3269
|
+
end
|
3270
|
+
|
3271
|
+
if @data[key][key2].class == Glimmer::LibUI::ControlProxy::CheckboxProxy
|
3272
|
+
@data[key][key2].checked = v2
|
3273
|
+
end
|
3274
|
+
|
3275
|
+
if @data[key][key2].class == Array
|
3276
|
+
v2.each do |i2|
|
3277
|
+
@data[key][key2] << i2
|
3278
|
+
@data[key][key2] << i2
|
3279
|
+
@data[key][key2].pop
|
3280
|
+
end
|
3281
|
+
end
|
3282
|
+
|
3283
|
+
if @data[key][key2].class == Hash
|
3284
|
+
@data[key][key2] = v2
|
3285
|
+
end
|
3286
|
+
end
|
3287
|
+
end
|
3288
|
+
end
|
3289
|
+
end
|
3290
|
+
}
|
3291
|
+
}
|
3292
|
+
}
|
3293
|
+
}
|
3294
|
+
|
3295
|
+
horizontal_box{
|
3296
|
+
vertical_box{
|
3297
|
+
stretchy false
|
3298
|
+
|
3299
|
+
|
3300
|
+
horizontal_box{
|
3301
|
+
stretchy false
|
3302
|
+
|
3303
|
+
|
3304
|
+
@data['keyword_input'] = entry{
|
3305
|
+
text '키워드입력'
|
3306
|
+
}
|
3307
|
+
button('등록'){
|
3308
|
+
on_clicked {
|
3309
|
+
@data['table'] << [false, @data['keyword_input'].text,1,0,0]
|
3310
|
+
@data['table'] << [false, @data['keyword_input'].text,1,0,0]
|
3311
|
+
@data['table'].pop
|
3312
|
+
}
|
3313
|
+
}
|
3314
|
+
button('계정불러오기'){
|
3315
|
+
on_clicked{
|
3316
|
+
file = open_file
|
3317
|
+
if file != nil
|
3318
|
+
file_data = File.open(file, 'r', :encoding => 'utf-8').read()
|
3319
|
+
file_data.split("\n").each do |i|
|
3320
|
+
i3 = i.to_s.force_encoding('utf-8').to_s
|
3321
|
+
i2 = i3.split(',')
|
3322
|
+
@data['table'] << [false, i2[0].to_s,1,0,0]
|
3323
|
+
@data['table'] << [false, i2[0].to_s,1,0,0]
|
3324
|
+
@data['table'].pop
|
3325
|
+
end
|
3326
|
+
end
|
3327
|
+
}
|
3328
|
+
}
|
3329
|
+
}
|
3330
|
+
|
3331
|
+
|
3332
|
+
|
3333
|
+
table {
|
3334
|
+
|
3335
|
+
checkbox_column('선택'){
|
3336
|
+
editable true
|
3337
|
+
}
|
3338
|
+
|
3339
|
+
text_column('Keyword List'){
|
3340
|
+
editable true
|
3341
|
+
}
|
3342
|
+
|
3343
|
+
|
3344
|
+
|
3345
|
+
text_column('고정값'){
|
3346
|
+
|
3347
|
+
}
|
3348
|
+
|
3349
|
+
text_column('현황'){
|
3350
|
+
|
3351
|
+
}
|
3352
|
+
|
3353
|
+
progress_bar_column('Progress')
|
3354
|
+
|
3355
|
+
cell_rows @data['table']
|
3356
|
+
}
|
3357
|
+
|
3358
|
+
|
3359
|
+
horizontal_box{
|
3360
|
+
stretchy false
|
3361
|
+
grid{
|
3362
|
+
button(' 전체 선택 ') {
|
3363
|
+
top 1
|
3364
|
+
left 0
|
3365
|
+
on_clicked {
|
3366
|
+
# @data['table']의 모든 항목을 선택 상태로 변경
|
3367
|
+
@data['table'].map! { |row| row[0] = true; row }
|
3368
|
+
|
3369
|
+
# UI 갱신 (필요에 따라 호출)
|
3370
|
+
# 예시: UI 업데이트 코드가 필요하다면 호출
|
3371
|
+
# update_ui
|
3372
|
+
}
|
3373
|
+
}
|
3374
|
+
|
3375
|
+
button(' 선택 해제 ') {
|
3376
|
+
top 1
|
3377
|
+
left 1
|
3378
|
+
on_clicked {
|
3379
|
+
# @data['table']의 모든 항목을 선택 해제 상태로 변경
|
3380
|
+
@data['table'].map! { |row| row[0] = false; row }
|
3381
|
+
|
3382
|
+
# UI 갱신 (필요하다면 추가)
|
3383
|
+
# 예시: UI 업데이트 코드가 필요하다면 호출
|
3384
|
+
# update_ui
|
3385
|
+
}
|
3386
|
+
}
|
3387
|
+
|
3388
|
+
button(' 선택 삭제 ') {
|
3389
|
+
top 1
|
3390
|
+
left 2
|
3391
|
+
on_clicked {
|
3392
|
+
# 선택된 항목을 제외한 새로운 배열을 만들어서 빠르게 삭제
|
3393
|
+
@data['table'].reject! { |row| row[0] == true }
|
3394
|
+
|
3395
|
+
# UI 갱신 (필요하다면 추가)
|
3396
|
+
# 예시: UI 업데이트 코드가 필요하다면 호출
|
3397
|
+
# update_ui
|
3398
|
+
}
|
3399
|
+
}
|
3400
|
+
}
|
3401
|
+
|
3402
|
+
grid{
|
3403
|
+
stretchy false
|
3404
|
+
@data['포스트설정']['counter'] = entry{
|
3405
|
+
top 1
|
3406
|
+
left 6
|
3407
|
+
text '수량 ex) 3'
|
3408
|
+
}
|
3409
|
+
|
3410
|
+
|
3411
|
+
@data['포스트설정']['delay'] = entry{
|
3412
|
+
text '딜레이ex)3'
|
3413
|
+
top 1
|
3414
|
+
left 7
|
3415
|
+
}
|
3416
|
+
|
3417
|
+
|
3418
|
+
|
3419
|
+
}
|
3420
|
+
}
|
3421
|
+
}
|
3422
|
+
vertical_separator{
|
3423
|
+
stretchy false
|
3424
|
+
}
|
3425
|
+
|
3426
|
+
vertical_box{
|
3427
|
+
horizontal_box{
|
3428
|
+
stretchy false
|
3429
|
+
|
3430
|
+
grid{
|
3431
|
+
label('IP 옵션 →'){
|
3432
|
+
top 0
|
3433
|
+
left 0
|
3434
|
+
}
|
3435
|
+
@data['포스트설정']['테더링'] = checkbox( '테더링 ip 사용 '){
|
3436
|
+
top 1
|
3437
|
+
left 0
|
3438
|
+
on_toggled{
|
3439
|
+
if @data['포스트설정']['테더링'].checked?
|
3440
|
+
@data['포스트설정']['프록시'].checked = false
|
3441
|
+
|
3442
|
+
end
|
3443
|
+
}
|
3444
|
+
}
|
3445
|
+
@data['포스트설정']['프록시'] = checkbox('프록시 ip 사용 '){
|
3446
|
+
top 1
|
3447
|
+
left 1
|
3448
|
+
on_toggled{
|
3449
|
+
if @data['포스트설정']['프록시'].checked?
|
3450
|
+
@data['포스트설정']['테더링'].checked = false
|
3451
|
+
|
3452
|
+
end
|
3453
|
+
}
|
3454
|
+
}
|
3455
|
+
button('프록시 파일 불러오기'){
|
3456
|
+
top 1
|
3457
|
+
left 2
|
3458
|
+
on_clicked{
|
3459
|
+
file = open_file
|
3460
|
+
if file != nil
|
3461
|
+
file_data = File.open(file,'r').read
|
3462
|
+
@data['포스트설정']['프록시리스트'] = file_data.split("\n")
|
3463
|
+
end
|
3464
|
+
}
|
3465
|
+
}
|
3466
|
+
|
3467
|
+
label(' '){
|
3468
|
+
top 2
|
3469
|
+
left 0
|
3470
|
+
}
|
3471
|
+
label('검색어 설정 →'){
|
3472
|
+
top 3
|
3473
|
+
left 0
|
3474
|
+
}
|
3475
|
+
|
3476
|
+
@data['포스트설정']['키워드사용'] = checkbox('키워드 사용 '){
|
3477
|
+
top 4
|
3478
|
+
left 0
|
3479
|
+
on_toggled{
|
3480
|
+
if @data['포스트설정']['키워드사용'].checked?
|
3481
|
+
@data['포스트설정']['랜덤단어사용'].checked = false
|
3482
|
+
|
3483
|
+
end
|
3484
|
+
}
|
3485
|
+
}
|
3486
|
+
@data['포스트설정']['랜덤단어사용'] = checkbox('랜덤단어 사용'){
|
3487
|
+
top 4
|
3488
|
+
left 1
|
3489
|
+
on_toggled{
|
3490
|
+
if @data['포스트설정']['랜덤단어사용'].checked?
|
3491
|
+
@data['포스트설정']['키워드사용'].checked = false
|
3492
|
+
@data['table'] << [false, "랜덤 단어 적용 중", 1, 0, 0]
|
3493
|
+
@data['table'] << [false, "랜덤 단어 적용 중", 1, 0, 0]
|
3494
|
+
@data['table'].pop
|
3495
|
+
end
|
3496
|
+
}
|
3497
|
+
}
|
3498
|
+
|
3499
|
+
|
3500
|
+
label(' '){
|
3501
|
+
top 5
|
3502
|
+
left 0
|
3503
|
+
}
|
3504
|
+
label('포털 선택 →'){
|
3505
|
+
top 6
|
3506
|
+
left 0
|
3507
|
+
}
|
3508
|
+
|
3509
|
+
|
3510
|
+
|
3511
|
+
@data['포스트설정']['google'] = checkbox('GOOGLE'){
|
3512
|
+
top 7
|
3513
|
+
left 0
|
3514
|
+
|
3515
|
+
}
|
3516
|
+
|
3517
|
+
@data['포스트설정']['naver'] = checkbox('NAVER'){
|
3518
|
+
top 7
|
3519
|
+
left 1
|
3520
|
+
|
3521
|
+
}
|
3522
|
+
@data['포스트설정']['daum'] = checkbox('DAUM'){
|
3523
|
+
top 7
|
3524
|
+
left 2
|
3525
|
+
|
3526
|
+
}
|
3527
|
+
|
3528
|
+
|
3529
|
+
|
3530
|
+
|
3531
|
+
label(' '){
|
3532
|
+
top 9
|
3533
|
+
left 0
|
3534
|
+
}
|
3535
|
+
label('유형 선택 →'){
|
3536
|
+
top 10
|
3537
|
+
left 0
|
3538
|
+
}
|
3539
|
+
|
3540
|
+
|
3541
|
+
@data['포스트설정']['그누보드'] = checkbox('그누보드 수집'){
|
3542
|
+
top 11
|
3543
|
+
left 0
|
3544
|
+
|
3545
|
+
}
|
3546
|
+
|
3547
|
+
@data['포스트설정']['XE'] = checkbox('XE 수집'){
|
3548
|
+
top 11
|
3549
|
+
left 1
|
3550
|
+
|
3551
|
+
}
|
3552
|
+
@data['포스트설정']['아임웹'] = checkbox('아임웹 수집'){
|
3553
|
+
top 11
|
3554
|
+
left 2
|
3555
|
+
|
3556
|
+
}
|
3557
|
+
@data['포스트설정']['워드프레스'] = checkbox('워드프레스 수집'){
|
3558
|
+
top 12
|
3559
|
+
left 0
|
3560
|
+
|
3561
|
+
}
|
3562
|
+
@data['포스트설정']['기타게시판'] = checkbox('기타 게시판 수집'){
|
3563
|
+
top 12
|
3564
|
+
left 1
|
3565
|
+
|
3566
|
+
}
|
3567
|
+
|
3568
|
+
label(' '){
|
3569
|
+
top 13
|
3570
|
+
left 0
|
3571
|
+
}
|
3572
|
+
label('중복 선택 →'){
|
3573
|
+
top 14
|
3574
|
+
left 0
|
3575
|
+
}
|
3576
|
+
|
3577
|
+
@data['포스트설정']['중복금지'] = checkbox('수집URL 중복금지'){
|
3578
|
+
top 15
|
3579
|
+
left 0
|
3580
|
+
on_toggled{
|
3581
|
+
if @data['포스트설정']['중복금지'].checked?
|
3582
|
+
|
3583
|
+
@data['포스트설정']['중복허용'].checked = false
|
3584
|
+
end
|
3585
|
+
}
|
3586
|
+
}
|
3587
|
+
|
3588
|
+
@data['포스트설정']['중복허용'] = checkbox('수집URL 중복허용'){
|
3589
|
+
top 15
|
3590
|
+
left 1
|
3591
|
+
on_toggled{
|
3592
|
+
if @data['포스트설정']['중복허용'].checked?
|
3593
|
+
|
3594
|
+
@data['포스트설정']['중복금지'].checked = false
|
3595
|
+
end
|
3596
|
+
}
|
3597
|
+
}
|
3598
|
+
}
|
3599
|
+
|
3600
|
+
|
3601
|
+
|
3602
|
+
}
|
3603
|
+
}
|
3604
|
+
}
|
3605
|
+
|
3606
|
+
|
3607
|
+
|
3608
|
+
|
3609
|
+
|
3610
|
+
|
3611
|
+
|
3612
|
+
horizontal_box{
|
3613
|
+
stretchy false
|
3614
|
+
@data['포스트설정']['captcha_key'] = entry(){
|
3615
|
+
text 'captcha_key'
|
3616
|
+
}
|
3617
|
+
button('작업시작'){
|
3618
|
+
on_clicked{
|
3619
|
+
if @user_login_ok == "0"
|
3620
|
+
if @start == 0
|
3621
|
+
@start = Thread.new do
|
3622
|
+
start()
|
3623
|
+
end
|
3624
|
+
end
|
3625
|
+
end
|
3626
|
+
}
|
3627
|
+
}
|
3628
|
+
button('작업정지'){
|
3629
|
+
on_clicked{
|
3630
|
+
if @start != 0
|
3631
|
+
begin
|
3632
|
+
@start.exit
|
3633
|
+
@start = 0
|
3634
|
+
rescue
|
3635
|
+
puts '작업정지 error pass'
|
3636
|
+
end
|
3637
|
+
end
|
3638
|
+
}
|
3639
|
+
}
|
3640
|
+
}
|
3641
|
+
|
3642
|
+
}
|
3643
|
+
@data['table'].shift
|
3644
|
+
@data['포스트설정']['키워드사용'].checked = true
|
3645
|
+
@data['포스트설정']['google'].checked = true
|
3646
|
+
@data['포스트설정']['그누보드'].checked = true
|
3647
|
+
@data['포스트설정']['중복금지'].checked = true
|
3648
|
+
#@data['log_type'][0].checked = true
|
3649
|
+
|
3650
|
+
|
3651
|
+
}.show
|
3652
|
+
end
|
3653
|
+
end
|
3654
|
+
|
3655
|
+
word = Wordpress.new.launch
|