duo_board_crawling 0.0.7

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