128 lines
4.5 KiB
Python
Executable File
128 lines
4.5 KiB
Python
Executable File
#!/usr/bin/python3
|
|
|
|
import os
|
|
import re # 정규 표현식 모듈
|
|
import uuid # 고유 식별자 생성 모듈
|
|
import requests # HTTP 요청을 처리하는 모듈
|
|
import rsa # RSA 암호화 알고리즘 모듈
|
|
import lzstring # LZ-String 압축 알고리즘 모듈
|
|
from urllib3.util.retry import Retry # HTTP 요청 재시도를 위한 모듈
|
|
from requests.adapters import HTTPAdapter # HTTP 어댑터
|
|
import time # 시간 처리 모듈
|
|
from bs4 import BeautifulSoup # HTML/XML 파서
|
|
from urllib.parse import urljoin # URL 조합 함수
|
|
|
|
# 주어진 키와 사용자 정보를 이용하여 암호화하는 함수
|
|
def encrypt(key_str, uid, upw):
|
|
# 문자열을 조합하는 함수
|
|
def naver_style_join(l):
|
|
return ''.join([chr(len(s)) + s for s in l])
|
|
|
|
# 암호화 키 분리 및 정수 변환
|
|
sessionkey, keyname, e_str, n_str = key_str.split(',')
|
|
e, n = int(e_str, 16), int(n_str, 16)
|
|
|
|
# 메시지 조합 및 인코딩
|
|
message = naver_style_join([sessionkey, uid, upw]).encode()
|
|
|
|
# 공개키 생성 및 메시지 암호화
|
|
pubkey = rsa.PublicKey(e, n)
|
|
encrypted = rsa.encrypt(message, pubkey)
|
|
|
|
return keyname, encrypted.hex()
|
|
|
|
# 사용자 계정을 암호화하는 함수
|
|
def encrypt_account(uid, upw):
|
|
key_str = requests.get('https://nid.naver.com/login/ext/keys.nhn').content.decode("utf-8")
|
|
return encrypt(key_str, uid, upw)
|
|
|
|
# 네이버 세션 생성 함수
|
|
def naver_session(nid, npw):
|
|
encnm, encpw = encrypt_account(nid, npw)
|
|
|
|
# HTTP 세션 설정
|
|
s = requests.Session()
|
|
retries = Retry(total=5, backoff_factor=0.1, status_forcelist=[500, 502, 503, 504])
|
|
s.mount('https://', HTTPAdapter(max_retries=retries))
|
|
request_headers = {'User-agent': 'Mozilla/5.0'}
|
|
|
|
# 인증 데이터 생성 및 압축
|
|
bvsd_uuid = uuid.uuid4()
|
|
encData = '{"a":"%s-4","b":"1.3.4","d":[{"i":"id","b":{"a":["0,%s"]},"d":"%s","e":false,"f":false},{"i":"%s","e":true,"f":false}],"h":"1f","i":{"a":"Mozilla/5.0"}}' % (bvsd_uuid, nid, nid, npw)
|
|
bvsd = '{"uuid":"%s","encData":"%s"}' % (bvsd_uuid, lzstring.LZString.compressToEncodedURIComponent(encData))
|
|
|
|
# 로그인 요청 및 최종 URL 접속
|
|
resp = s.post('https://nid.naver.com/nidlogin.login', data={'svctype': '0', 'enctp': '1', 'encnm': encnm, 'enc_url': 'http0X0.0000000000001P-10220.0000000.000000www.naver.com', 'url': 'www.naver.com', 'smart_level': '1', 'encpw': encpw, 'bvsd': bvsd}, headers=request_headers)
|
|
finalize_url = re.search(r'location\.replace\("([^"]+)"\)', resp.content.decode("utf-8")).group(1)
|
|
s.get(finalize_url)
|
|
|
|
return s
|
|
|
|
# 네이버 캠페인 링크를 찾는 함수
|
|
def find_naver_campaign_links(base_url, visited_urls_file='/tmp/visited_urls.txt'):
|
|
# 방문한 URL 파일에서 읽기
|
|
try:
|
|
with open(visited_urls_file, 'r') as file:
|
|
visited_urls = set(file.read().splitlines())
|
|
except FileNotFoundError:
|
|
visited_urls = set()
|
|
|
|
# 기본 URL에 대한 요청
|
|
response = requests.get(base_url)
|
|
soup = BeautifulSoup(response.text, 'html.parser')
|
|
|
|
# 'list_subject' 클래스를 가진 span 요소 찾기 및 'a' 태그 추출
|
|
list_subject_links = soup.find_all('span', class_='list_subject')
|
|
naver_links = []
|
|
for span in list_subject_links:
|
|
a_tag = span.find('a', href=True)
|
|
if a_tag and '네이버' in a_tag.text:
|
|
#print(a_tag['href'])
|
|
naver_links.append(a_tag['href'])
|
|
|
|
# 캠페인 링크를 저장할 리스트 초기화
|
|
campaign_links = []
|
|
|
|
# 각 네이버 링크 확인
|
|
for link in naver_links:
|
|
full_link = urljoin(base_url, link)
|
|
if full_link in visited_urls:
|
|
print(link + " already visited!")
|
|
continue # 이미 방문한 링크는 건너뛰기
|
|
|
|
res = requests.get(full_link)
|
|
inner_soup = BeautifulSoup(res.text, 'html.parser')
|
|
|
|
# 캠페인 URL로 시작하는 링크 찾기
|
|
for a_tag in inner_soup.find_all('a', href=True):
|
|
if a_tag['href'].startswith("https://campaign2-api.naver.com"):
|
|
campaign_links.append(a_tag['href'])
|
|
|
|
# 방문한 링크 추가
|
|
visited_urls.add(full_link)
|
|
|
|
# 방문한 URL 파일에 저장
|
|
with open(visited_urls_file, 'w') as file:
|
|
for url in visited_urls:
|
|
file.write(url + '\n')
|
|
|
|
return campaign_links
|
|
|
|
# 시작할 기본 URL
|
|
base_url = "https://www.clien.net/service/board/jirum"
|
|
|
|
# 메인 실행 부분
|
|
if __name__ == "__main__":
|
|
s = naver_session(os.getenv('NAVER_ID'), os.getenv('NAVER_PWD'))
|
|
campaign_links = find_naver_campaign_links(base_url)
|
|
if(campaign_links == []):
|
|
print("All links visited.")
|
|
else:
|
|
for link in campaign_links:
|
|
print(link + "to be visited")
|
|
response = s.get(link)
|
|
#print(response.text) # 디버깅용
|
|
response.raise_for_status()
|
|
time.sleep(5)
|
|
print(link + " done!")
|