duo_cafe_comment 0.0.50 → 0.0.52

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/duo_cafe_comment.rb +2289 -609
  3. metadata +2 -2
@@ -219,19 +219,29 @@ class Naver
219
219
  begin
220
220
  wait = Selenium::WebDriver::Wait.new(:timeout => 7)
221
221
  #요소가 나타날 때까지 3초 동안 기다립니다.
222
- wait.until { @driver.find_element(:xpath, '//*[@for="switch"]') }
223
- sleep(1.5)
224
- @driver.find_element(:xpath, '//*[@id="login_keep_wrap"]/div[1]/label').click
225
- sleep(1.5)
226
- @driver.find_element(:xpath, '//*[@id="id"]').click
222
+ wait.until { @driver.find_element(:xpath, '//*[@id="id" and @name="id"]') }
223
+ @driver.find_element(:xpath, '//*[@id="id" and @name="id"]').click
227
224
  Clipboard.copy(user_id)
228
225
  @driver.action.key_down(:control).send_keys('v').key_up(:control).perform
229
226
  sleep(1.5)
230
- @driver.find_element(:xpath, '//*[@id="pw"]').click
227
+ @driver.find_element(:xpath, '//*[@id="pw" and @name="pw"]').click
231
228
  Clipboard.copy(user_pw)
232
229
  @driver.action.key_down(:control).send_keys('v').key_up(:control).perform
233
230
  sleep(1.5)
234
- @driver.find_element(:xpath, '//*[@id="log.login"]').click
231
+
232
+ begin
233
+ smart_level_value = @driver.find_element(id: 'smart_LEVEL').attribute('value')
234
+ if smart_level_value == '1'
235
+ @driver.find_element(xpath: '//label[@for="switch" and @class="switch_btn"]').click
236
+ sleep(1.5)
237
+ end
238
+ rescue
239
+ end
240
+
241
+ wait = Selenium::WebDriver::Wait.new(:timeout => 3)
242
+ #요소가 나타날 때까지 3초 동안 기다립니다.
243
+ wait.until { @driver.find_element(xpath: '//button[@type="submit" and @id="log.login"]') }
244
+ @driver.find_element(xpath: '//button[@type="submit" and @id="log.login"]').click
235
245
  sleep(2.5)
236
246
  rescue => e
237
247
  puts '-[√] 로딩 지연 접속 실패.......'.red
@@ -253,9 +263,9 @@ class Naver
253
263
  end
254
264
 
255
265
  begin
256
- wait = Selenium::WebDriver::Wait.new(:timeout => 3)
266
+ wait = Selenium::WebDriver::Wait.new(:timeout => 5)
257
267
  #요소가 나타날 때까지 3초 동안 기다립니다.
258
- wait.until { @driver.find_element(:xpath, '//*[@class="MyView-module__btn_logout___bsTOJ"]') }
268
+ wait.until { @driver.find_element(:xpath, '//*[@type="button" and @class="MyView-module__btn_logout___bsTOJ"]') }
259
269
 
260
270
  rescue => e
261
271
  puts '-[√] 로그인 실패.......'.red
@@ -493,36 +503,7 @@ class Naver
493
503
  sleep(1)
494
504
  @driver.switch_to.frame(@driver.find_element(:xpath, '//*[@id="cafe_main"]')) # 아이프레임 선택
495
505
 
496
- if @data['포스트설정']['순서사용2'].checked?
497
- @content_soon ||= 0 # 초기 한 번만 0으로 세팅
498
-
499
- if @data['내용설정']['내용'].nil? || @data['내용설정']['내용'].empty?
500
- content = ''
501
- else
502
- if @data.dig('내용설정', '랜덤사용')&.respond_to?(:checked?) && @data['내용설정']['랜덤사용'].checked?
503
- content = @data['내용설정']['내용'].sample[2]
504
- else
505
- content = @data['내용설정']['내용'][@content_soon][2]
506
- @content_soon += 1
507
- @content_soon = 0 if @content_soon >= @data['내용설정']['내용'].length
508
- end
509
- end
510
- else
511
- end
512
-
513
- # 디엠 자동 변경이 체크된 경우 content를 변환
514
- if @data['포스트설정']['내용자동변경'].checked?
515
- change_memory = {}
516
- @data['포스트설정']['내용자동변경값'].each do |key, v|
517
- change_memory[key] = v.sample
518
- end
519
- @data['포스트설정']['내용자동변경값'].each do |key, _|
520
- if content.include?(key)
521
- content = content.gsub(key, change_memory[key]) # gsub을 사용하여 내용 치환
522
- else
523
- end
524
- end
525
- end
506
+
526
507
 
527
508
  if option['좋아요'] == 'true'
528
509
  puts "좋아요 클릭 옵션 진행!!".cyan
@@ -551,363 +532,1474 @@ class Naver
551
532
  else
552
533
  end
553
534
 
554
-
555
- begin
556
- wait = Selenium::WebDriver::Wait.new(:timeout => 10)
557
- wait.until { @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]') }
558
-
559
- # 댓글 입력
560
- element = @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]')
561
- @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element)#크롤 이동
562
- sleep(1)
563
- if option['ChatGPT사용'] == 'true'
564
- pcol1 = @driver.find_element(:css, 'div.title_area > h3.title_text').text
565
- sleep(1)
566
-
567
- puts "ChatGPT로 댓글을 만드는 중입니다."
568
- @api_key = api_key
569
- url = 'https://api.openai.com/v1/chat/completions'
570
- headers = {
571
- 'Content-Type' => 'application/json',
572
- 'Authorization' => 'Bearer ' + @api_key
573
- }
574
- data = {
575
- 'model' => 'gpt-3.5-turbo',
576
- 'messages' => [
577
- { "role" => "system", "content" => "해당 제목에 알맞은 댓글을 짧게 한 개만 만들어줘" },
578
- { "role" => "user", "content" => pcol1 } # pcol1 직접 사용
579
- ]
580
- }
581
-
582
- begin
583
- req = HTTP.headers(headers).post(url, json: data)
584
- puts "HTTP Status: #{req.status}" # 상태 코드 확인
585
- response = JSON.parse(req.body.to_s)
586
- puts "API Response: #{response}" # 전체 응답 출력
587
-
588
- if req.status == 429
589
- return "API 요청 제한을 초과했습니다. 플랜 및 할당량을 확인하세요."
590
- end
591
535
 
592
- # 응답 데이터에서 안전하게 값 추출
593
- raw_answer = response.dig('choices', 0, 'message', 'content') || "댓글 생성을 실패했습니다." # 응답이 없을 경우 기본 메시지 설정
594
- answer = raw_answer.gsub(/\. /, ".\n") # 줄바꿈 추가
595
536
 
596
- rescue => e
597
- puts "Error: #{e.message}"
598
- answer = "오류가 발생했습니다."
599
- end
600
-
601
- # 댓글 입력
602
- @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]').send_keys(answer)
603
- sleep(1)
604
- else
605
- begin
606
- puts (content)
607
- @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]').send_keys(content)
608
- sleep(1)
609
- rescue
610
- end
611
- end
612
-
613
- # 이모티콘 자동 삽입
614
- if option['이모티콘자동삽입'] == 'true'
615
- puts "이모티콘 자동 삽입 옵션 진행!!".cyan
616
-
617
- # '이모티콘' 버튼 클릭
618
- @driver.find_element(:xpath, '//*[@class="button_sticker"]').click
619
- sleep(1)
620
-
537
+ if option['re_coment'] == 'true' # 대 댓글 작업때
538
+ if @data['포스트설정']['전체대댓글'].checked?
621
539
  begin
622
- # 'se2_line_sticker_set' 클래스를 가진 <ul> 요소 안의 모든 <li> 요소 찾기
623
- sticker_list_elements = wait.until { @driver.find_elements(:css, '.se2_line_sticker_set li') }
624
-
625
- # 16개 <li> 요소 중 랜덤으로 하나 선택하여 클릭
626
- random_li = sticker_list_elements.sample
627
- random_button = random_li.find_element(:tag_name, 'button') # <button> 태그 찾기
628
- random_button.click
629
-
630
- sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
631
-
632
- # 첫 번째 클릭한 <li> 내에서 버튼을 찾기
633
- inner_buttons = random_li.find_elements(:tag_name, 'button')
634
-
635
- # 20개 <button> 요소 중 랜덤으로 하나 선택하여 클릭
636
- random_button_in_li = inner_buttons.sample
637
- sleep(1)
638
- random_button_in_li.click
639
-
640
- sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
641
-
642
- rescue Selenium::WebDriver::Error::StaleElementReferenceError => e
643
- #puts "Stale element reference 오류 발생, 계속 진행: #{e.message}".yellow
644
- # 오류 발생 시에도 계속 진행하려면 작업을 계속하도록 처리
645
- # 예를 들어, continue, or next 등으로 다음 단계로 넘어갈 수 있습니다.
646
-
647
- rescue => e
648
- puts "기타 오류로 인해 이모티콘 삽입 안됨"
649
- # 기타 오류 처리
650
- # 여기에 추가적인 예외 처리 로직을 넣을 수 있습니다.
651
- end
652
- else
653
- puts "이모티콘 자동 삽입 옵션이 비활성화됨."
654
- end
655
-
656
- # 이미지 자동 삽입
657
- if option['이미지자동삽입'] == 'true'
658
- puts "이미지 자동 상입 옵션 진행!!".cyan
659
-
660
- # 아이프레임 요소가 나타날 때까지 기다립니다.
661
- @image = image
662
- image_path = image
663
-
664
- @driver.find_element(:xpath, '//*[@for="attach2"]').click
665
- sleep(1)
666
- key_stroke('escape')
667
- # 파일 경로 자동 입력
668
- file_input = @driver.find_element(:xpath, '//*[@id="attach2"]')
669
-
670
- # send_keys로 파일 경로를 입력하여 이미지 업로드
671
- file_input.send_keys(image_path)
672
- sleep(2)
673
-
674
- else
675
- end
676
-
677
- wait.until { @driver.find_element(:xpath, '//*[@class="button btn_register is_active"]') }
678
- @driver.find_element(:xpath, '//*[@class="button btn_register is_active"]').click
679
- puts "#{board_url} [댓글 작성 완료 !!]".cyan
680
-
681
- sleep(2)
682
- begin
683
- @driver.switch_to.alert
684
- sleep(1)
685
- error_text = @driver.switch_to.alert.text
686
- sleep(1)
687
- @driver.switch_to.alert.accept
688
- puts (error_text).red
689
- posting_url = @driver.current_url
690
-
691
- File.open('./log/posting_log.txt', 'a') do |ff|
692
- ff.write('[')
693
- ff.write(DateTime.now.strftime("%Y년%m월%d일%H시%M분"))
694
- ff.write(']')
695
- ff.write(' ')
696
- ff.write('【등록실패:')
697
- ff.write(error_text)
698
- ff.write('】')
699
- ff.write(' ')
700
- ff.write(posting_url)
701
- ff.close()
702
- puts '-[√] 로그 파일 생성 완료.......'.yellow
703
- end
704
-
705
- rescue
706
- #@driver.execute_script("document.body.style.zoom = '1.00'")
707
- sleep(1)
708
- posting_url = @driver.current_url
709
-
710
- File.open('./log/posting_log.txt', 'a') do |ff|
711
- ff.write('[')
712
- ff.write(DateTime.now.strftime("%Y년%m월%d일%H시%M분"))
713
- ff.write(']')
714
- ff.write(' ')
715
- ff.write('【등록성공확인】')
716
- ff.write(' ')
717
- ff.write(posting_url)
718
- ff.write("\n")
719
- ff.close()
720
- puts '-[√] 로그 파일 생성 완료.......'.yellow
721
- end
722
- end
723
- end
724
- @driver.switch_to.default_content() # 아이프레임 해제
725
- def sleep_with_progress(sleep_delay)
726
- print "[설정 딜레이 진행 중] "
727
- steps = (sleep_delay.to_f / 0.5).to_i
728
- steps.times do
729
- print "."
730
- STDOUT.flush
731
- sleep(1)
732
- end
733
- puts "\n"
734
- end
540
+ comment_items = @driver.find_elements(:css, 'li.CommentItem')
541
+ original_comments = comment_items.select { |item| !item.attribute('class').include?('CommentItem--reply') }
735
542
 
736
- sleep_with_progress(sleep_delay)
737
-
543
+ original_comments.each_with_index do |item, index|
738
544
 
739
- rescue => e
740
- puts "Error: #{e.message}"
741
- end
742
- end
743
- else
744
- end
745
-
746
- ################################################################################ 설정게시글사용 ################################################################################
545
+ begin
747
546
 
748
- if option['설정게시글사용'] == 'true'
749
- puts "게시판 list 기반으로 댓글 작업 옵션 진행!!".cyan
750
-
751
- @driver.get(board_url) # 해당 URL로 이동
752
- begin
753
- # 아이프레임 요소가 나타날 때까지 기다립니다.
754
- wait = Selenium::WebDriver::Wait.new(:timeout => 20) # 아이프레임 선택
755
- wait.until { @driver.find_element(:xpath, '//*[@id="cafe_main"]') } # 아이프레임 선택
756
- sleep(1)
757
- @driver.switch_to.frame(@driver.find_element(:xpath, '//*[@id="cafe_main"]')) # 아이프레임 선택
758
-
759
- if @data['포스트설정']['순서사용2'].checked?
760
- @content_soon ||= 0 # 초기 한 번만 0으로 세팅
547
+ if @data['포스트설정']['순서사용2'].checked?
548
+ @content_soon ||= 0 # 초기 번만 0으로 세팅
761
549
 
762
- if @data['내용설정']['내용'].nil? || @data['내용설정']['내용'].empty?
763
- content = ''
764
- else
765
- if @data.dig('내용설정', '랜덤사용')&.respond_to?(:checked?) && @data['내용설정']['랜덤사용'].checked?
766
- content = @data['내용설정']['내용'].sample[2]
767
- else
768
- content = @data['내용설정']['내용'][@content_soon][2]
769
- @content_soon += 1
770
- @content_soon = 0 if @content_soon >= @data['내용설정']['내용'].length
771
- end
772
- end
773
- else
774
- end
775
-
776
- # 디엠 자동 변경이 체크된 경우 content를 변환
777
- if @data['포스트설정']['내용자동변경'].checked?
778
- change_memory = {}
779
- @data['포스트설정']['내용자동변경값'].each do |key, v|
780
- change_memory[key] = v.sample
781
- end
782
- @data['포스트설정']['내용자동변경값'].each do |key, _|
783
- if content.include?(key)
784
- content = content.gsub(key, change_memory[key]) # gsub을 사용하여 내용 치환
785
- else
786
- end
787
- end
788
- end
550
+ if @data['내용설정']['내용'].nil? || @data['내용설정']['내용'].empty?
551
+ content = ''
552
+ else
553
+ if @data.dig('내용설정', '랜덤사용')&.respond_to?(:checked?) && @data['내용설정']['랜덤사용'].checked?
554
+ content = @data['내용설정']['내용'].sample[2]
555
+ else
556
+ content = @data['내용설정']['내용'][@content_soon][2]
557
+ @content_soon += 1
558
+ @content_soon = 0 if @content_soon >= @data['내용설정']['내용'].length
559
+ end
560
+ end
561
+ else
562
+ end
563
+
564
+ # 디엠 자동 변경이 체크된 경우 content를 변환
565
+ if @data['포스트설정']['내용자동변경'].checked?
566
+ change_memory = {}
567
+ @data['포스트설정']['내용자동변경값'].each do |key, v|
568
+ change_memory[key] = v.sample
569
+ end
570
+ @data['포스트설정']['내용자동변경값'].each do |key, _|
571
+ if content.include?(key)
572
+ content = content.gsub(key, change_memory[key]) # gsub을 사용하여 내용 치환
573
+ else
574
+ end
575
+ end
576
+ end
789
577
 
578
+ if option['ChatGPT사용'] == 'true'
579
+ pcol1 = @driver.find_element(:css, 'div.title_area > h3.title_text').text
580
+ sleep(1)
581
+
582
+ puts "ChatGPT로 댓글을 만드는 중입니다."
583
+ @api_key = api_key
584
+ url = 'https://api.openai.com/v1/chat/completions'
585
+ headers = {
586
+ 'Content-Type' => 'application/json',
587
+ 'Authorization' => 'Bearer ' + @api_key
588
+ }
589
+ data = {
590
+ 'model' => 'gpt-3.5-turbo',
591
+ 'messages' => [
592
+ { "role" => "system", "content" => "해당 제목에 알맞은 댓글을 짧게 한 개만 만들어줘" },
593
+ { "role" => "user", "content" => pcol1 } # pcol1 직접 사용
594
+ ]
595
+ }
596
+
597
+ begin
598
+ req = HTTP.headers(headers).post(url, json: data)
599
+ puts "HTTP Status: #{req.status}" # 상태 코드 확인
600
+ response = JSON.parse(req.body.to_s)
601
+ puts "API Response: #{response}" # 전체 응답 출력
602
+
603
+ if req.status == 429
604
+ return "API 요청 제한을 초과했습니다. 플랜 및 할당량을 확인하세요."
605
+ end
606
+
607
+ # 응답 데이터에서 안전하게 값 추출
608
+ raw_content = response.dig('choices', 0, 'message', 'content') || "댓글 생성을 실패했습니다." # 응답이 없을 경우 기본 메시지 설정
609
+ content = raw_content.gsub(/\. /, ".\n") # 줄바꿈 추가
610
+
611
+ rescue => e
612
+ puts "Error: #{e.message}"
613
+ content = "오류가 발생했습니다."
614
+ end
615
+ else
616
+ end
790
617
 
791
- if option['좋아요'] == 'true'
792
- puts "좋아요 클릭 옵션 진행!!".cyan
793
- wait = Selenium::WebDriver::Wait.new(:timeout => 10)
794
- wait.until { @driver.find_element(:xpath, '//*[@class="u_ico _icon"]') }
795
-
796
- # 댓글 입력
797
- element = @driver.find_element(:xpath, '//*[@class="u_ico _icon"]')
798
- @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element)#크롤 이동
799
- sleep(1)
800
-
801
- # 좋아요 버튼을 찾기
802
- like_button = @driver.find_element(:xpath, '//div[@class="ReactionLikeIt u_likeit_list_module _cafeReactionModule"]//a[@role="button"]')
803
-
804
- # aria-pressed 속성 값 확인
805
- aria_pressed = like_button.attribute('aria-pressed')
806
-
807
- if aria_pressed == 'true'
808
- # 이미 좋아요를 누른 상태일 경우
809
-
810
- else
811
- # 좋아요를 아직 누르지 않은 상태일 경우 클릭
812
- @driver.find_element(:xpath, '//*[@class="u_ico _icon"]').click
813
- sleep(2)
814
- end
815
- else
816
- end
817
-
818
-
819
- begin
820
- wait = Selenium::WebDriver::Wait.new(:timeout => 10)
821
- wait.until { @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]') }
618
+ reply_button = item.find_element(:css, 'a.comment_info_button')
619
+ puts "대댓글 #{index + 1} 작성 중..."
620
+ reply_button.click
621
+ sleep(1.5)
622
+
623
+ textarea = @driver.find_element(:css, 'textarea.comment_inbox_text')
624
+ textarea.send_keys(content)
625
+ sleep(1)
626
+
627
+ if option['이모티콘자동삽입'] == 'true'
628
+ puts "이모티콘 자동 삽입 옵션 진행!!".cyan
629
+ reply_comments = @driver.find_elements(:css, 'li.CommentItem.CommentItem--reply')
630
+ reply_comments.each_with_index do |item, index|
631
+ begin
632
+
633
+
634
+ # 해당 대댓글 내부의 이모티콘 버튼 찾기
635
+ sticker_button = item.find_element(:css, 'a.button_sticker')
636
+ sticker_button.click
637
+ sleep(1)
638
+
639
+ rescue
640
+ end
641
+ end
642
+ begin
643
+ # 'se2_line_sticker_set' 클래스를 가진 <ul> 요소 안의 모든 <li> 요소 찾기
644
+ sticker_list_elements = wait.until { @driver.find_elements(:css, '.se2_line_sticker_set li') }
645
+
646
+ # 16개 <li> 요소 중 랜덤으로 하나 선택하여 클릭
647
+ random_li = sticker_list_elements.sample
648
+ random_button = random_li.find_element(:tag_name, 'button') # <button> 태그 찾기
649
+ random_button.click
650
+
651
+ sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
652
+
653
+ # 첫 번째 클릭한 <li> 내에서 버튼을 찾기
654
+ inner_buttons = random_li.find_elements(:tag_name, 'button')
655
+
656
+ # 20개 <button> 요소 중 랜덤으로 하나 선택하여 클릭
657
+ random_button_in_li = inner_buttons.sample
658
+ sleep(1)
659
+ random_button_in_li.click
660
+
661
+ sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
662
+
663
+ rescue Selenium::WebDriver::Error::StaleElementReferenceError => e
664
+ #puts "Stale element reference 오류 발생, 계속 진행: #{e.message}".yellow
665
+ # 오류 발생 시에도 계속 진행하려면 작업을 계속하도록 처리
666
+ # 예를 들어, continue, or next 등으로 다음 단계로 넘어갈 수 있습니다.
667
+
668
+ rescue => e
669
+ puts "기타 오류로 인해 이모티콘 삽입 안됨"
670
+ # 기타 오류 처리
671
+ # 여기에 추가적인 예외 처리 로직을 넣을 수 있습니다.
672
+ end
673
+ else
674
+ puts "이모티콘 자동 삽입 옵션이 비활성화됨."
675
+ end
822
676
 
823
- # 댓글 입력
824
- element = @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]')
825
- @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element)#크롤 이동
826
- sleep(1)
827
- if option['ChatGPT사용'] == 'true'
828
- pcol1 = @driver.find_element(:css, 'div.title_area > h3.title_text').text
829
- sleep(1)
830
-
831
- puts "ChatGPT로 댓글을 만드는 중입니다."
832
- @api_key = api_key
833
- url = 'https://api.openai.com/v1/chat/completions'
834
- headers = {
835
- 'Content-Type' => 'application/json',
836
- 'Authorization' => 'Bearer ' + @api_key
837
- }
838
- data = {
839
- 'model' => 'gpt-3.5-turbo',
840
- 'messages' => [
841
- { "role" => "system", "content" => "해당 제목에 알맞은 댓글을 짧게 한 개만 만들어줘" },
842
- { "role" => "user", "content" => pcol1 } # pcol1 직접 사용
843
- ]
844
- }
845
-
846
- begin
847
- req = HTTP.headers(headers).post(url, json: data)
848
- puts "HTTP Status: #{req.status}" # 상태 코드 확인
849
- response = JSON.parse(req.body.to_s)
850
- puts "API Response: #{response}" # 전체 응답 출력
851
-
852
- if req.status == 429
853
- return "API 요청 제한을 초과했습니다. 플랜 및 할당량을 확인하세요."
854
- end
855
-
856
- # 응답 데이터에서 안전하게 값 추출
857
- raw_answer = response.dig('choices', 0, 'message', 'content') || "댓글 생성을 실패했습니다." # 응답이 없을 경우 기본 메시지 설정
858
- answer = raw_answer.gsub(/\. /, ".\n") # 줄바꿈 추가
859
-
677
+ # 이미지 자동 삽입
678
+ if option['이미지자동삽입'] == 'true'
679
+ puts "이미지 자동 상입 옵션 진행!!".cyan
680
+
681
+ # 아이프레임 요소가 나타날 때까지 기다립니다.
682
+ @image = image
683
+ image_path = image
684
+ reply_comments = @driver.find_elements(:css, 'li.CommentItem.CommentItem--reply')
685
+
686
+ reply_comments.each_with_index do |item, index|
687
+ begin
688
+
689
+
690
+ # 해당 대댓글 내부에서 for="attach2"인 라벨 클릭
691
+ attach_button = item.find_element(:xpath, './/*[@class="button_file"]')
692
+ attach_button.click
693
+ sleep(1)
694
+
695
+ rescue
696
+ end
697
+ end
698
+ key_stroke('escape')
699
+ # 파일 경로 자동 입력
700
+ file_input = @driver.find_element(:xpath, '//*[@title="사진첨부"]')
701
+
702
+ # send_keys로 파일 경로를 입력하여 이미지 업로드
703
+ file_input.send_keys(image_path)
704
+ sleep(2)
705
+
706
+ else
707
+ end
708
+
709
+ register_btn = @driver.find_element(:css, 'a.button.btn_register')
710
+ register_btn.click
711
+ sleep(2)
712
+
860
713
  rescue => e
861
- puts "Error: #{e.message}"
862
- answer = "오류가 발생했습니다."
863
- end
864
-
865
- # 댓글 입력
866
- @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]').send_keys(answer)
867
- sleep(1)
868
- else
869
- begin
870
- puts (content)
871
- @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]').send_keys(content)
872
- sleep(1)
873
- rescue
714
+ puts "대댓글 #{index + 1} 처리 중 오류 발생: #{e.message}"
715
+ next
716
+ end
874
717
  end
875
- end
876
-
877
- # 이모티콘 자동 삽입
878
- if option['이모티콘자동삽입'] == 'true'
879
- puts "이모티콘 자동 삽입 옵션 진행!!".cyan
718
+ rescue => e
719
+ puts "전체대댓글 처리 중 예외 발생: #{e.message}"
720
+ end
721
+
722
+ elsif @data['포스트설정']['지정대댓글'].checked?
723
+ targets = @data['포스트설정']['nik_or_number'].text.to_s.force_encoding('utf-8').split(',').map(&:strip)
724
+ targets.each do |target|
725
+ if target.match?(/^\d+$/)
726
+ index = target.to_i - 1
727
+ comment_items = @driver.find_elements(:css, 'li.CommentItem')
728
+ original_comments = comment_items.select { |item| !item.attribute('class').include?('CommentItem--reply') }
729
+
730
+ if original_comments[index]
731
+ begin
732
+
733
+ if @data['포스트설정']['순서사용2'].checked?
734
+ @content_soon ||= 0 # 초기 한 번만 0으로 세팅
735
+
736
+ if @data['내용설정']['내용'].nil? || @data['내용설정']['내용'].empty?
737
+ content = ''
738
+ else
739
+ if @data.dig('내용설정', '랜덤사용')&.respond_to?(:checked?) && @data['내용설정']['랜덤사용'].checked?
740
+ content = @data['내용설정']['내용'].sample[2]
741
+ else
742
+ content = @data['내용설정']['내용'][@content_soon][2]
743
+ @content_soon += 1
744
+ @content_soon = 0 if @content_soon >= @data['내용설정']['내용'].length
745
+ end
746
+ end
747
+ else
748
+ end
749
+
750
+ # 디엠 자동 변경이 체크된 경우 content를 변환
751
+ if @data['포스트설정']['내용자동변경'].checked?
752
+ change_memory = {}
753
+ @data['포스트설정']['내용자동변경값'].each do |key, v|
754
+ change_memory[key] = v.sample
755
+ end
756
+ @data['포스트설정']['내용자동변경값'].each do |key, _|
757
+ if content.include?(key)
758
+ content = content.gsub(key, change_memory[key]) # gsub을 사용하여 내용 치환
759
+ else
760
+ end
761
+ end
762
+ end
763
+
764
+ if option['ChatGPT사용'] == 'true'
765
+ pcol1 = @driver.find_element(:css, 'div.title_area > h3.title_text').text
766
+ sleep(1)
767
+
768
+ puts "ChatGPT로 댓글을 만드는 중입니다."
769
+ @api_key = api_key
770
+ url = 'https://api.openai.com/v1/chat/completions'
771
+ headers = {
772
+ 'Content-Type' => 'application/json',
773
+ 'Authorization' => 'Bearer ' + @api_key
774
+ }
775
+ data = {
776
+ 'model' => 'gpt-3.5-turbo',
777
+ 'messages' => [
778
+ { "role" => "system", "content" => "해당 제목에 알맞은 댓글을 짧게 한 개만 만들어줘" },
779
+ { "role" => "user", "content" => pcol1 } # pcol1 직접 사용
780
+ ]
781
+ }
782
+
783
+ begin
784
+ req = HTTP.headers(headers).post(url, json: data)
785
+ puts "HTTP Status: #{req.status}" # 상태 코드 확인
786
+ response = JSON.parse(req.body.to_s)
787
+ puts "API Response: #{response}" # 전체 응답 출력
788
+
789
+ if req.status == 429
790
+ return "API 요청 제한을 초과했습니다. 플랜 및 할당량을 확인하세요."
791
+ end
792
+
793
+ # 응답 데이터에서 안전하게 값 추출
794
+ raw_content = response.dig('choices', 0, 'message', 'content') || "댓글 생성을 실패했습니다." # 응답이 없을 경우 기본 메시지 설정
795
+ content = raw_content.gsub(/\. /, ".\n") # 줄바꿈 추가
796
+
797
+ rescue => e
798
+ puts "Error: #{e.message}"
799
+ content = "오류가 발생했습니다."
800
+ end
801
+ else
802
+ end
803
+
804
+ puts "#{index + 1}번째 댓글에 대댓글 작성 시작"
805
+ reply_button = original_comments[index].find_element(:css, 'a.comment_info_button')
806
+ reply_button.click
807
+ sleep(1.5)
808
+
809
+ textarea = @driver.find_element(:css, 'textarea.comment_inbox_text')
810
+ textarea.send_keys(content)
811
+ sleep(1)
812
+
813
+ if option['이모티콘자동삽입'] == 'true'
814
+ puts "이모티콘 자동 삽입 옵션 진행!!".cyan
815
+ reply_comments = @driver.find_elements(:css, 'li.CommentItem.CommentItem--reply')
816
+ reply_comments.each_with_index do |item, index|
817
+ begin
818
+
819
+
820
+ # 해당 대댓글 내부의 이모티콘 버튼 찾기
821
+ sticker_button = item.find_element(:css, 'a.button_sticker')
822
+ sticker_button.click
823
+ sleep(1)
824
+
825
+ rescue
826
+ end
827
+ end
828
+
829
+ begin
830
+ # 'se2_line_sticker_set' 클래스를 가진 <ul> 요소 안의 모든 <li> 요소 찾기
831
+ sticker_list_elements = wait.until { @driver.find_elements(:css, '.se2_line_sticker_set li') }
832
+
833
+ # 16개 <li> 요소 중 랜덤으로 하나 선택하여 클릭
834
+ random_li = sticker_list_elements.sample
835
+ random_button = random_li.find_element(:tag_name, 'button') # <button> 태그 찾기
836
+ random_button.click
837
+
838
+ sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
839
+
840
+ # 첫 번째 클릭한 <li> 내에서 버튼을 찾기
841
+ inner_buttons = random_li.find_elements(:tag_name, 'button')
842
+
843
+ # 20개 <button> 요소 중 랜덤으로 하나 선택하여 클릭
844
+ random_button_in_li = inner_buttons.sample
845
+ sleep(1)
846
+ random_button_in_li.click
847
+
848
+ sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
849
+
850
+ rescue Selenium::WebDriver::Error::StaleElementReferenceError => e
851
+ #puts "Stale element reference 오류 발생, 계속 진행: #{e.message}".yellow
852
+ # 오류 발생 시에도 계속 진행하려면 작업을 계속하도록 처리
853
+ # 예를 들어, continue, or next 등으로 다음 단계로 넘어갈 수 있습니다.
854
+
855
+ rescue => e
856
+ puts "기타 오류로 인해 이모티콘 삽입 안됨"
857
+ # 기타 오류 처리
858
+ # 여기에 추가적인 예외 처리 로직을 넣을 수 있습니다.
859
+ end
860
+ else
861
+ puts "이모티콘 자동 삽입 옵션이 비활성화됨."
862
+ end
863
+
864
+ # 이미지 자동 삽입
865
+ if option['이미지자동삽입'] == 'true'
866
+ puts "이미지 자동 상입 옵션 진행!!".cyan
867
+
868
+ # 아이프레임 요소가 나타날 때까지 기다립니다.
869
+ @image = image
870
+ image_path = image
871
+ reply_comments = @driver.find_elements(:css, 'li.CommentItem.CommentItem--reply')
872
+
873
+ reply_comments.each_with_index do |item, index|
874
+ begin
875
+
876
+
877
+ # 해당 대댓글 내부에서 for="attach2"인 라벨 클릭
878
+ attach_button = item.find_element(:xpath, './/*[@class="button_file"]')
879
+ attach_button.click
880
+ sleep(1)
881
+
882
+ rescue
883
+ end
884
+ end
885
+ key_stroke('escape')
886
+ # 파일 경로 자동 입력
887
+ file_input = @driver.find_element(:xpath, '//*[@title="사진첨부"]')
888
+
889
+ # send_keys로 파일 경로를 입력하여 이미지 업로드
890
+ file_input.send_keys(image_path)
891
+ sleep(2)
892
+
893
+ else
894
+ end
895
+
896
+ register_btn = @driver.find_element(:css, 'a.button.btn_register')
897
+ register_btn.click
898
+ sleep(2)
899
+
900
+ puts "#{index + 1}번째 댓글에 대댓글 작성 완료"
901
+ rescue => e
902
+ puts "댓글 인덱스 #{index + 1} 처리 중 오류 발생: #{e.message}"
903
+ end
904
+ else
905
+ puts "해당 인덱스(#{index + 1})의 답글쓰기 버튼이 없습니다."
906
+ end
907
+
908
+ else # 닉네임으로 찾기
909
+ comment_items = @driver.find_elements(:css, 'li.CommentItem')
910
+ original_comments = comment_items.select { |item| !item.attribute('class').include?('CommentItem--reply') }
911
+
912
+ matched = false
913
+ last_matched_item = nil # 마지막에 닉네임이 일치한 댓글 저장
914
+
915
+ original_comments.each_with_index do |item, idx|
916
+ begin
917
+ nickname_element = item.find_element(:css, 'a.comment_nickname')
918
+ nickname = nickname_element.text.strip
919
+
920
+ if nickname.include?(target)
921
+ puts "#{target} 닉네임이 포함된 댓글 발견 (#{idx + 1}번째)"
922
+ last_matched_item = item # 매번 갱신 → 마지막에 발견된 걸 저장
923
+ end
924
+ rescue => e
925
+ puts "닉네임 검사 중 오류 발생: #{e.message}"
926
+ next
927
+ end
928
+ end
929
+
930
+ # 루프 끝난 뒤 마지막 댓글에만 작업 실행
931
+ if last_matched_item
932
+ begin
933
+
934
+ if @data['포스트설정']['순서사용2'].checked?
935
+ @content_soon ||= 0 # 초기 한 번만 0으로 세팅
936
+
937
+ if @data['내용설정']['내용'].nil? || @data['내용설정']['내용'].empty?
938
+ content = ''
939
+ else
940
+ if @data.dig('내용설정', '랜덤사용')&.respond_to?(:checked?) && @data['내용설정']['랜덤사용'].checked?
941
+ content = @data['내용설정']['내용'].sample[2]
942
+ else
943
+ content = @data['내용설정']['내용'][@content_soon][2]
944
+ @content_soon += 1
945
+ @content_soon = 0 if @content_soon >= @data['내용설정']['내용'].length
946
+ end
947
+ end
948
+ else
949
+ end
950
+
951
+ # 디엠 자동 변경이 체크된 경우 content를 변환
952
+ if @data['포스트설정']['내용자동변경'].checked?
953
+ change_memory = {}
954
+ @data['포스트설정']['내용자동변경값'].each do |key, v|
955
+ change_memory[key] = v.sample
956
+ end
957
+ @data['포스트설정']['내용자동변경값'].each do |key, _|
958
+ if content.include?(key)
959
+ content = content.gsub(key, change_memory[key]) # gsub을 사용하여 내용 치환
960
+ else
961
+ end
962
+ end
963
+ end
964
+
965
+ if option['ChatGPT사용'] == 'true'
966
+ pcol1 = @driver.find_element(:css, 'div.title_area > h3.title_text').text
967
+ sleep(1)
968
+
969
+ puts "ChatGPT로 댓글을 만드는 중입니다."
970
+ @api_key = api_key
971
+ url = 'https://api.openai.com/v1/chat/completions'
972
+ headers = {
973
+ 'Content-Type' => 'application/json',
974
+ 'Authorization' => 'Bearer ' + @api_key
975
+ }
976
+ data = {
977
+ 'model' => 'gpt-3.5-turbo',
978
+ 'messages' => [
979
+ { "role" => "system", "content" => "해당 제목에 알맞은 댓글을 짧게 한 개만 만들어줘" },
980
+ { "role" => "user", "content" => pcol1 } # pcol1 직접 사용
981
+ ]
982
+ }
983
+
984
+ begin
985
+ req = HTTP.headers(headers).post(url, json: data)
986
+ puts "HTTP Status: #{req.status}" # 상태 코드 확인
987
+ response = JSON.parse(req.body.to_s)
988
+ puts "API Response: #{response}" # 전체 응답 출력
989
+
990
+ if req.status == 429
991
+ return "API 요청 제한을 초과했습니다. 플랜 및 할당량을 확인하세요."
992
+ end
993
+
994
+ # 응답 데이터에서 안전하게 값 추출
995
+ raw_content = response.dig('choices', 0, 'message', 'content') || "댓글 생성을 실패했습니다." # 응답이 없을 경우 기본 메시지 설정
996
+ content = raw_content.gsub(/\. /, ".\n") # 줄바꿈 추가
997
+
998
+ rescue => e
999
+ puts "Error: #{e.message}"
1000
+ content = "오류가 발생했습니다."
1001
+ end
1002
+ else
1003
+ end
1004
+
1005
+ reply_button = last_matched_item.find_element(:css, 'a.comment_info_button')
1006
+ reply_button.click
1007
+ sleep(1.5)
1008
+
1009
+ textarea = @driver.find_element(:css, 'textarea.comment_inbox_text')
1010
+ textarea.send_keys(content)
1011
+ sleep(1)
1012
+
1013
+ if option['이모티콘자동삽입'] == 'true'
1014
+ puts "이모티콘 자동 삽입 옵션 진행!!".cyan
1015
+ reply_comments = @driver.find_elements(:css, 'li.CommentItem.CommentItem--reply')
1016
+ reply_comments.each_with_index do |item, index|
1017
+ begin
1018
+
1019
+ sticker_button = item.find_element(:css, 'a.button_sticker')
1020
+ sticker_button.click
1021
+ sleep(1)
1022
+ rescue
1023
+ end
1024
+ end
1025
+ begin
1026
+ sticker_list_elements = wait.until { @driver.find_elements(:css, '.se2_line_sticker_set li') }
1027
+ random_li = sticker_list_elements.sample
1028
+ random_button = random_li.find_element(:tag_name, 'button')
1029
+ random_button.click
1030
+ sleep(1)
1031
+ inner_buttons = random_li.find_elements(:tag_name, 'button')
1032
+ random_button_in_li = inner_buttons.sample
1033
+ sleep(1)
1034
+ random_button_in_li.click
1035
+ sleep(1)
1036
+ rescue Selenium::WebDriver::Error::StaleElementReferenceError
1037
+ rescue => e
1038
+ puts "기타 오류로 인해 이모티콘 삽입 안됨"
1039
+ end
1040
+ else
1041
+ puts "이모티콘 자동 삽입 옵션이 비활성화됨."
1042
+ end
1043
+
1044
+ if option['이미지자동삽입'] == 'true'
1045
+ puts "이미지 자동 삽입 옵션 진행!!".cyan
1046
+ @image = image
1047
+ image_path = image
1048
+ reply_comments = @driver.find_elements(:css, 'li.CommentItem.CommentItem--reply')
1049
+ reply_comments.each_with_index do |item, index|
1050
+ begin
1051
+
1052
+ attach_button = item.find_element(:xpath, './/*[@class="button_file"]')
1053
+ attach_button.click
1054
+ sleep(1)
1055
+ rescue
1056
+ end
1057
+ end
1058
+ key_stroke('escape')
1059
+ file_input = @driver.find_element(:xpath, '//*[@title="사진첨부"]')
1060
+ file_input.send_keys(image_path)
1061
+ sleep(2)
1062
+ end
1063
+
1064
+ register_btn = @driver.find_element(:css, 'a.button.btn_register')
1065
+ register_btn.click
1066
+ sleep(2)
1067
+
1068
+ matched = true
1069
+ rescue => e
1070
+ puts "대댓글 등록 중 오류 발생: #{e.message}"
1071
+ end
1072
+ end
1073
+
1074
+ puts "닉네임 '#{target}'을 포함한 댓글을 찾지 못했습니다." unless matched
1075
+
1076
+ end
1077
+ end
1078
+
1079
+ end
1080
+
1081
+ elsif option['re_coment'] == 'false' # 대 댓글 아닐때
1082
+ if @data['포스트설정']['순서사용2'].checked?
1083
+ @content_soon ||= 0 # 초기 한 번만 0으로 세팅
1084
+
1085
+ if @data['내용설정']['내용'].nil? || @data['내용설정']['내용'].empty?
1086
+ content = ''
1087
+ else
1088
+ if @data.dig('내용설정', '랜덤사용')&.respond_to?(:checked?) && @data['내용설정']['랜덤사용'].checked?
1089
+ content = @data['내용설정']['내용'].sample[2]
1090
+ else
1091
+ content = @data['내용설정']['내용'][@content_soon][2]
1092
+ @content_soon += 1
1093
+ @content_soon = 0 if @content_soon >= @data['내용설정']['내용'].length
1094
+ end
1095
+ end
1096
+ else
1097
+ end
1098
+
1099
+ # 디엠 자동 변경이 체크된 경우 content를 변환
1100
+ if @data['포스트설정']['내용자동변경'].checked?
1101
+ change_memory = {}
1102
+ @data['포스트설정']['내용자동변경값'].each do |key, v|
1103
+ change_memory[key] = v.sample
1104
+ end
1105
+ @data['포스트설정']['내용자동변경값'].each do |key, _|
1106
+ if content.include?(key)
1107
+ content = content.gsub(key, change_memory[key]) # gsub을 사용하여 내용 치환
1108
+ else
1109
+ end
1110
+ end
1111
+ end
1112
+
1113
+ if option['ChatGPT사용'] == 'true'
1114
+ pcol1 = @driver.find_element(:css, 'div.title_area > h3.title_text').text
1115
+ sleep(1)
1116
+
1117
+ puts "ChatGPT로 댓글을 만드는 중입니다."
1118
+ @api_key = api_key
1119
+ url = 'https://api.openai.com/v1/chat/completions'
1120
+ headers = {
1121
+ 'Content-Type' => 'application/json',
1122
+ 'Authorization' => 'Bearer ' + @api_key
1123
+ }
1124
+ data = {
1125
+ 'model' => 'gpt-3.5-turbo',
1126
+ 'messages' => [
1127
+ { "role" => "system", "content" => "해당 제목에 알맞은 댓글을 짧게 한 개만 만들어줘" },
1128
+ { "role" => "user", "content" => pcol1 } # pcol1 직접 사용
1129
+ ]
1130
+ }
1131
+
1132
+ begin
1133
+ req = HTTP.headers(headers).post(url, json: data)
1134
+ puts "HTTP Status: #{req.status}" # 상태 코드 확인
1135
+ response = JSON.parse(req.body.to_s)
1136
+ puts "API Response: #{response}" # 전체 응답 출력
1137
+
1138
+ if req.status == 429
1139
+ return "API 요청 제한을 초과했습니다. 플랜 및 할당량을 확인하세요."
1140
+ end
1141
+
1142
+ # 응답 데이터에서 안전하게 값 추출
1143
+ raw_content = response.dig('choices', 0, 'message', 'content') || "댓글 생성을 실패했습니다." # 응답이 없을 경우 기본 메시지 설정
1144
+ content = raw_content.gsub(/\. /, ".\n") # 줄바꿈 추가
1145
+
1146
+ rescue => e
1147
+ puts "Error: #{e.message}"
1148
+ content = "오류가 발생했습니다."
1149
+ end
1150
+ else
1151
+ end
1152
+
1153
+ wait = Selenium::WebDriver::Wait.new(timeout: 10)
1154
+ wait.until { @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]') }
1155
+
1156
+ element = @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]')
1157
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element)
1158
+ sleep(1)
1159
+
1160
+ element.send_keys(content)
1161
+ sleep(1)
1162
+
1163
+ # 이모티콘 자동 삽입
1164
+ if option['이모티콘자동삽입'] == 'true'
1165
+ puts "이모티콘 자동 삽입 옵션 진행!!".cyan
1166
+
1167
+ # '이모티콘' 버튼 클릭
1168
+ @driver.find_element(:xpath, '//*[@class="button_sticker"]').click
1169
+ sleep(1)
1170
+
1171
+ begin
1172
+ # 'se2_line_sticker_set' 클래스를 가진 <ul> 요소 안의 모든 <li> 요소 찾기
1173
+ sticker_list_elements = wait.until { @driver.find_elements(:css, '.se2_line_sticker_set li') }
1174
+
1175
+ # 16개 <li> 요소 중 랜덤으로 하나 선택하여 클릭
1176
+ random_li = sticker_list_elements.sample
1177
+ random_button = random_li.find_element(:tag_name, 'button') # <button> 태그 찾기
1178
+ random_button.click
1179
+
1180
+ sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
1181
+
1182
+ # 첫 번째 클릭한 <li> 내에서 버튼을 찾기
1183
+ inner_buttons = random_li.find_elements(:tag_name, 'button')
1184
+
1185
+ # 20개 <button> 요소 중 랜덤으로 하나 선택하여 클릭
1186
+ random_button_in_li = inner_buttons.sample
1187
+ sleep(1)
1188
+ random_button_in_li.click
1189
+
1190
+ sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
1191
+
1192
+ rescue Selenium::WebDriver::Error::StaleElementReferenceError => e
1193
+ #puts "Stale element reference 오류 발생, 계속 진행: #{e.message}".yellow
1194
+ # 오류 발생 시에도 계속 진행하려면 작업을 계속하도록 처리
1195
+ # 예를 들어, continue, or next 등으로 다음 단계로 넘어갈 수 있습니다.
1196
+
1197
+ rescue => e
1198
+ puts "기타 오류로 인해 이모티콘 삽입 안됨"
1199
+ # 기타 오류 처리
1200
+ # 여기에 추가적인 예외 처리 로직을 넣을 수 있습니다.
1201
+ end
1202
+ else
1203
+ puts "이모티콘 자동 삽입 옵션이 비활성화됨."
1204
+ end
1205
+
1206
+ # 이미지 자동 삽입
1207
+ if option['이미지자동삽입'] == 'true'
1208
+ puts "이미지 자동 상입 옵션 진행!!".cyan
1209
+
1210
+ # 아이프레임 요소가 나타날 때까지 기다립니다.
1211
+ @image = image
1212
+ image_path = image
1213
+
1214
+ @driver.find_element(:xpath, '//*[@for="attach2"]').click
1215
+ sleep(1)
1216
+ key_stroke('escape')
1217
+ # 파일 경로 자동 입력
1218
+ file_input = @driver.find_element(:xpath, '//*[@class="button_file"]')
1219
+
1220
+ # send_keys로 파일 경로를 입력하여 이미지 업로드
1221
+ file_input.send_keys(image_path)
1222
+ sleep(2)
880
1223
 
1224
+ else
1225
+ end
1226
+
1227
+
1228
+ wait.until { @driver.find_element(:xpath, '//*[@class="button btn_register is_active"]') }
1229
+ @driver.find_element(:xpath, '//*[@class="button btn_register is_active"]').click
1230
+ puts "#{board_url} [댓글 작성 완료 !!]".cyan
1231
+ sleep(2)
1232
+ end
1233
+
1234
+
1235
+
1236
+ begin
1237
+ @driver.switch_to.alert
1238
+ sleep(1)
1239
+ error_text = @driver.switch_to.alert.text
1240
+ sleep(1)
1241
+ @driver.switch_to.alert.accept
1242
+ puts (error_text).red
1243
+ posting_url = @driver.current_url
1244
+
1245
+ File.open('./log/posting_log.txt', 'a') do |ff|
1246
+ ff.write('[')
1247
+ ff.write(DateTime.now.strftime("%Y년%m월%d일%H시%M분"))
1248
+ ff.write(']')
1249
+ ff.write(' ')
1250
+ ff.write('【등록실패:')
1251
+ ff.write(error_text)
1252
+ ff.write('】')
1253
+ ff.write(' ')
1254
+ ff.write(posting_url)
1255
+ ff.close()
1256
+ puts '-[√] 로그 파일 생성 완료.......'.yellow
1257
+ end
1258
+
1259
+ rescue
1260
+ #@driver.execute_script("document.body.style.zoom = '1.00'")
1261
+ sleep(1)
1262
+ posting_url = @driver.current_url
1263
+
1264
+ File.open('./log/posting_log.txt', 'a') do |ff|
1265
+ ff.write('[')
1266
+ ff.write(DateTime.now.strftime("%Y년%m월%d일%H시%M분"))
1267
+ ff.write(']')
1268
+ ff.write(' ')
1269
+ ff.write('【등록성공확인】')
1270
+ ff.write(' ')
1271
+ ff.write(posting_url)
1272
+ ff.write("\n")
1273
+ ff.close()
1274
+ puts '-[√] 로그 파일 생성 완료.......'.yellow
1275
+ end
1276
+ end
1277
+
1278
+ @driver.switch_to.default_content() # 아이프레임 해제
1279
+ def sleep_with_progress(sleep_delay)
1280
+ print "[설정 딜레이 진행 중] "
1281
+ steps = (sleep_delay.to_f / 0.5).to_i
1282
+ steps.times do
1283
+ print "."
1284
+ STDOUT.flush
1285
+ sleep(1)
1286
+ end
1287
+ puts "\n"
1288
+ end
1289
+
1290
+ sleep_with_progress(sleep_delay)
1291
+
1292
+
1293
+ rescue => e
1294
+ puts "Error: #{e.message}"
1295
+ end
1296
+ end
1297
+ else
1298
+ end
1299
+
1300
+ ################################################################################ 설정게시글사용 ################################################################################
1301
+
1302
+ if option['설정게시글사용'] == 'true'
1303
+ puts "게시판 list 기반으로 댓글 작업 옵션 진행!!".cyan
1304
+
1305
+ @driver.get(board_url) # 해당 URL로 이동
1306
+ begin
1307
+ # 아이프레임 요소가 나타날 때까지 기다립니다.
1308
+ wait = Selenium::WebDriver::Wait.new(:timeout => 20) # 아이프레임 선택
1309
+ wait.until { @driver.find_element(:xpath, '//*[@id="cafe_main"]') } # 아이프레임 선택
1310
+ sleep(1)
1311
+ @driver.switch_to.frame(@driver.find_element(:xpath, '//*[@id="cafe_main"]')) # 아이프레임 선택
1312
+
1313
+
1314
+ if option['좋아요'] == 'true'
1315
+ puts "좋아요 클릭 옵션 진행!!".cyan
1316
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
1317
+ wait.until { @driver.find_element(:xpath, '//*[@class="u_ico _icon"]') }
1318
+
1319
+ # 댓글 입력
1320
+ element = @driver.find_element(:xpath, '//*[@class="u_ico _icon"]')
1321
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element)#크롤 이동
1322
+ sleep(1)
1323
+
1324
+ # 좋아요 버튼을 찾기
1325
+ like_button = @driver.find_element(:xpath, '//div[@class="ReactionLikeIt u_likeit_list_module _cafeReactionModule"]//a[@role="button"]')
1326
+
1327
+ # aria-pressed 속성 값 확인
1328
+ aria_pressed = like_button.attribute('aria-pressed')
1329
+
1330
+ if aria_pressed == 'true'
1331
+ # 이미 좋아요를 누른 상태일 경우
1332
+
1333
+ else
1334
+ # 좋아요를 아직 누르지 않은 상태일 경우 클릭
1335
+ @driver.find_element(:xpath, '//*[@class="u_ico _icon"]').click
1336
+ sleep(2)
1337
+ end
1338
+ else
1339
+ end
1340
+
1341
+
1342
+
1343
+ if option['re_coment'] == 'true' # 대 댓글 작업때
1344
+ if @data['포스트설정']['전체대댓글'].checked?
1345
+ begin
1346
+ comment_items = @driver.find_elements(:css, 'li.CommentItem')
1347
+ original_comments = comment_items.select { |item| !item.attribute('class').include?('CommentItem--reply') }
1348
+
1349
+ original_comments.each_with_index do |item, index|
1350
+
1351
+ begin
1352
+
1353
+ if @data['포스트설정']['순서사용2'].checked?
1354
+ @content_soon ||= 0 # 초기 한 번만 0으로 세팅
1355
+
1356
+ if @data['내용설정']['내용'].nil? || @data['내용설정']['내용'].empty?
1357
+ content = ''
1358
+ else
1359
+ if @data.dig('내용설정', '랜덤사용')&.respond_to?(:checked?) && @data['내용설정']['랜덤사용'].checked?
1360
+ content = @data['내용설정']['내용'].sample[2]
1361
+ else
1362
+ content = @data['내용설정']['내용'][@content_soon][2]
1363
+ @content_soon += 1
1364
+ @content_soon = 0 if @content_soon >= @data['내용설정']['내용'].length
1365
+ end
1366
+ end
1367
+ else
1368
+ end
1369
+
1370
+ # 디엠 자동 변경이 체크된 경우 content를 변환
1371
+ if @data['포스트설정']['내용자동변경'].checked?
1372
+ change_memory = {}
1373
+ @data['포스트설정']['내용자동변경값'].each do |key, v|
1374
+ change_memory[key] = v.sample
1375
+ end
1376
+ @data['포스트설정']['내용자동변경값'].each do |key, _|
1377
+ if content.include?(key)
1378
+ content = content.gsub(key, change_memory[key]) # gsub을 사용하여 내용 치환
1379
+ else
1380
+ end
1381
+ end
1382
+ end
1383
+
1384
+ if option['ChatGPT사용'] == 'true'
1385
+ pcol1 = @driver.find_element(:css, 'div.title_area > h3.title_text').text
1386
+ sleep(1)
1387
+
1388
+ puts "ChatGPT로 댓글을 만드는 중입니다."
1389
+ @api_key = api_key
1390
+ url = 'https://api.openai.com/v1/chat/completions'
1391
+ headers = {
1392
+ 'Content-Type' => 'application/json',
1393
+ 'Authorization' => 'Bearer ' + @api_key
1394
+ }
1395
+ data = {
1396
+ 'model' => 'gpt-3.5-turbo',
1397
+ 'messages' => [
1398
+ { "role" => "system", "content" => "해당 제목에 알맞은 댓글을 짧게 한 개만 만들어줘" },
1399
+ { "role" => "user", "content" => pcol1 } # pcol1 직접 사용
1400
+ ]
1401
+ }
1402
+
1403
+ begin
1404
+ req = HTTP.headers(headers).post(url, json: data)
1405
+ puts "HTTP Status: #{req.status}" # 상태 코드 확인
1406
+ response = JSON.parse(req.body.to_s)
1407
+ puts "API Response: #{response}" # 전체 응답 출력
1408
+
1409
+ if req.status == 429
1410
+ return "API 요청 제한을 초과했습니다. 플랜 및 할당량을 확인하세요."
1411
+ end
1412
+
1413
+ # 응답 데이터에서 안전하게 값 추출
1414
+ raw_content = response.dig('choices', 0, 'message', 'content') || "댓글 생성을 실패했습니다." # 응답이 없을 경우 기본 메시지 설정
1415
+ content = raw_content.gsub(/\. /, ".\n") # 줄바꿈 추가
1416
+
1417
+ rescue => e
1418
+ puts "Error: #{e.message}"
1419
+ content = "오류가 발생했습니다."
1420
+ end
1421
+ else
1422
+ end
1423
+
1424
+ reply_button = item.find_element(:css, 'a.comment_info_button')
1425
+ puts "대댓글 #{index + 1} 작성 중..."
1426
+ reply_button.click
1427
+ sleep(1.5)
1428
+
1429
+ textarea = @driver.find_element(:css, 'textarea.comment_inbox_text')
1430
+ textarea.send_keys(content)
1431
+ sleep(1)
1432
+
1433
+ if option['이모티콘자동삽입'] == 'true'
1434
+ puts "이모티콘 자동 삽입 옵션 진행!!".cyan
1435
+ reply_comments = @driver.find_elements(:css, 'li.CommentItem.CommentItem--reply')
1436
+ reply_comments.each_with_index do |item, index|
1437
+ begin
1438
+
1439
+
1440
+ # 해당 대댓글 내부의 이모티콘 버튼 찾기
1441
+ sticker_button = item.find_element(:css, 'a.button_sticker')
1442
+ sticker_button.click
1443
+ sleep(1)
1444
+
1445
+ rescue
1446
+ end
1447
+ end
1448
+ begin
1449
+ # 'se2_line_sticker_set' 클래스를 가진 <ul> 요소 안의 모든 <li> 요소 찾기
1450
+ sticker_list_elements = wait.until { @driver.find_elements(:css, '.se2_line_sticker_set li') }
1451
+
1452
+ # 16개 <li> 요소 중 랜덤으로 하나 선택하여 클릭
1453
+ random_li = sticker_list_elements.sample
1454
+ random_button = random_li.find_element(:tag_name, 'button') # <button> 태그 찾기
1455
+ random_button.click
1456
+
1457
+ sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
1458
+
1459
+ # 첫 번째 클릭한 <li> 내에서 버튼을 찾기
1460
+ inner_buttons = random_li.find_elements(:tag_name, 'button')
1461
+
1462
+ # 20개 <button> 요소 중 랜덤으로 하나 선택하여 클릭
1463
+ random_button_in_li = inner_buttons.sample
1464
+ sleep(1)
1465
+ random_button_in_li.click
1466
+
1467
+ sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
1468
+
1469
+ rescue Selenium::WebDriver::Error::StaleElementReferenceError => e
1470
+ #puts "Stale element reference 오류 발생, 계속 진행: #{e.message}".yellow
1471
+ # 오류 발생 시에도 계속 진행하려면 작업을 계속하도록 처리
1472
+ # 예를 들어, continue, or next 등으로 다음 단계로 넘어갈 수 있습니다.
1473
+
1474
+ rescue => e
1475
+ puts "기타 오류로 인해 이모티콘 삽입 안됨"
1476
+ # 기타 오류 처리
1477
+ # 여기에 추가적인 예외 처리 로직을 넣을 수 있습니다.
1478
+ end
1479
+ else
1480
+ puts "이모티콘 자동 삽입 옵션이 비활성화됨."
1481
+ end
1482
+
1483
+ # 이미지 자동 삽입
1484
+ if option['이미지자동삽입'] == 'true'
1485
+ puts "이미지 자동 상입 옵션 진행!!".cyan
1486
+
1487
+ # 아이프레임 요소가 나타날 때까지 기다립니다.
1488
+ @image = image
1489
+ image_path = image
1490
+ reply_comments = @driver.find_elements(:css, 'li.CommentItem.CommentItem--reply')
1491
+
1492
+ reply_comments.each_with_index do |item, index|
1493
+ begin
1494
+
1495
+
1496
+ # 해당 대댓글 내부에서 for="attach2"인 라벨 클릭
1497
+ attach_button = item.find_element(:xpath, './/*[@class="button_file"]')
1498
+ attach_button.click
1499
+ sleep(1)
1500
+
1501
+ rescue
1502
+ end
1503
+ end
1504
+ key_stroke('escape')
1505
+ # 파일 경로 자동 입력
1506
+ file_input = @driver.find_element(:xpath, '//*[@title="사진첨부"]')
1507
+
1508
+ # send_keys로 파일 경로를 입력하여 이미지 업로드
1509
+ file_input.send_keys(image_path)
1510
+ sleep(2)
1511
+
1512
+ else
1513
+ end
1514
+
1515
+ register_btn = @driver.find_element(:css, 'a.button.btn_register')
1516
+ register_btn.click
1517
+ sleep(2)
1518
+
1519
+ rescue => e
1520
+ puts "대댓글 #{index + 1} 처리 중 오류 발생: #{e.message}"
1521
+ next
1522
+ end
1523
+ end
1524
+ rescue => e
1525
+ puts "전체대댓글 처리 중 예외 발생: #{e.message}"
1526
+ end
1527
+
1528
+ elsif @data['포스트설정']['지정대댓글'].checked?
1529
+ targets = @data['포스트설정']['nik_or_number'].text.to_s.force_encoding('utf-8').split(',').map(&:strip)
1530
+ targets.each do |target|
1531
+ if target.match?(/^\d+$/)
1532
+ index = target.to_i - 1
1533
+ comment_items = @driver.find_elements(:css, 'li.CommentItem')
1534
+ original_comments = comment_items.select { |item| !item.attribute('class').include?('CommentItem--reply') }
1535
+
1536
+ if original_comments[index]
1537
+ begin
1538
+
1539
+ if @data['포스트설정']['순서사용2'].checked?
1540
+ @content_soon ||= 0 # 초기 한 번만 0으로 세팅
1541
+
1542
+ if @data['내용설정']['내용'].nil? || @data['내용설정']['내용'].empty?
1543
+ content = ''
1544
+ else
1545
+ if @data.dig('내용설정', '랜덤사용')&.respond_to?(:checked?) && @data['내용설정']['랜덤사용'].checked?
1546
+ content = @data['내용설정']['내용'].sample[2]
1547
+ else
1548
+ content = @data['내용설정']['내용'][@content_soon][2]
1549
+ @content_soon += 1
1550
+ @content_soon = 0 if @content_soon >= @data['내용설정']['내용'].length
1551
+ end
1552
+ end
1553
+ else
1554
+ end
1555
+
1556
+ # 디엠 자동 변경이 체크된 경우 content를 변환
1557
+ if @data['포스트설정']['내용자동변경'].checked?
1558
+ change_memory = {}
1559
+ @data['포스트설정']['내용자동변경값'].each do |key, v|
1560
+ change_memory[key] = v.sample
1561
+ end
1562
+ @data['포스트설정']['내용자동변경값'].each do |key, _|
1563
+ if content.include?(key)
1564
+ content = content.gsub(key, change_memory[key]) # gsub을 사용하여 내용 치환
1565
+ else
1566
+ end
1567
+ end
1568
+ end
1569
+
1570
+ if option['ChatGPT사용'] == 'true'
1571
+ pcol1 = @driver.find_element(:css, 'div.title_area > h3.title_text').text
1572
+ sleep(1)
1573
+
1574
+ puts "ChatGPT로 댓글을 만드는 중입니다."
1575
+ @api_key = api_key
1576
+ url = 'https://api.openai.com/v1/chat/completions'
1577
+ headers = {
1578
+ 'Content-Type' => 'application/json',
1579
+ 'Authorization' => 'Bearer ' + @api_key
1580
+ }
1581
+ data = {
1582
+ 'model' => 'gpt-3.5-turbo',
1583
+ 'messages' => [
1584
+ { "role" => "system", "content" => "해당 제목에 알맞은 댓글을 짧게 한 개만 만들어줘" },
1585
+ { "role" => "user", "content" => pcol1 } # pcol1 직접 사용
1586
+ ]
1587
+ }
1588
+
1589
+ begin
1590
+ req = HTTP.headers(headers).post(url, json: data)
1591
+ puts "HTTP Status: #{req.status}" # 상태 코드 확인
1592
+ response = JSON.parse(req.body.to_s)
1593
+ puts "API Response: #{response}" # 전체 응답 출력
1594
+
1595
+ if req.status == 429
1596
+ return "API 요청 제한을 초과했습니다. 플랜 및 할당량을 확인하세요."
1597
+ end
1598
+
1599
+ # 응답 데이터에서 안전하게 값 추출
1600
+ raw_content = response.dig('choices', 0, 'message', 'content') || "댓글 생성을 실패했습니다." # 응답이 없을 경우 기본 메시지 설정
1601
+ content = raw_content.gsub(/\. /, ".\n") # 줄바꿈 추가
1602
+
1603
+ rescue => e
1604
+ puts "Error: #{e.message}"
1605
+ content = "오류가 발생했습니다."
1606
+ end
1607
+ else
1608
+ end
1609
+
1610
+ puts "#{index + 1}번째 댓글에 대댓글 작성 시작"
1611
+ reply_button = original_comments[index].find_element(:css, 'a.comment_info_button')
1612
+ reply_button.click
1613
+ sleep(1.5)
1614
+
1615
+ textarea = @driver.find_element(:css, 'textarea.comment_inbox_text')
1616
+ textarea.send_keys(content)
1617
+ sleep(1)
1618
+
1619
+ if option['이모티콘자동삽입'] == 'true'
1620
+ puts "이모티콘 자동 삽입 옵션 진행!!".cyan
1621
+ reply_comments = @driver.find_elements(:css, 'li.CommentItem.CommentItem--reply')
1622
+ reply_comments.each_with_index do |item, index|
1623
+ begin
1624
+
1625
+
1626
+ # 해당 대댓글 내부의 이모티콘 버튼 찾기
1627
+ sticker_button = item.find_element(:css, 'a.button_sticker')
1628
+ sticker_button.click
1629
+ sleep(1)
1630
+
1631
+ rescue
1632
+ end
1633
+ end
1634
+
1635
+ begin
1636
+ # 'se2_line_sticker_set' 클래스를 가진 <ul> 요소 안의 모든 <li> 요소 찾기
1637
+ sticker_list_elements = wait.until { @driver.find_elements(:css, '.se2_line_sticker_set li') }
1638
+
1639
+ # 16개 <li> 요소 중 랜덤으로 하나 선택하여 클릭
1640
+ random_li = sticker_list_elements.sample
1641
+ random_button = random_li.find_element(:tag_name, 'button') # <button> 태그 찾기
1642
+ random_button.click
1643
+
1644
+ sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
1645
+
1646
+ # 첫 번째 클릭한 <li> 내에서 버튼을 찾기
1647
+ inner_buttons = random_li.find_elements(:tag_name, 'button')
1648
+
1649
+ # 20개 <button> 요소 중 랜덤으로 하나 선택하여 클릭
1650
+ random_button_in_li = inner_buttons.sample
1651
+ sleep(1)
1652
+ random_button_in_li.click
1653
+
1654
+ sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
1655
+
1656
+ rescue Selenium::WebDriver::Error::StaleElementReferenceError => e
1657
+ #puts "Stale element reference 오류 발생, 계속 진행: #{e.message}".yellow
1658
+ # 오류 발생 시에도 계속 진행하려면 작업을 계속하도록 처리
1659
+ # 예를 들어, continue, or next 등으로 다음 단계로 넘어갈 수 있습니다.
1660
+
1661
+ rescue => e
1662
+ puts "기타 오류로 인해 이모티콘 삽입 안됨"
1663
+ # 기타 오류 처리
1664
+ # 여기에 추가적인 예외 처리 로직을 넣을 수 있습니다.
1665
+ end
1666
+ else
1667
+ puts "이모티콘 자동 삽입 옵션이 비활성화됨."
1668
+ end
1669
+
1670
+ # 이미지 자동 삽입
1671
+ if option['이미지자동삽입'] == 'true'
1672
+ puts "이미지 자동 상입 옵션 진행!!".cyan
1673
+
1674
+ # 아이프레임 요소가 나타날 때까지 기다립니다.
1675
+ @image = image
1676
+ image_path = image
1677
+ reply_comments = @driver.find_elements(:css, 'li.CommentItem.CommentItem--reply')
1678
+
1679
+ reply_comments.each_with_index do |item, index|
1680
+ begin
1681
+
1682
+
1683
+ # 해당 대댓글 내부에서 for="attach2"인 라벨 클릭
1684
+ attach_button = item.find_element(:xpath, './/*[@class="button_file"]')
1685
+ attach_button.click
1686
+ sleep(1)
1687
+
1688
+ rescue
1689
+ end
1690
+ end
1691
+ key_stroke('escape')
1692
+ # 파일 경로 자동 입력
1693
+ file_input = @driver.find_element(:xpath, '//*[@title="사진첨부"]')
1694
+
1695
+ # send_keys로 파일 경로를 입력하여 이미지 업로드
1696
+ file_input.send_keys(image_path)
1697
+ sleep(2)
1698
+
1699
+ else
1700
+ end
1701
+
1702
+ register_btn = @driver.find_element(:css, 'a.button.btn_register')
1703
+ register_btn.click
1704
+ sleep(2)
1705
+
1706
+ puts "#{index + 1}번째 댓글에 대댓글 작성 완료"
1707
+ rescue => e
1708
+ puts "댓글 인덱스 #{index + 1} 처리 중 오류 발생: #{e.message}"
1709
+ end
1710
+ else
1711
+ puts "해당 인덱스(#{index + 1})의 답글쓰기 버튼이 없습니다."
1712
+ end
1713
+
1714
+ else # 닉네임으로 찾기
1715
+ comment_items = @driver.find_elements(:css, 'li.CommentItem')
1716
+ original_comments = comment_items.select { |item| !item.attribute('class').include?('CommentItem--reply') }
1717
+
1718
+ matched = false
1719
+ last_matched_item = nil # 마지막에 닉네임이 일치한 댓글 저장
1720
+
1721
+ original_comments.each_with_index do |item, idx|
1722
+ begin
1723
+ nickname_element = item.find_element(:css, 'a.comment_nickname')
1724
+ nickname = nickname_element.text.strip
1725
+
1726
+ if nickname.include?(target)
1727
+ puts "#{target} 닉네임이 포함된 댓글 발견 (#{idx + 1}번째)"
1728
+ last_matched_item = item # 매번 갱신 → 마지막에 발견된 걸 저장
1729
+ end
1730
+ rescue => e
1731
+ puts "닉네임 검사 중 오류 발생: #{e.message}"
1732
+ next
1733
+ end
1734
+ end
1735
+
1736
+ # 루프 끝난 뒤 마지막 댓글에만 작업 실행
1737
+ if last_matched_item
1738
+ begin
1739
+
1740
+ if @data['포스트설정']['순서사용2'].checked?
1741
+ @content_soon ||= 0 # 초기 한 번만 0으로 세팅
1742
+
1743
+ if @data['내용설정']['내용'].nil? || @data['내용설정']['내용'].empty?
1744
+ content = ''
1745
+ else
1746
+ if @data.dig('내용설정', '랜덤사용')&.respond_to?(:checked?) && @data['내용설정']['랜덤사용'].checked?
1747
+ content = @data['내용설정']['내용'].sample[2]
1748
+ else
1749
+ content = @data['내용설정']['내용'][@content_soon][2]
1750
+ @content_soon += 1
1751
+ @content_soon = 0 if @content_soon >= @data['내용설정']['내용'].length
1752
+ end
1753
+ end
1754
+ else
1755
+ end
1756
+
1757
+ # 디엠 자동 변경이 체크된 경우 content를 변환
1758
+ if @data['포스트설정']['내용자동변경'].checked?
1759
+ change_memory = {}
1760
+ @data['포스트설정']['내용자동변경값'].each do |key, v|
1761
+ change_memory[key] = v.sample
1762
+ end
1763
+ @data['포스트설정']['내용자동변경값'].each do |key, _|
1764
+ if content.include?(key)
1765
+ content = content.gsub(key, change_memory[key]) # gsub을 사용하여 내용 치환
1766
+ else
1767
+ end
1768
+ end
1769
+ end
1770
+
1771
+ if option['ChatGPT사용'] == 'true'
1772
+ pcol1 = @driver.find_element(:css, 'div.title_area > h3.title_text').text
1773
+ sleep(1)
1774
+
1775
+ puts "ChatGPT로 댓글을 만드는 중입니다."
1776
+ @api_key = api_key
1777
+ url = 'https://api.openai.com/v1/chat/completions'
1778
+ headers = {
1779
+ 'Content-Type' => 'application/json',
1780
+ 'Authorization' => 'Bearer ' + @api_key
1781
+ }
1782
+ data = {
1783
+ 'model' => 'gpt-3.5-turbo',
1784
+ 'messages' => [
1785
+ { "role" => "system", "content" => "해당 제목에 알맞은 댓글을 짧게 한 개만 만들어줘" },
1786
+ { "role" => "user", "content" => pcol1 } # pcol1 직접 사용
1787
+ ]
1788
+ }
1789
+
1790
+ begin
1791
+ req = HTTP.headers(headers).post(url, json: data)
1792
+ puts "HTTP Status: #{req.status}" # 상태 코드 확인
1793
+ response = JSON.parse(req.body.to_s)
1794
+ puts "API Response: #{response}" # 전체 응답 출력
1795
+
1796
+ if req.status == 429
1797
+ return "API 요청 제한을 초과했습니다. 플랜 및 할당량을 확인하세요."
1798
+ end
1799
+
1800
+ # 응답 데이터에서 안전하게 값 추출
1801
+ raw_content = response.dig('choices', 0, 'message', 'content') || "댓글 생성을 실패했습니다." # 응답이 없을 경우 기본 메시지 설정
1802
+ content = raw_content.gsub(/\. /, ".\n") # 줄바꿈 추가
1803
+
1804
+ rescue => e
1805
+ puts "Error: #{e.message}"
1806
+ content = "오류가 발생했습니다."
1807
+ end
1808
+ else
1809
+ end
1810
+
1811
+ reply_button = last_matched_item.find_element(:css, 'a.comment_info_button')
1812
+ reply_button.click
1813
+ sleep(1.5)
1814
+
1815
+ textarea = @driver.find_element(:css, 'textarea.comment_inbox_text')
1816
+ textarea.send_keys(content)
1817
+ sleep(1)
1818
+
1819
+ if option['이모티콘자동삽입'] == 'true'
1820
+ puts "이모티콘 자동 삽입 옵션 진행!!".cyan
1821
+ reply_comments = @driver.find_elements(:css, 'li.CommentItem.CommentItem--reply')
1822
+ reply_comments.each_with_index do |item, index|
1823
+ begin
1824
+
1825
+ sticker_button = item.find_element(:css, 'a.button_sticker')
1826
+ sticker_button.click
1827
+ sleep(1)
1828
+ rescue
1829
+ end
1830
+ end
1831
+ begin
1832
+ sticker_list_elements = wait.until { @driver.find_elements(:css, '.se2_line_sticker_set li') }
1833
+ random_li = sticker_list_elements.sample
1834
+ random_button = random_li.find_element(:tag_name, 'button')
1835
+ random_button.click
1836
+ sleep(1)
1837
+ inner_buttons = random_li.find_elements(:tag_name, 'button')
1838
+ random_button_in_li = inner_buttons.sample
1839
+ sleep(1)
1840
+ random_button_in_li.click
1841
+ sleep(1)
1842
+ rescue Selenium::WebDriver::Error::StaleElementReferenceError
1843
+ rescue => e
1844
+ puts "기타 오류로 인해 이모티콘 삽입 안됨"
1845
+ end
1846
+ else
1847
+ puts "이모티콘 자동 삽입 옵션이 비활성화됨."
1848
+ end
1849
+
1850
+ if option['이미지자동삽입'] == 'true'
1851
+ puts "이미지 자동 삽입 옵션 진행!!".cyan
1852
+ @image = image
1853
+ image_path = image
1854
+ reply_comments = @driver.find_elements(:css, 'li.CommentItem.CommentItem--reply')
1855
+ reply_comments.each_with_index do |item, index|
1856
+ begin
1857
+
1858
+ attach_button = item.find_element(:xpath, './/*[@class="button_file"]')
1859
+ attach_button.click
1860
+ sleep(1)
1861
+ rescue
1862
+ end
1863
+ end
1864
+ key_stroke('escape')
1865
+ file_input = @driver.find_element(:xpath, '//*[@title="사진첨부"]')
1866
+ file_input.send_keys(image_path)
1867
+ sleep(2)
1868
+ end
1869
+
1870
+ register_btn = @driver.find_element(:css, 'a.button.btn_register')
1871
+ register_btn.click
1872
+ sleep(2)
1873
+
1874
+ matched = true
1875
+ rescue => e
1876
+ puts "대댓글 등록 중 오류 발생: #{e.message}"
1877
+ end
1878
+ end
1879
+
1880
+ puts "닉네임 '#{target}'을 포함한 댓글을 찾지 못했습니다." unless matched
1881
+
1882
+ end
1883
+ end
1884
+
1885
+ end
1886
+
1887
+ elsif option['re_coment'] == 'false' # 대 댓글 아닐때
1888
+ if @data['포스트설정']['순서사용2'].checked?
1889
+ @content_soon ||= 0 # 초기 한 번만 0으로 세팅
1890
+
1891
+ if @data['내용설정']['내용'].nil? || @data['내용설정']['내용'].empty?
1892
+ content = ''
1893
+ else
1894
+ if @data.dig('내용설정', '랜덤사용')&.respond_to?(:checked?) && @data['내용설정']['랜덤사용'].checked?
1895
+ content = @data['내용설정']['내용'].sample[2]
1896
+ else
1897
+ content = @data['내용설정']['내용'][@content_soon][2]
1898
+ @content_soon += 1
1899
+ @content_soon = 0 if @content_soon >= @data['내용설정']['내용'].length
1900
+ end
1901
+ end
1902
+ else
1903
+ end
1904
+
1905
+ # 디엠 자동 변경이 체크된 경우 content를 변환
1906
+ if @data['포스트설정']['내용자동변경'].checked?
1907
+ change_memory = {}
1908
+ @data['포스트설정']['내용자동변경값'].each do |key, v|
1909
+ change_memory[key] = v.sample
1910
+ end
1911
+ @data['포스트설정']['내용자동변경값'].each do |key, _|
1912
+ if content.include?(key)
1913
+ content = content.gsub(key, change_memory[key]) # gsub을 사용하여 내용 치환
1914
+ else
1915
+ end
1916
+ end
1917
+ end
1918
+
1919
+ if option['ChatGPT사용'] == 'true'
1920
+ pcol1 = @driver.find_element(:css, 'div.title_area > h3.title_text').text
1921
+ sleep(1)
1922
+
1923
+ puts "ChatGPT로 댓글을 만드는 중입니다."
1924
+ @api_key = api_key
1925
+ url = 'https://api.openai.com/v1/chat/completions'
1926
+ headers = {
1927
+ 'Content-Type' => 'application/json',
1928
+ 'Authorization' => 'Bearer ' + @api_key
1929
+ }
1930
+ data = {
1931
+ 'model' => 'gpt-3.5-turbo',
1932
+ 'messages' => [
1933
+ { "role" => "system", "content" => "해당 제목에 알맞은 댓글을 짧게 한 개만 만들어줘" },
1934
+ { "role" => "user", "content" => pcol1 } # pcol1 직접 사용
1935
+ ]
1936
+ }
1937
+
1938
+ begin
1939
+ req = HTTP.headers(headers).post(url, json: data)
1940
+ puts "HTTP Status: #{req.status}" # 상태 코드 확인
1941
+ response = JSON.parse(req.body.to_s)
1942
+ puts "API Response: #{response}" # 전체 응답 출력
1943
+
1944
+ if req.status == 429
1945
+ return "API 요청 제한을 초과했습니다. 플랜 및 할당량을 확인하세요."
1946
+ end
1947
+
1948
+ # 응답 데이터에서 안전하게 값 추출
1949
+ raw_content = response.dig('choices', 0, 'message', 'content') || "댓글 생성을 실패했습니다." # 응답이 없을 경우 기본 메시지 설정
1950
+ content = raw_content.gsub(/\. /, ".\n") # 줄바꿈 추가
1951
+
1952
+ rescue => e
1953
+ puts "Error: #{e.message}"
1954
+ content = "오류가 발생했습니다."
1955
+ end
1956
+ else
1957
+ end
1958
+
1959
+ wait = Selenium::WebDriver::Wait.new(timeout: 10)
1960
+ wait.until { @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]') }
1961
+
1962
+ element = @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]')
1963
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element)
1964
+ sleep(1)
1965
+
1966
+ element.send_keys(content)
1967
+ sleep(1)
1968
+
1969
+ # 이모티콘 자동 삽입
1970
+ if option['이모티콘자동삽입'] == 'true'
1971
+ puts "이모티콘 자동 삽입 옵션 진행!!".cyan
1972
+
881
1973
  # '이모티콘' 버튼 클릭
882
1974
  @driver.find_element(:xpath, '//*[@class="button_sticker"]').click
883
1975
  sleep(1)
884
-
1976
+
885
1977
  begin
886
1978
  # 'se2_line_sticker_set' 클래스를 가진 <ul> 요소 안의 모든 <li> 요소 찾기
887
1979
  sticker_list_elements = wait.until { @driver.find_elements(:css, '.se2_line_sticker_set li') }
888
-
1980
+
889
1981
  # 16개 <li> 요소 중 랜덤으로 하나 선택하여 클릭
890
1982
  random_li = sticker_list_elements.sample
891
1983
  random_button = random_li.find_element(:tag_name, 'button') # <button> 태그 찾기
892
1984
  random_button.click
893
-
894
- sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
895
1985
 
1986
+ sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
1987
+
896
1988
  # 첫 번째 클릭한 <li> 내에서 버튼을 찾기
897
1989
  inner_buttons = random_li.find_elements(:tag_name, 'button')
898
-
1990
+
899
1991
  # 20개 <button> 요소 중 랜덤으로 하나 선택하여 클릭
900
1992
  random_button_in_li = inner_buttons.sample
901
1993
  sleep(1)
902
1994
  random_button_in_li.click
903
-
904
- sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
905
1995
 
1996
+ sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
1997
+
906
1998
  rescue Selenium::WebDriver::Error::StaleElementReferenceError => e
907
1999
  #puts "Stale element reference 오류 발생, 계속 진행: #{e.message}".yellow
908
2000
  # 오류 발생 시에도 계속 진행하려면 작업을 계속하도록 처리
909
2001
  # 예를 들어, continue, or next 등으로 다음 단계로 넘어갈 수 있습니다.
910
-
2002
+
911
2003
  rescue => e
912
2004
  puts "기타 오류로 인해 이모티콘 삽입 안됨"
913
2005
  # 기타 오류 처리
@@ -916,34 +2008,37 @@ class Naver
916
2008
  else
917
2009
  puts "이모티콘 자동 삽입 옵션이 비활성화됨."
918
2010
  end
919
-
2011
+
920
2012
  # 이미지 자동 삽입
921
2013
  if option['이미지자동삽입'] == 'true'
922
- puts "이미지 자동 상입 옵션 진행!!".cyan
923
-
924
- # 아이프레임 요소가 나타날 때까지 기다립니다.
925
- @image = image
926
- image_path = image
927
-
928
- @driver.find_element(:xpath, '//*[@for="attach2"]').click
929
- sleep(1)
930
- key_stroke('escape')
931
- # 파일 경로 자동 입력
932
- file_input = @driver.find_element(:xpath, '//*[@id="attach2"]')
933
-
934
- # send_keys로 파일 경로를 입력하여 이미지 업로드
935
- file_input.send_keys(image_path)
936
- sleep(2)
937
-
2014
+ puts "이미지 자동 상입 옵션 진행!!".cyan
2015
+
2016
+ # 아이프레임 요소가 나타날 때까지 기다립니다.
2017
+ @image = image
2018
+ image_path = image
2019
+
2020
+ @driver.find_element(:xpath, '//*[@for="attach2"]').click
2021
+ sleep(1)
2022
+ key_stroke('escape')
2023
+ # 파일 경로 자동 입력
2024
+ file_input = @driver.find_element(:xpath, '//*[@class="button_file"]')
2025
+
2026
+ # send_keys로 파일 경로를 입력하여 이미지 업로드
2027
+ file_input.send_keys(image_path)
2028
+ sleep(2)
2029
+
938
2030
  else
939
2031
  end
940
2032
 
941
-
2033
+
942
2034
  wait.until { @driver.find_element(:xpath, '//*[@class="button btn_register is_active"]') }
943
2035
  @driver.find_element(:xpath, '//*[@class="button btn_register is_active"]').click
944
2036
  puts "#{board_url} [댓글 작성 완료 !!]".cyan
945
-
946
2037
  sleep(2)
2038
+ end
2039
+
2040
+
2041
+
947
2042
  begin
948
2043
  @driver.switch_to.alert
949
2044
  sleep(1)
@@ -984,28 +2079,28 @@ class Naver
984
2079
  ff.close()
985
2080
  puts '-[√] 로그 파일 생성 완료.......'.yellow
986
2081
  end
987
- end
988
- end
989
- @driver.switch_to.default_content() # 아이프레임 해제
990
- def sleep_with_progress(sleep_delay)
991
- print "[설정 딜레이 진행 중] "
992
- steps = (sleep_delay.to_f / 0.5).to_i
993
- steps.times do
994
- print "."
995
- STDOUT.flush
996
- sleep(1)
997
- end
998
- puts "\n"
2082
+ end
2083
+
2084
+ @driver.switch_to.default_content() # 아이프레임 해제
2085
+ def sleep_with_progress(sleep_delay)
2086
+ print "[설정 딜레이 진행 중] "
2087
+ steps = (sleep_delay.to_f / 0.5).to_i
2088
+ steps.times do
2089
+ print "."
2090
+ STDOUT.flush
2091
+ sleep(1)
999
2092
  end
1000
- sleep_with_progress(sleep_delay)
1001
-
2093
+ puts "\n"
2094
+ end
1002
2095
 
1003
- rescue => e
1004
- puts "Error: #{e.message}"
1005
- end
1006
-
1007
- else
1008
- end
2096
+ sleep_with_progress(sleep_delay)
2097
+
2098
+
2099
+ rescue => e
2100
+ puts "Error: #{e.message}"
2101
+ end
2102
+ else
2103
+ end
1009
2104
  ################################################################################ 키워드검색사용 ################################################################################
1010
2105
  if option['키워드검색사용'] == 'true'
1011
2106
  puts "키워드 검색 기반으로 댓글 작업 옵션 진행!!".cyan
@@ -1097,203 +2192,744 @@ class Naver
1097
2192
  puts "수집한 URL들: #{collected_urls}"
1098
2193
 
1099
2194
 
1100
- collected_urls.first(counts_number).each do |url|
1101
- @driver.get(url) # 해당 URL로 이동
1102
- sleep(1)
1103
- wait = Selenium::WebDriver::Wait.new(:timeout => 20) # 아이프레임 선택
1104
- wait.until { @driver.find_element(:xpath, '//*[@id="cafe_main"]') } # 아이프레임 선택
1105
- sleep(1)
1106
- @driver.switch_to.frame(@driver.find_element(:xpath, '//*[@id="cafe_main"]')) # 아이프레임 선택
2195
+ collected_urls.first(counts_number).each do |url|
2196
+ @driver.get(url) # 해당 URL로 이동
2197
+ sleep(1)
2198
+ wait = Selenium::WebDriver::Wait.new(:timeout => 20) # 아이프레임 선택
2199
+ wait.until { @driver.find_element(:xpath, '//*[@id="cafe_main"]') } # 아이프레임 선택
2200
+ sleep(1)
2201
+ @driver.switch_to.frame(@driver.find_element(:xpath, '//*[@id="cafe_main"]')) # 아이프레임 선택
2202
+
2203
+
2204
+ if option['좋아요'] == 'true'
2205
+ puts "좋아요 클릭 옵션 진행!!".cyan
2206
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
2207
+ wait.until { @driver.find_element(:xpath, '//*[@class="u_ico _icon"]') }
2208
+
2209
+ # 댓글 입력
2210
+ element = @driver.find_element(:xpath, '//*[@class="u_ico _icon"]')
2211
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element)#크롤 이동
2212
+ sleep(1)
2213
+
2214
+ # 좋아요 버튼을 찾기
2215
+ like_button = @driver.find_element(:xpath, '//div[@class="ReactionLikeIt u_likeit_list_module _cafeReactionModule"]//a[@role="button"]')
2216
+
2217
+ # aria-pressed 속성 값 확인
2218
+ aria_pressed = like_button.attribute('aria-pressed')
2219
+
2220
+ if aria_pressed == 'true'
2221
+ # 이미 좋아요를 누른 상태일 경우
2222
+
2223
+ else
2224
+ # 좋아요를 아직 누르지 않은 상태일 경우 클릭
2225
+ @driver.find_element(:xpath, '//*[@class="u_ico _icon"]').click
2226
+ sleep(2)
2227
+ end
2228
+ else
2229
+ end
2230
+
2231
+
2232
+
2233
+ if option['re_coment'] == 'true' # 대 댓글 작업때
2234
+ if @data['포스트설정']['전체대댓글'].checked?
2235
+ begin
2236
+ comment_items = @driver.find_elements(:css, 'li.CommentItem')
2237
+ original_comments = comment_items.select { |item| !item.attribute('class').include?('CommentItem--reply') }
2238
+
2239
+ original_comments.each_with_index do |item, index|
2240
+
2241
+ begin
2242
+
2243
+ if @data['포스트설정']['순서사용2'].checked?
2244
+ @content_soon ||= 0 # 초기 한 번만 0으로 세팅
2245
+
2246
+ if @data['내용설정']['내용'].nil? || @data['내용설정']['내용'].empty?
2247
+ content = ''
2248
+ else
2249
+ if @data.dig('내용설정', '랜덤사용')&.respond_to?(:checked?) && @data['내용설정']['랜덤사용'].checked?
2250
+ content = @data['내용설정']['내용'].sample[2]
2251
+ else
2252
+ content = @data['내용설정']['내용'][@content_soon][2]
2253
+ @content_soon += 1
2254
+ @content_soon = 0 if @content_soon >= @data['내용설정']['내용'].length
2255
+ end
2256
+ end
2257
+ else
2258
+ end
2259
+
2260
+ # 디엠 자동 변경이 체크된 경우 content를 변환
2261
+ if @data['포스트설정']['내용자동변경'].checked?
2262
+ change_memory = {}
2263
+ @data['포스트설정']['내용자동변경값'].each do |key, v|
2264
+ change_memory[key] = v.sample
2265
+ end
2266
+ @data['포스트설정']['내용자동변경값'].each do |key, _|
2267
+ if content.include?(key)
2268
+ content = content.gsub(key, change_memory[key]) # gsub을 사용하여 내용 치환
2269
+ else
2270
+ end
2271
+ end
2272
+ end
2273
+
2274
+ if option['ChatGPT사용'] == 'true'
2275
+ pcol1 = @driver.find_element(:css, 'div.title_area > h3.title_text').text
2276
+ sleep(1)
2277
+
2278
+ puts "ChatGPT로 댓글을 만드는 중입니다."
2279
+ @api_key = api_key
2280
+ url = 'https://api.openai.com/v1/chat/completions'
2281
+ headers = {
2282
+ 'Content-Type' => 'application/json',
2283
+ 'Authorization' => 'Bearer ' + @api_key
2284
+ }
2285
+ data = {
2286
+ 'model' => 'gpt-3.5-turbo',
2287
+ 'messages' => [
2288
+ { "role" => "system", "content" => "해당 제목에 알맞은 댓글을 짧게 한 개만 만들어줘" },
2289
+ { "role" => "user", "content" => pcol1 } # pcol1 직접 사용
2290
+ ]
2291
+ }
2292
+
2293
+ begin
2294
+ req = HTTP.headers(headers).post(url, json: data)
2295
+ puts "HTTP Status: #{req.status}" # 상태 코드 확인
2296
+ response = JSON.parse(req.body.to_s)
2297
+ puts "API Response: #{response}" # 전체 응답 출력
2298
+
2299
+ if req.status == 429
2300
+ return "API 요청 제한을 초과했습니다. 플랜 및 할당량을 확인하세요."
2301
+ end
2302
+
2303
+ # 응답 데이터에서 안전하게 값 추출
2304
+ raw_content = response.dig('choices', 0, 'message', 'content') || "댓글 생성을 실패했습니다." # 응답이 없을 경우 기본 메시지 설정
2305
+ content = raw_content.gsub(/\. /, ".\n") # 줄바꿈 추가
2306
+
2307
+ rescue => e
2308
+ puts "Error: #{e.message}"
2309
+ content = "오류가 발생했습니다."
2310
+ end
2311
+ else
2312
+ end
2313
+
2314
+ reply_button = item.find_element(:css, 'a.comment_info_button')
2315
+ puts "대댓글 #{index + 1} 작성 중..."
2316
+ reply_button.click
2317
+ sleep(1.5)
2318
+
2319
+ textarea = @driver.find_element(:css, 'textarea.comment_inbox_text')
2320
+ textarea.send_keys(content)
2321
+ sleep(1)
2322
+
2323
+ if option['이모티콘자동삽입'] == 'true'
2324
+ puts "이모티콘 자동 삽입 옵션 진행!!".cyan
2325
+ reply_comments = @driver.find_elements(:css, 'li.CommentItem.CommentItem--reply')
2326
+ reply_comments.each_with_index do |item, index|
2327
+ begin
2328
+
2329
+
2330
+ # 해당 대댓글 내부의 이모티콘 버튼 찾기
2331
+ sticker_button = item.find_element(:css, 'a.button_sticker')
2332
+ sticker_button.click
2333
+ sleep(1)
2334
+
2335
+ rescue
2336
+ end
2337
+ end
2338
+ begin
2339
+ # 'se2_line_sticker_set' 클래스를 가진 <ul> 요소 안의 모든 <li> 요소 찾기
2340
+ sticker_list_elements = wait.until { @driver.find_elements(:css, '.se2_line_sticker_set li') }
2341
+
2342
+ # 16개 <li> 요소 중 랜덤으로 하나 선택하여 클릭
2343
+ random_li = sticker_list_elements.sample
2344
+ random_button = random_li.find_element(:tag_name, 'button') # <button> 태그 찾기
2345
+ random_button.click
2346
+
2347
+ sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
2348
+
2349
+ # 첫 번째 클릭한 <li> 내에서 버튼을 찾기
2350
+ inner_buttons = random_li.find_elements(:tag_name, 'button')
2351
+
2352
+ # 20개 <button> 요소 중 랜덤으로 하나 선택하여 클릭
2353
+ random_button_in_li = inner_buttons.sample
2354
+ sleep(1)
2355
+ random_button_in_li.click
2356
+
2357
+ sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
2358
+
2359
+ rescue Selenium::WebDriver::Error::StaleElementReferenceError => e
2360
+ #puts "Stale element reference 오류 발생, 계속 진행: #{e.message}".yellow
2361
+ # 오류 발생 시에도 계속 진행하려면 작업을 계속하도록 처리
2362
+ # 예를 들어, continue, or next 등으로 다음 단계로 넘어갈 수 있습니다.
2363
+
2364
+ rescue => e
2365
+ puts "기타 오류로 인해 이모티콘 삽입 안됨"
2366
+ # 기타 오류 처리
2367
+ # 여기에 추가적인 예외 처리 로직을 넣을 수 있습니다.
2368
+ end
2369
+ else
2370
+ puts "이모티콘 자동 삽입 옵션이 비활성화됨."
2371
+ end
2372
+
2373
+ # 이미지 자동 삽입
2374
+ if option['이미지자동삽입'] == 'true'
2375
+ puts "이미지 자동 상입 옵션 진행!!".cyan
2376
+
2377
+ # 아이프레임 요소가 나타날 때까지 기다립니다.
2378
+ @image = image
2379
+ image_path = image
2380
+ reply_comments = @driver.find_elements(:css, 'li.CommentItem.CommentItem--reply')
2381
+
2382
+ reply_comments.each_with_index do |item, index|
2383
+ begin
2384
+
2385
+
2386
+ # 해당 대댓글 내부에서 for="attach2"인 라벨 클릭
2387
+ attach_button = item.find_element(:xpath, './/*[@class="button_file"]')
2388
+ attach_button.click
2389
+ sleep(1)
2390
+
2391
+ rescue
2392
+ end
2393
+ end
2394
+ key_stroke('escape')
2395
+ # 파일 경로 자동 입력
2396
+ file_input = @driver.find_element(:xpath, '//*[@title="사진첨부"]')
2397
+
2398
+ # send_keys로 파일 경로를 입력하여 이미지 업로드
2399
+ file_input.send_keys(image_path)
2400
+ sleep(2)
2401
+
2402
+ else
2403
+ end
2404
+
2405
+ register_btn = @driver.find_element(:css, 'a.button.btn_register')
2406
+ register_btn.click
2407
+ sleep(2)
2408
+
2409
+ rescue => e
2410
+ puts "대댓글 #{index + 1} 처리 중 오류 발생: #{e.message}"
2411
+ next
2412
+ end
2413
+ end
2414
+ rescue => e
2415
+ puts "전체대댓글 처리 중 예외 발생: #{e.message}"
2416
+ end
2417
+
2418
+ elsif @data['포스트설정']['지정대댓글'].checked?
2419
+ targets = @data['포스트설정']['nik_or_number'].text.to_s.force_encoding('utf-8').split(',').map(&:strip)
2420
+ targets.each do |target|
2421
+ if target.match?(/^\d+$/)
2422
+ index = target.to_i - 1
2423
+ comment_items = @driver.find_elements(:css, 'li.CommentItem')
2424
+ original_comments = comment_items.select { |item| !item.attribute('class').include?('CommentItem--reply') }
2425
+
2426
+ if original_comments[index]
2427
+ begin
2428
+
2429
+ if @data['포스트설정']['순서사용2'].checked?
2430
+ @content_soon ||= 0 # 초기 한 번만 0으로 세팅
2431
+
2432
+ if @data['내용설정']['내용'].nil? || @data['내용설정']['내용'].empty?
2433
+ content = ''
2434
+ else
2435
+ if @data.dig('내용설정', '랜덤사용')&.respond_to?(:checked?) && @data['내용설정']['랜덤사용'].checked?
2436
+ content = @data['내용설정']['내용'].sample[2]
2437
+ else
2438
+ content = @data['내용설정']['내용'][@content_soon][2]
2439
+ @content_soon += 1
2440
+ @content_soon = 0 if @content_soon >= @data['내용설정']['내용'].length
2441
+ end
2442
+ end
2443
+ else
2444
+ end
2445
+
2446
+ # 디엠 자동 변경이 체크된 경우 content를 변환
2447
+ if @data['포스트설정']['내용자동변경'].checked?
2448
+ change_memory = {}
2449
+ @data['포스트설정']['내용자동변경값'].each do |key, v|
2450
+ change_memory[key] = v.sample
2451
+ end
2452
+ @data['포스트설정']['내용자동변경값'].each do |key, _|
2453
+ if content.include?(key)
2454
+ content = content.gsub(key, change_memory[key]) # gsub을 사용하여 내용 치환
2455
+ else
2456
+ end
2457
+ end
2458
+ end
2459
+
2460
+ if option['ChatGPT사용'] == 'true'
2461
+ pcol1 = @driver.find_element(:css, 'div.title_area > h3.title_text').text
2462
+ sleep(1)
2463
+
2464
+ puts "ChatGPT로 댓글을 만드는 중입니다."
2465
+ @api_key = api_key
2466
+ url = 'https://api.openai.com/v1/chat/completions'
2467
+ headers = {
2468
+ 'Content-Type' => 'application/json',
2469
+ 'Authorization' => 'Bearer ' + @api_key
2470
+ }
2471
+ data = {
2472
+ 'model' => 'gpt-3.5-turbo',
2473
+ 'messages' => [
2474
+ { "role" => "system", "content" => "해당 제목에 알맞은 댓글을 짧게 한 개만 만들어줘" },
2475
+ { "role" => "user", "content" => pcol1 } # pcol1 직접 사용
2476
+ ]
2477
+ }
2478
+
2479
+ begin
2480
+ req = HTTP.headers(headers).post(url, json: data)
2481
+ puts "HTTP Status: #{req.status}" # 상태 코드 확인
2482
+ response = JSON.parse(req.body.to_s)
2483
+ puts "API Response: #{response}" # 전체 응답 출력
2484
+
2485
+ if req.status == 429
2486
+ return "API 요청 제한을 초과했습니다. 플랜 및 할당량을 확인하세요."
2487
+ end
2488
+
2489
+ # 응답 데이터에서 안전하게 값 추출
2490
+ raw_content = response.dig('choices', 0, 'message', 'content') || "댓글 생성을 실패했습니다." # 응답이 없을 경우 기본 메시지 설정
2491
+ content = raw_content.gsub(/\. /, ".\n") # 줄바꿈 추가
2492
+
2493
+ rescue => e
2494
+ puts "Error: #{e.message}"
2495
+ content = "오류가 발생했습니다."
2496
+ end
2497
+ else
2498
+ end
2499
+
2500
+ puts "#{index + 1}번째 댓글에 대댓글 작성 시작"
2501
+ reply_button = original_comments[index].find_element(:css, 'a.comment_info_button')
2502
+ reply_button.click
2503
+ sleep(1.5)
2504
+
2505
+ textarea = @driver.find_element(:css, 'textarea.comment_inbox_text')
2506
+ textarea.send_keys(content)
2507
+ sleep(1)
2508
+
2509
+ if option['이모티콘자동삽입'] == 'true'
2510
+ puts "이모티콘 자동 삽입 옵션 진행!!".cyan
2511
+ reply_comments = @driver.find_elements(:css, 'li.CommentItem.CommentItem--reply')
2512
+ reply_comments.each_with_index do |item, index|
2513
+ begin
2514
+
2515
+
2516
+ # 해당 대댓글 내부의 이모티콘 버튼 찾기
2517
+ sticker_button = item.find_element(:css, 'a.button_sticker')
2518
+ sticker_button.click
2519
+ sleep(1)
2520
+
2521
+ rescue
2522
+ end
2523
+ end
2524
+
2525
+ begin
2526
+ # 'se2_line_sticker_set' 클래스를 가진 <ul> 요소 안의 모든 <li> 요소 찾기
2527
+ sticker_list_elements = wait.until { @driver.find_elements(:css, '.se2_line_sticker_set li') }
2528
+
2529
+ # 16개 <li> 요소 중 랜덤으로 하나 선택하여 클릭
2530
+ random_li = sticker_list_elements.sample
2531
+ random_button = random_li.find_element(:tag_name, 'button') # <button> 태그 찾기
2532
+ random_button.click
2533
+
2534
+ sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
2535
+
2536
+ # 첫 번째 클릭한 <li> 내에서 버튼을 찾기
2537
+ inner_buttons = random_li.find_elements(:tag_name, 'button')
2538
+
2539
+ # 20개 <button> 요소 중 랜덤으로 하나 선택하여 클릭
2540
+ random_button_in_li = inner_buttons.sample
2541
+ sleep(1)
2542
+ random_button_in_li.click
2543
+
2544
+ sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
2545
+
2546
+ rescue Selenium::WebDriver::Error::StaleElementReferenceError => e
2547
+ #puts "Stale element reference 오류 발생, 계속 진행: #{e.message}".yellow
2548
+ # 오류 발생 시에도 계속 진행하려면 작업을 계속하도록 처리
2549
+ # 예를 들어, continue, or next 등으로 다음 단계로 넘어갈 수 있습니다.
2550
+
2551
+ rescue => e
2552
+ puts "기타 오류로 인해 이모티콘 삽입 안됨"
2553
+ # 기타 오류 처리
2554
+ # 여기에 추가적인 예외 처리 로직을 넣을 수 있습니다.
2555
+ end
2556
+ else
2557
+ puts "이모티콘 자동 삽입 옵션이 비활성화됨."
2558
+ end
2559
+
2560
+ # 이미지 자동 삽입
2561
+ if option['이미지자동삽입'] == 'true'
2562
+ puts "이미지 자동 상입 옵션 진행!!".cyan
2563
+
2564
+ # 아이프레임 요소가 나타날 때까지 기다립니다.
2565
+ @image = image
2566
+ image_path = image
2567
+ reply_comments = @driver.find_elements(:css, 'li.CommentItem.CommentItem--reply')
2568
+
2569
+ reply_comments.each_with_index do |item, index|
2570
+ begin
2571
+
2572
+
2573
+ # 해당 대댓글 내부에서 for="attach2"인 라벨 클릭
2574
+ attach_button = item.find_element(:xpath, './/*[@class="button_file"]')
2575
+ attach_button.click
2576
+ sleep(1)
2577
+
2578
+ rescue
2579
+ end
2580
+ end
2581
+ key_stroke('escape')
2582
+ # 파일 경로 자동 입력
2583
+ file_input = @driver.find_element(:xpath, '//*[@title="사진첨부"]')
2584
+
2585
+ # send_keys로 파일 경로를 입력하여 이미지 업로드
2586
+ file_input.send_keys(image_path)
2587
+ sleep(2)
2588
+
2589
+ else
2590
+ end
2591
+
2592
+ register_btn = @driver.find_element(:css, 'a.button.btn_register')
2593
+ register_btn.click
2594
+ sleep(2)
2595
+
2596
+ puts "#{index + 1}번째 댓글에 대댓글 작성 완료"
2597
+ rescue => e
2598
+ puts "댓글 인덱스 #{index + 1} 처리 중 오류 발생: #{e.message}"
2599
+ end
2600
+ else
2601
+ puts "해당 인덱스(#{index + 1})의 답글쓰기 버튼이 없습니다."
2602
+ end
2603
+
2604
+ else # 닉네임으로 찾기
2605
+ comment_items = @driver.find_elements(:css, 'li.CommentItem')
2606
+ original_comments = comment_items.select { |item| !item.attribute('class').include?('CommentItem--reply') }
2607
+
2608
+ matched = false
2609
+ last_matched_item = nil # 마지막에 닉네임이 일치한 댓글 저장
2610
+
2611
+ original_comments.each_with_index do |item, idx|
2612
+ begin
2613
+ nickname_element = item.find_element(:css, 'a.comment_nickname')
2614
+ nickname = nickname_element.text.strip
2615
+
2616
+ if nickname.include?(target)
2617
+ puts "#{target} 닉네임이 포함된 댓글 발견 (#{idx + 1}번째)"
2618
+ last_matched_item = item # 매번 갱신 → 마지막에 발견된 걸 저장
2619
+ end
2620
+ rescue => e
2621
+ puts "닉네임 검사 중 오류 발생: #{e.message}"
2622
+ next
2623
+ end
2624
+ end
2625
+
2626
+ # 루프 끝난 뒤 마지막 댓글에만 작업 실행
2627
+ if last_matched_item
2628
+ begin
2629
+
2630
+ if @data['포스트설정']['순서사용2'].checked?
2631
+ @content_soon ||= 0 # 초기 한 번만 0으로 세팅
2632
+
2633
+ if @data['내용설정']['내용'].nil? || @data['내용설정']['내용'].empty?
2634
+ content = ''
2635
+ else
2636
+ if @data.dig('내용설정', '랜덤사용')&.respond_to?(:checked?) && @data['내용설정']['랜덤사용'].checked?
2637
+ content = @data['내용설정']['내용'].sample[2]
2638
+ else
2639
+ content = @data['내용설정']['내용'][@content_soon][2]
2640
+ @content_soon += 1
2641
+ @content_soon = 0 if @content_soon >= @data['내용설정']['내용'].length
2642
+ end
2643
+ end
2644
+ else
2645
+ end
2646
+
2647
+ # 디엠 자동 변경이 체크된 경우 content를 변환
2648
+ if @data['포스트설정']['내용자동변경'].checked?
2649
+ change_memory = {}
2650
+ @data['포스트설정']['내용자동변경값'].each do |key, v|
2651
+ change_memory[key] = v.sample
2652
+ end
2653
+ @data['포스트설정']['내용자동변경값'].each do |key, _|
2654
+ if content.include?(key)
2655
+ content = content.gsub(key, change_memory[key]) # gsub을 사용하여 내용 치환
2656
+ else
2657
+ end
2658
+ end
2659
+ end
1107
2660
 
1108
- if @data['포스트설정']['순서사용2'].checked?
1109
- @content_soon ||= 0 # 초기 번만 0으로 세팅
2661
+ if option['ChatGPT사용'] == 'true'
2662
+ pcol1 = @driver.find_element(:css, 'div.title_area > h3.title_text').text
2663
+ sleep(1)
2664
+
2665
+ puts "ChatGPT로 댓글을 만드는 중입니다."
2666
+ @api_key = api_key
2667
+ url = 'https://api.openai.com/v1/chat/completions'
2668
+ headers = {
2669
+ 'Content-Type' => 'application/json',
2670
+ 'Authorization' => 'Bearer ' + @api_key
2671
+ }
2672
+ data = {
2673
+ 'model' => 'gpt-3.5-turbo',
2674
+ 'messages' => [
2675
+ { "role" => "system", "content" => "해당 제목에 알맞은 댓글을 짧게 한 개만 만들어줘" },
2676
+ { "role" => "user", "content" => pcol1 } # pcol1 직접 사용
2677
+ ]
2678
+ }
2679
+
2680
+ begin
2681
+ req = HTTP.headers(headers).post(url, json: data)
2682
+ puts "HTTP Status: #{req.status}" # 상태 코드 확인
2683
+ response = JSON.parse(req.body.to_s)
2684
+ puts "API Response: #{response}" # 전체 응답 출력
2685
+
2686
+ if req.status == 429
2687
+ return "API 요청 제한을 초과했습니다. 플랜 및 할당량을 확인하세요."
2688
+ end
2689
+
2690
+ # 응답 데이터에서 안전하게 값 추출
2691
+ raw_content = response.dig('choices', 0, 'message', 'content') || "댓글 생성을 실패했습니다." # 응답이 없을 경우 기본 메시지 설정
2692
+ content = raw_content.gsub(/\. /, ".\n") # 줄바꿈 추가
2693
+
2694
+ rescue => e
2695
+ puts "Error: #{e.message}"
2696
+ content = "오류가 발생했습니다."
2697
+ end
2698
+ else
2699
+ end
2700
+
2701
+ reply_button = last_matched_item.find_element(:css, 'a.comment_info_button')
2702
+ reply_button.click
2703
+ sleep(1.5)
2704
+
2705
+ textarea = @driver.find_element(:css, 'textarea.comment_inbox_text')
2706
+ textarea.send_keys(content)
2707
+ sleep(1)
2708
+
2709
+ if option['이모티콘자동삽입'] == 'true'
2710
+ puts "이모티콘 자동 삽입 옵션 진행!!".cyan
2711
+ reply_comments = @driver.find_elements(:css, 'li.CommentItem.CommentItem--reply')
2712
+ reply_comments.each_with_index do |item, index|
2713
+ begin
2714
+
2715
+ sticker_button = item.find_element(:css, 'a.button_sticker')
2716
+ sticker_button.click
2717
+ sleep(1)
2718
+ rescue
2719
+ end
2720
+ end
2721
+ begin
2722
+ sticker_list_elements = wait.until { @driver.find_elements(:css, '.se2_line_sticker_set li') }
2723
+ random_li = sticker_list_elements.sample
2724
+ random_button = random_li.find_element(:tag_name, 'button')
2725
+ random_button.click
2726
+ sleep(1)
2727
+ inner_buttons = random_li.find_elements(:tag_name, 'button')
2728
+ random_button_in_li = inner_buttons.sample
2729
+ sleep(1)
2730
+ random_button_in_li.click
2731
+ sleep(1)
2732
+ rescue Selenium::WebDriver::Error::StaleElementReferenceError
2733
+ rescue => e
2734
+ puts "기타 오류로 인해 이모티콘 삽입 안됨"
2735
+ end
2736
+ else
2737
+ puts "이모티콘 자동 삽입 옵션이 비활성화됨."
2738
+ end
1110
2739
 
1111
- if @data['내용설정']['내용'].nil? || @data['내용설정']['내용'].empty?
1112
- content = ''
1113
- else
1114
- if @data.dig('내용설정', '랜덤사용')&.respond_to?(:checked?) && @data['내용설정']['랜덤사용'].checked?
1115
- content = @data['내용설정']['내용'].sample[2]
1116
- else
1117
- content = @data['내용설정']['내용'][@content_soon][2]
1118
- @content_soon += 1
1119
- @content_soon = 0 if @content_soon >= @data['내용설정']['내용'].length
1120
- end
1121
- end
1122
- else
1123
- end
1124
-
1125
- # 디엠 자동 변경이 체크된 경우 content를 변환
1126
- if @data['포스트설정']['내용자동변경'].checked?
1127
- change_memory = {}
1128
- @data['포스트설정']['내용자동변경값'].each do |key, v|
1129
- change_memory[key] = v.sample
1130
- end
1131
- @data['포스트설정']['내용자동변경값'].each do |key, _|
1132
- if content.include?(key)
1133
- content = content.gsub(key, change_memory[key]) # gsub을 사용하여 내용 치환
1134
- else
1135
- end
1136
- end
1137
- end
2740
+ if option['이미지자동삽입'] == 'true'
2741
+ puts "이미지 자동 삽입 옵션 진행!!".cyan
2742
+ @image = image
2743
+ image_path = image
2744
+ reply_comments = @driver.find_elements(:css, 'li.CommentItem.CommentItem--reply')
2745
+ reply_comments.each_with_index do |item, index|
2746
+ begin
2747
+
2748
+ attach_button = item.find_element(:xpath, './/*[@class="button_file"]')
2749
+ attach_button.click
2750
+ sleep(1)
2751
+ rescue
2752
+ end
2753
+ end
2754
+ key_stroke('escape')
2755
+ file_input = @driver.find_element(:xpath, '//*[@title="사진첨부"]')
2756
+ file_input.send_keys(image_path)
2757
+ sleep(2)
2758
+ end
1138
2759
 
1139
- if option['좋아요'] == 'true'
1140
- puts "좋아요 클릭 옵션 진행!!".cyan
1141
- wait = Selenium::WebDriver::Wait.new(:timeout => 10)
1142
- wait.until { @driver.find_element(:xpath, '//*[@class="u_ico _icon"]') }
2760
+ register_btn = @driver.find_element(:css, 'a.button.btn_register')
2761
+ register_btn.click
2762
+ sleep(2)
1143
2763
 
1144
- # 댓글 입력
1145
- element = @driver.find_element(:xpath, '//*[@class="u_ico _icon"]')
1146
- @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element)#크롤 이동
1147
- sleep(1)
2764
+ matched = true
2765
+ rescue => e
2766
+ puts "대댓글 등록 오류 발생: #{e.message}"
2767
+ end
2768
+ end
2769
+
2770
+ puts "닉네임 '#{target}'을 포함한 댓글을 찾지 못했습니다." unless matched
1148
2771
 
1149
- # 좋아요 버튼을 찾기
1150
- like_button = @driver.find_element(:xpath, '//div[@class="ReactionLikeIt u_likeit_list_module _cafeReactionModule"]//a[@role="button"]')
2772
+ end
2773
+ end
1151
2774
 
1152
- # aria-pressed 속성 값 확인
1153
- aria_pressed = like_button.attribute('aria-pressed')
2775
+ end
1154
2776
 
1155
- if aria_pressed == 'true'
1156
- # 이미 좋아요를 누른 상태일 경우
1157
-
1158
- else
1159
- # 좋아요를 아직 누르지 않은 상태일 경우 클릭
1160
- @driver.find_element(:xpath, '//*[@class="u_ico _icon"]').click
1161
- sleep(2)
1162
- end
1163
- else
1164
- end
2777
+ elsif option['re_coment'] == 'false' # 대 댓글 아닐때
2778
+ if @data['포스트설정']['순서사용2'].checked?
2779
+ @content_soon ||= 0 # 초기 한 번만 0으로 세팅
1165
2780
 
1166
-
1167
-
2781
+ if @data['내용설정']['내용'].nil? || @data['내용설정']['내용'].empty?
2782
+ content = ''
2783
+ else
2784
+ if @data.dig('내용설정', '랜덤사용')&.respond_to?(:checked?) && @data['내용설정']['랜덤사용'].checked?
2785
+ content = @data['내용설정']['내용'].sample[2]
2786
+ else
2787
+ content = @data['내용설정']['내용'][@content_soon][2]
2788
+ @content_soon += 1
2789
+ @content_soon = 0 if @content_soon >= @data['내용설정']['내용'].length
2790
+ end
2791
+ end
2792
+ else
2793
+ end
2794
+
2795
+ # 디엠 자동 변경이 체크된 경우 content를 변환
2796
+ if @data['포스트설정']['내용자동변경'].checked?
2797
+ change_memory = {}
2798
+ @data['포스트설정']['내용자동변경값'].each do |key, v|
2799
+ change_memory[key] = v.sample
2800
+ end
2801
+ @data['포스트설정']['내용자동변경값'].each do |key, _|
2802
+ if content.include?(key)
2803
+ content = content.gsub(key, change_memory[key]) # gsub을 사용하여 내용 치환
2804
+ else
2805
+ end
2806
+ end
2807
+ end
1168
2808
 
1169
- begin
1170
- wait = Selenium::WebDriver::Wait.new(:timeout => 10)
1171
- wait.until { @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]') }
2809
+ if option['ChatGPT사용'] == 'true'
2810
+ pcol1 = @driver.find_element(:css, 'div.title_area > h3.title_text').text
2811
+ sleep(1)
2812
+
2813
+ puts "ChatGPT로 댓글을 만드는 중입니다."
2814
+ @api_key = api_key
2815
+ url = 'https://api.openai.com/v1/chat/completions'
2816
+ headers = {
2817
+ 'Content-Type' => 'application/json',
2818
+ 'Authorization' => 'Bearer ' + @api_key
2819
+ }
2820
+ data = {
2821
+ 'model' => 'gpt-3.5-turbo',
2822
+ 'messages' => [
2823
+ { "role" => "system", "content" => "해당 제목에 알맞은 댓글을 짧게 한 개만 만들어줘" },
2824
+ { "role" => "user", "content" => pcol1 } # pcol1 직접 사용
2825
+ ]
2826
+ }
2827
+
2828
+ begin
2829
+ req = HTTP.headers(headers).post(url, json: data)
2830
+ puts "HTTP Status: #{req.status}" # 상태 코드 확인
2831
+ response = JSON.parse(req.body.to_s)
2832
+ puts "API Response: #{response}" # 전체 응답 출력
2833
+
2834
+ if req.status == 429
2835
+ return "API 요청 제한을 초과했습니다. 플랜 및 할당량을 확인하세요."
2836
+ end
2837
+
2838
+ # 응답 데이터에서 안전하게 값 추출
2839
+ raw_content = response.dig('choices', 0, 'message', 'content') || "댓글 생성을 실패했습니다." # 응답이 없을 경우 기본 메시지 설정
2840
+ content = raw_content.gsub(/\. /, ".\n") # 줄바꿈 추가
2841
+
2842
+ rescue => e
2843
+ puts "Error: #{e.message}"
2844
+ content = "오류가 발생했습니다."
2845
+ end
2846
+ else
2847
+ end
1172
2848
 
1173
- # 댓글 입력
1174
- element = @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]')
1175
- @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element)#크롤 이동
1176
- sleep(1)
1177
- if option['ChatGPT사용'] == 'true'
1178
- pcol1 = @driver.find_element(:css, 'div.title_area > h3.title_text').text
1179
- sleep(1)
1180
-
1181
- puts "ChatGPT로 댓글을 만드는 중입니다."
1182
- @api_key = api_key
1183
- url = 'https://api.openai.com/v1/chat/completions'
1184
- headers = {
1185
- 'Content-Type' => 'application/json',
1186
- 'Authorization' => 'Bearer ' + @api_key
1187
- }
1188
- data = {
1189
- 'model' => 'gpt-3.5-turbo',
1190
- 'messages' => [
1191
- { "role" => "system", "content" => "해당 제목에 알맞은 댓글을 짧게 한 개만 만들어줘" },
1192
- { "role" => "user", "content" => pcol1 } # pcol1 직접 사용
1193
- ]
1194
- }
1195
-
1196
- begin
1197
- req = HTTP.headers(headers).post(url, json: data)
1198
- puts "HTTP Status: #{req.status}" # 상태 코드 확인
1199
- response = JSON.parse(req.body.to_s)
1200
- puts "API Response: #{response}" # 전체 응답 출력
1201
-
1202
- if req.status == 429
1203
- return "API 요청 제한을 초과했습니다. 플랜 및 할당량을 확인하세요."
1204
- end
1205
-
1206
- # 응답 데이터에서 안전하게 값 추출
1207
- raw_answer = response.dig('choices', 0, 'message', 'content') || "댓글 생성을 실패했습니다." # 응답이 없을 경우 기본 메시지 설정
1208
- answer = raw_answer.gsub(/\. /, ".\n") # 줄바꿈 추가
1209
-
1210
- rescue => e
1211
- puts "Error: #{e.message}"
1212
- answer = "오류가 발생했습니다."
1213
- end
1214
-
1215
- # 댓글 입력
1216
- @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]').send_keys(answer)
1217
- sleep(1)
1218
- else
1219
- begin
1220
- puts (content)
1221
- @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]').send_keys(content)
2849
+ wait = Selenium::WebDriver::Wait.new(timeout: 10)
2850
+ wait.until { @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]') }
2851
+
2852
+ element = @driver.find_element(:xpath, '//*[@placeholder="댓글을 남겨보세요"]')
2853
+ @driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'})", element)
1222
2854
  sleep(1)
1223
- rescue
1224
- end
1225
- end
1226
-
1227
- # 이모티콘 자동 삽입
1228
- if option['이모티콘자동삽입'] == 'true'
1229
- puts "이모티콘 자동 삽입 옵션 진행!!".cyan
1230
-
1231
- # '이모티콘' 버튼 클릭
1232
- @driver.find_element(:xpath, '//*[@class="button_sticker"]').click
1233
- sleep(1)
1234
-
1235
- begin
1236
- # 'se2_line_sticker_set' 클래스를 가진 <ul> 요소 안의 모든 <li> 요소 찾기
1237
- sticker_list_elements = wait.until { @driver.find_elements(:css, '.se2_line_sticker_set li') }
1238
-
1239
- # 16개 <li> 요소 중 랜덤으로 하나 선택하여 클릭
1240
- random_li = sticker_list_elements.sample
1241
- random_button = random_li.find_element(:tag_name, 'button') # <button> 태그 찾기
1242
- random_button.click
2855
+
2856
+ element.send_keys(content)
2857
+ sleep(1)
2858
+
2859
+ # 이모티콘 자동 삽입
2860
+ if option['이모티콘자동삽입'] == 'true'
2861
+ puts "이모티콘 자동 삽입 옵션 진행!!".cyan
2862
+
2863
+ # '이모티콘' 버튼 클릭
2864
+ @driver.find_element(:xpath, '//*[@class="button_sticker"]').click
2865
+ sleep(1)
2866
+
2867
+ begin
2868
+ # 'se2_line_sticker_set' 클래스를 가진 <ul> 요소 안의 모든 <li> 요소 찾기
2869
+ sticker_list_elements = wait.until { @driver.find_elements(:css, '.se2_line_sticker_set li') }
2870
+
2871
+ # 16개 <li> 요소 중 랜덤으로 하나 선택하여 클릭
2872
+ random_li = sticker_list_elements.sample
2873
+ random_button = random_li.find_element(:tag_name, 'button') # <button> 태그 찾기
2874
+ random_button.click
2875
+
2876
+ sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
2877
+
2878
+ # 첫 번째 클릭한 <li> 내에서 버튼을 찾기
2879
+ inner_buttons = random_li.find_elements(:tag_name, 'button')
2880
+
2881
+ # 20개 <button> 요소 중 랜덤으로 하나 선택하여 클릭
2882
+ random_button_in_li = inner_buttons.sample
2883
+ sleep(1)
2884
+ random_button_in_li.click
2885
+
2886
+ sleep(1) # 클릭 후 잠시 대기 (로딩 시간 고려)
2887
+
2888
+ rescue Selenium::WebDriver::Error::StaleElementReferenceError => e
2889
+ #puts "Stale element reference 오류 발생, 계속 진행: #{e.message}".yellow
2890
+ # 오류 발생 시에도 계속 진행하려면 작업을 계속하도록 처리
2891
+ # 예를 들어, continue, or next 등으로 다음 단계로 넘어갈 수 있습니다.
2892
+
2893
+ rescue => e
2894
+ puts "기타 오류로 인해 이모티콘 삽입 안됨"
2895
+ # 기타 오류 처리
2896
+ # 여기에 추가적인 예외 처리 로직을 넣을 수 있습니다.
2897
+ end
2898
+ else
2899
+ puts "이모티콘 자동 삽입 옵션이 비활성화됨."
2900
+ end
1243
2901
 
1244
- sleep(1) # 클릭 잠시 대기 (로딩 시간 고려)
1245
-
1246
- # 번째 클릭한 <li> 내에서 버튼을 찾기
1247
- inner_buttons = random_li.find_elements(:tag_name, 'button')
2902
+ # 이미지 자동 삽입
2903
+ if option['이미지자동삽입'] == 'true'
2904
+ puts "이미지 자동 상입 옵션 진행!!".cyan
1248
2905
 
1249
- # 20개 <button> 요소 랜덤으로 하나 선택하여 클릭
1250
- random_button_in_li = inner_buttons.sample
1251
- sleep(1)
1252
- random_button_in_li.click
2906
+ # 아이프레임 요소가 나타날 때까지 기다립니다.
2907
+ @image = image
2908
+ image_path = image
2909
+
2910
+ @driver.find_element(:xpath, '//*[@for="attach2"]').click
2911
+ sleep(1)
2912
+ key_stroke('escape')
2913
+ # 파일 경로 자동 입력
2914
+ file_input = @driver.find_element(:xpath, '//*[@class="button_file"]')
1253
2915
 
1254
- sleep(1) # 클릭 잠시 대기 (로딩 시간 고려)
1255
-
1256
- rescue Selenium::WebDriver::Error::StaleElementReferenceError => e
1257
- #puts "Stale element reference 오류 발생, 계속 진행: #{e.message}".yellow
1258
- # 오류 발생 시에도 계속 진행하려면 작업을 계속하도록 처리
1259
- # 예를 들어, continue, or next 등으로 다음 단계로 넘어갈 수 있습니다.
1260
-
1261
- rescue => e
1262
- puts "기타 오류로 인해 이모티콘 삽입 안됨"
1263
- # 기타 오류 처리
1264
- # 여기에 추가적인 예외 처리 로직을 넣을 수 있습니다.
1265
- end
1266
- else
1267
- puts "이모티콘 자동 삽입 옵션이 비활성화됨."
1268
- end
1269
-
1270
- # 이미지 자동 삽입
1271
- if option['이미지자동삽입'] == 'true'
1272
- puts "이미지 자동 상입 옵션 진행!!".cyan
2916
+ # send_keys로 파일 경로를 입력하여 이미지 업로드
2917
+ file_input.send_keys(image_path)
2918
+ sleep(2)
2919
+
2920
+ else
2921
+ end
1273
2922
 
1274
- # 아이프레임 요소가 나타날 때까지 기다립니다.
1275
- @image = image
1276
- image_path = image
1277
-
1278
- @driver.find_element(:xpath, '//*[@for="attach2"]').click
1279
- sleep(1)
1280
- key_stroke('escape')
1281
- # 파일 경로 자동 입력
1282
- file_input = @driver.find_element(:xpath, '//*[@id="attach2"]')
2923
+
2924
+ wait.until { @driver.find_element(:xpath, '//*[@class="button btn_register is_active"]') }
2925
+ @driver.find_element(:xpath, '//*[@class="button btn_register is_active"]').click
2926
+ sleep(2)
2927
+ posting_url = @driver.current_url
2928
+ puts "#{posting_url} [댓글 진행 완료 !!]".cyan
2929
+ end
1283
2930
 
1284
- # send_keys로 파일 경로를 입력하여 이미지 업로드
1285
- file_input.send_keys(image_path)
1286
- sleep(2)
1287
2931
 
1288
- else
1289
- end
1290
2932
 
1291
-
1292
-
1293
- wait.until { @driver.find_element(:xpath, '//*[@class="button btn_register is_active"]') }
1294
- @driver.find_element(:xpath, '//*[@class="button btn_register is_active"]').click
1295
- puts "#{board_url} [댓글 작성 완료 !!]".cyan
1296
- sleep(2)
1297
2933
  begin
1298
2934
  @driver.switch_to.alert
1299
2935
  sleep(1)
@@ -1334,26 +2970,28 @@ class Naver
1334
2970
  ff.close()
1335
2971
  puts '-[√] 로그 파일 생성 완료.......'.yellow
1336
2972
  end
1337
- end
1338
- end
1339
- @driver.switch_to.default_content() # 아이프레임 해제
1340
- def sleep_with_progress(sleep_delay)
1341
- print "[설정 딜레이 진행 중] "
1342
- steps = (sleep_delay.to_f / 0.5).to_i
1343
- steps.times do
1344
- print "."
1345
- STDOUT.flush
1346
- sleep(1)
2973
+ end
2974
+
2975
+
2976
+ @driver.switch_to.default_content() # 아이프레임 해제
2977
+ def sleep_with_progress(sleep_delay)
2978
+ print "[설정 딜레이 진행 중] "
2979
+ steps = (sleep_delay.to_f / 0.5).to_i
2980
+ steps.times do
2981
+ print "."
2982
+ STDOUT.flush
2983
+ sleep(1)
2984
+ end
2985
+ puts "\n"
1347
2986
  end
1348
- puts "\n"
1349
- end
1350
- sleep_with_progress(sleep_delay)
1351
-
1352
2987
 
1353
- rescue => e
2988
+ sleep_with_progress(sleep_delay)
2989
+
2990
+
2991
+ rescue => e
1354
2992
  puts "Error: #{e.message}"
1355
- end
1356
- end
2993
+ end
2994
+ end
1357
2995
  else
1358
2996
  end
1359
2997
 
@@ -1500,7 +3138,7 @@ end
1500
3138
  # 상태 표시 퍼샌테이지 아래 [7]넘버는 게이지바에 맞게 넘버를 넣어줘야 작동됨
1501
3139
  while true
1502
3140
  for n in 0..@data['table'].length-1
1503
- @data['table'][n][7] = 0
3141
+ @data['table'][n][8] = 0
1504
3142
  end
1505
3143
 
1506
3144
  while true
@@ -1513,7 +3151,18 @@ end
1513
3151
  next
1514
3152
  end
1515
3153
 
1516
-
3154
+ if table[4] == true
3155
+ option['re_coment'] = 'true'
3156
+ if @data['포스트설정']['전체대댓글'].checked?
3157
+
3158
+ elsif @data['포스트설정']['지정대댓글'].checked?
3159
+ nik_or_number = @data['포스트설정']['nik_or_number'].text.to_s.force_encoding('utf-8')
3160
+ puts nik_or_number
3161
+ else
3162
+ end
3163
+ else
3164
+ option['re_coment'] = 'false'
3165
+ end
1517
3166
 
1518
3167
 
1519
3168
  option['proxy'] = ''
@@ -1525,7 +3174,7 @@ end
1525
3174
  end
1526
3175
  end
1527
3176
 
1528
- if table[6].to_i > table[7].to_i #시작 부분 설정을 맞게해줘야 실행이 됨
3177
+ if table[7].to_i > table[8].to_i #시작 부분 설정을 맞게해줘야 실행이 됨
1529
3178
  #if table[6].to_i #시작 부분 설정을 맞게해줘야 실행이 됨
1530
3179
 
1531
3180
  if @data['포스트설정']['테더링'].checked?
@@ -1860,15 +3509,15 @@ end
1860
3509
  # p option
1861
3510
 
1862
3511
  # 댓글 설정 수 카운트
1863
- counts_number = @data['table'][index][5].to_i
3512
+ counts_number = @data['table'][index][6].to_i
1864
3513
  api_key = @data['포스트설정']['api_key'].text.to_s.force_encoding('utf-8')
1865
- sleep_delay = @data['table'][index][4].to_i
3514
+ sleep_delay = @data['table'][index][5].to_i
1866
3515
  naver.update(content,board_url,nickname,image,option,counts_number,keyword,api_key,sleep_delay)
1867
3516
 
1868
3517
 
1869
3518
 
1870
3519
  #완료했으니 수량 카운터
1871
- @data['table'][index][7] = @data['table'][index][7].to_i + 1
3520
+ @data['table'][index][8] = @data['table'][index][8].to_i + 1
1872
3521
  @data['table'][index][-1] = 100
1873
3522
  @data['table'] << []
1874
3523
  @data['table'].pop
@@ -2243,8 +3892,8 @@ end
2243
3892
  button('    댓글 등록 ID 추가    '){
2244
3893
 
2245
3894
  on_clicked {
2246
- @data['table'] << [false, @data['admin_list1'].text,@data['admin_list2'].text,@data['proxy'].text, 1, 2, 1,0,0]
2247
- @data['table'] << [false, @data['admin_list1'].text,@data['admin_list2'].text,@data['proxy'].text, 1, 2, 1,0,0]
3895
+ @data['table'] << [false, @data['admin_list1'].text,@data['admin_list2'].text,@data['proxy'].text,false, 1, 2, 1,0,0]
3896
+ @data['table'] << [false, @data['admin_list1'].text,@data['admin_list2'].text,@data['proxy'].text,false, 1, 2, 1,0,0]
2248
3897
  @data['table'].pop
2249
3898
  }
2250
3899
  }
@@ -2257,8 +3906,8 @@ end
2257
3906
  file_data.split("\n").each do |i|
2258
3907
  i3 = i.to_s.force_encoding('utf-8').to_s
2259
3908
  i2 = i3.split(',')
2260
- @data['table'] << [false, i2[0].to_s, i2[1].to_s,i2[2].to_s, 1,2,1,0,0]
2261
- @data['table'] << [false, i2[0].to_s, i2[1].to_s, 1,2,1,0,0]
3909
+ @data['table'] << [false, i2[0].to_s, i2[1].to_s,i2[2].to_s,['1', 'true'].include?(i2[3].to_s.strip.downcase), 1,2,1,0,0]
3910
+ @data['table'] << [false, i2[0].to_s, i2[1].to_s, false, 1,2,1,0,0]
2262
3911
  @data['table'].pop
2263
3912
  end
2264
3913
  end
@@ -2284,6 +3933,10 @@ end
2284
3933
  text_column('프록시'){
2285
3934
  editable true
2286
3935
  }
3936
+
3937
+ checkbox_column('대댓글작업') {
3938
+ editable true
3939
+ }
2287
3940
 
2288
3941
  text_column('딜레이'){
2289
3942
  editable true
@@ -2378,9 +4031,9 @@ end
2378
4031
  table_counter_again = @data['table_counter_again'].text.to_i
2379
4032
  # @data['table']의 각 항목을 업데이트
2380
4033
  @data['table'].map! do |row|
2381
- row[4] = table_delay_input
2382
- row[5] = table_counter_input
2383
- row[6] = table_counter_again
4034
+ row[5] = table_delay_input
4035
+ row[6] = table_counter_input
4036
+ row[7] = table_counter_again
2384
4037
  row # 수정된 row를 반환
2385
4038
  end
2386
4039
  }
@@ -3172,6 +4825,33 @@ end
3172
4825
  end
3173
4826
  }
3174
4827
  }
4828
+ @data['포스트설정']['전체대댓글'] = checkbox('대 댓글 전체 타겟(옵션1) '){
4829
+ top 1
4830
+ left 3
4831
+ on_toggled{
4832
+ if @data['포스트설정']['전체대댓글'].checked?
4833
+ @data['포스트설정']['지정대댓글'].checked = false
4834
+ end
4835
+ }
4836
+ }
4837
+ @data['포스트설정']['지정대댓글'] = checkbox('대 댓글 지정 타겟(옵션2)'){
4838
+ top 1
4839
+ left 4
4840
+ on_toggled{
4841
+ if @data['포스트설정']['지정대댓글'].checked?
4842
+ @data['포스트설정']['전체대댓글'].checked = false
4843
+ end
4844
+ }
4845
+ }
4846
+ @data['포스트설정']['nik_or_number'] = entry(){
4847
+ top 1
4848
+ left 5
4849
+ text '예)마루 or 예)1(댓글넘버)'
4850
+ }
4851
+ label('콤마로 추가 가능 예)마루,강쥐 or 예)1,3'){
4852
+ top 1
4853
+ left 6
4854
+ }
3175
4855
 
3176
4856
  }
3177
4857
  }