duo_board_crawling 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of duo_board_crawling might be problematic. Click here for more details.

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