일단 설명을 해보자면
나는 전혀 프로그램에 대해 모른다
그냥 챗 GPT에게 질문을 계속해서
만들어낸 코드이다 그래서 나는 이 코드가
어떻게 작동하는지는 모른다
다만 내가 질문해서 만들어 줬기 때문에
어떤동작을 하는지는 안다
내가 원했던건
구글에서 백링크로 작동될 수 있도록
내가 만들어둔 워드프레스 기반 홈페이지에
네이버 블로그의 글을 자동으로 올려주는 기능이다
RSS 제한으로 최근 50개 글 밖에 되지 않지만
조금만 더 응용하면 전체 글을 쓸 수도 있을 것 같다.
사용법은 : 워드프레스에 먼저 플러그인 REST API를 설치해야하고
코드상에서 사이트 주소
관리자 아이디
관리자 비밀번호를 입력후
마지막에 아래에 보면 블로그 주소 끝단에 자기 블로그
아이디를 넣으면 작동한다.
파이썬으로 작동되는데,
입력후에는
1. RSS 에서 최근 50개의 포스팅 주소를 먼저 읽어 온다
2. 읽어온 포스팅 주소 목록을 자동으로 urls.txt라는 문서로만든다
3. txt 파일에서 주소를 차례로 불러온다
4. 불러온 주소에서 본문내용과 첫 이미지를 따온다
5. WP에 자동 포스팅
이게 작동 구조다
요즘 워낙 챗 GPT로 생성된 자동글들이 많아서
이게 무슨 별 의미가 있을 까 싶긴 하지만
홈페이지에서 자료를 쌓아서 백 링크로 이용해 볼까 싶어서
일단 만들어 봤다 직접 옮기자니 귀찮고
간단하게 링크만 걸면 내용이 없으니 챗 GPT에게 시켜서
이렇게 코드를 만들어 봤다.
누가보면 간단한건데 싶겠지만
전혀모르는 상태에서 하려다보니 이걸 잡고
몇일간 gPT와 씨름을 했다.
여튼 모르는 상태에서도 이렇게 완성할 수 있다는게 신기할 따름..
import requests
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from bs4 import BeautifulSoup
import re
import time
import os
# 워드프레스 사이트 설정
wp_site = “사이트 주소”
wp_username = “관리자 아이디”
wp_password = “관리자 비밀번호”
wp_api_url = f“{wp_site}/wp-json/wp/v2”
# RSS 피드 URL
rss_url = ‘https://rss.blog.naver.com/블로그주소’
# JWT 인증 토큰 생성
def get_jwt_token():
auth_url = f“{wp_site}/wp-json/jwt-auth/v1/token”
response = requests.post(auth_url, data={
“username”: wp_username,
“password”: wp_password
})
if response.status_code == 200:
return response.json().get(“token”)
else:
print(“JWT 토큰 생성에 실패했습니다:”, response.text)
return None
# `iframe` 내부의 HTML 소스 가져오기
def fetch_iframe_content(url):
chrome_options = Options()
chrome_options.add_argument(“–headless”) # 브라우저 창을 띄우지 않음
# ChromeDriver 경로 설정
chrome_driver_path = ‘C:/chromedriver/chromedriver.exe’ # ChromeDriver 경로를 실제 설치 경로로 수정
service = Service(chrome_driver_path)
driver = webdriver.Chrome(service=service, options=chrome_options)
driver.get(url)
# 필요한 만큼 기다리기 (동적 콘텐츠가 로드될 시간)
time.sleep(5)
# `iframe`으로 전환
driver.switch_to.frame(“mainFrame”)
# `iframe` 내부의 HTML 소스 가져오기
page_source = driver.page_source
driver.quit()
return page_source
# 포스팅 제목과 내용 추출
def extract_blog_content(html):
soup = BeautifulSoup(html, ‘html.parser’)
# 포스팅 제목 추출
post_title_element = soup.select_one(‘div.se-module.se-module-text.se-title-text’)
if not post_title_element:
post_title_element = soup.select_one(‘div.pcol1’)
post_title = post_title_element.text.strip() if post_title_element else ‘제목 없음’
# 포스팅 내용 추출
post_content_element = soup.select_one(‘div.se-main-container’)
if not post_content_element:
post_content_element = soup.select_one(‘div#postViewArea’)
if not post_content_element:
print(“포스팅 내용을 찾을 수 없습니다.”)
return None
# 전체 텍스트를 한 번만 추출
content_text = post_content_element.get_text(separator=“\n”, strip=True)
images = post_content_element.find_all(‘img’)
image_url = None
for img in images:
if ‘src’ in img.attrs and ‘type=w773’ in img[‘src’]:
image_url = img[‘src’]
break
return {
‘title’: post_title,
‘text’: content_text,
‘image’: image_url
}
# 이미지 다운로드
def download_image(image_url):
response = requests.get(image_url)
if response.status_code == 200:
file_name = os.path.basename(image_url.split(“?”)[0])
with open(file_name, ‘wb’) as file:
file.write(response.content)
return file_name
return None
# 이미지 업로드
def upload_image_to_wp(image_path, token):
headers = {
“Authorization”: f“Bearer {token}”
}
files = {
‘file’: open(image_path, ‘rb’)
}
response = requests.post(f“{wp_api_url}/media”, headers=headers, files=files)
if response.status_code == 201:
print(f“이미지 업로드 성공: {response.json()}”)
return response.json().get(“source_url”)
else:
print(“이미지 업로드에 실패했습니다:”, response.text)
return None
# 워드프레스 포스팅 작성
def create_wp_post(title, content, token, category_id):
headers = {
“Authorization”: f“Bearer {token}”,
“Content-Type”: “application/json”
}
post_data = {
“title”: title,
“content”: content,
“status”: “publish”,
“categories”: [category_id]
}
response = requests.post(f“{wp_api_url}/posts”, headers=headers, json=post_data)
if response.status_code == 201:
print(“포스팅이 성공적으로 작성되었습니다.”)
else:
print(“포스팅 작성에 실패했습니다:”, response.text)
# URL 파일에서 읽어오기
def read_urls_from_file(file_path):
with open(file_path, ‘r’) as file:
urls = [line.strip() for line in file.readlines()]
return urls
# RSS 피드에서 URL 추출 및 파일에 저장
def fetch_urls_from_rss(rss_url):
feed = feedparser.parse(rss_url)
with open(‘urls.txt’, ‘w’, encoding=‘utf-8’) as file:
for entry in feed.entries:
clean_url = entry.link.split(‘?’)[0]
file.write(clean_url + ‘\n’)
print(“URLs have been successfully saved to ‘urls.txt’.”)
# 제목 중복 체크
def is_title_exists(title, token):
headers = {
“Authorization”: f“Bearer {token}”
}
response = requests.get(f“{wp_api_url}/posts?search={title}”, headers=headers)
if response.status_code == 200:
posts = response.json()
for post in posts:
if post[‘title’][‘rendered’] == title:
return True
return False
# 본문 내의 URL을 링크로 변환
def convert_urls_to_links(text):
url_pattern = re.compile(r‘(https?://\S+)’)
return url_pattern.sub(r‘<a href=”\1″>\1</a>’, text)
# 글자제한으로 아래로 이어짐
def main():
fetch_urls_from_rss(rss_url) # RSS 피드에서 URL 추출 및 파일에 저장
token = get_jwt_token()
if token:
urls = read_urls_from_file(‘urls.txt’) # URL 목록 파일 읽기
for blog_url in urls:
print(f“Processing {blog_url} …”)
iframe_content = fetch_iframe_content(blog_url)
content = extract_blog_content(iframe_content)
if content:
title = content[‘title’]
if is_title_exists(title, token):
print(f“제목 ‘{title}’ 포스팅이 이미 존재합니다. 생략합니다.”)
continue
source_link = f“<p>출처: <a href='{blog_url}’ target=’_blank’>{blog_url}</a></p>”
content_html = f“<h1>{title}</h1>{source_link}<p>{convert_urls_to_links(content[‘text’])}</p>”
if content[‘image’]:
image_path = download_image(content[‘image’])
if image_path:
wp_image_url = upload_image_to_wp(image_path, token)
if wp_image_url:
content_html += f“<img src='{wp_image_url}’ />”
os.remove(image_path)
category_id = 123 # 여기에 원하는 카테고리 ID를 입력하세요
create_wp_post(title, content_html, token, category_id)
else:
print(“JWT 토큰을 가져오지 못했습니다.”)
if __name__ == “__main__”:
main()
누가 이걸 써먹을지는 모르겠지만
필요하다면 언제든 써도된다 다만
문제가 생길 수도 있다 왜냐면
나도 뭐가 뭔지 모르고 오류가 있을 수도 있으니
참고만하시길.