이번 부트캠프에 참여하면서 처음으로 API와 파이썬을 직접 사용해볼 수 있었지만 실제로 내가 어떻게 활용할지에 대해서는 막연한 느낌이 있었습니다.
그래서 이번에는 Openai API를 활용해 글을 작성하고, 워드프레스 API로 발행하는 과정까지 직접 경험해보는 것을 목표로 잡았습니다.
‘발행완료’가 최우선이기 때문에 글의 품질이나 다른 문제들은 잠시 뒤로 할 예정입니다.
그래서 무엇을 만들것인가?
API에 대해서 유튜브에서 찾아보다가 우연히 아래의 영상을 접하게 되었는데요.
7분 10초쯤부터 나오는 내용인 ‘웹사이트 크롤링 후 재발행’이 저에게 활용도가 높을 것 같아서 이걸로 정했습니다.
해당 내용을 요약하자면
URL을 입력하면 해당 URL의 정보를 정리해 txt 파일로 저장한다.
질문을 하면 txt파일 내용을 바탕으로 GPT가 답변을 해준다.
이 정보를 활용하여 포스팅을 진행합니다.
이미 과제를 통해 OpenAI API로 글쓰기를 해보고, 그리모어가 어떻게든 해결해준다는 것을 알게되서 그런지 질문부터 던져봅니다.
아래와 같이 그리모어에게 질문했고, 답변을 통해 제 말을 잘 이해했다는 것을 알 수 있었습니다.
import requests
from bs4 import BeautifulSoup
import openai
# 워드프레스 포스팅 함수
def post_to_wordpress(title, content, wp_url, wp_username, wp_password):
credentials = (wp_username, wp_password)
headers = {'Content-Type': 'application/json'}
data = {"title": title, "content": content, "status": "publish"}
response = requests.post(f"{wp_url}/wp-json/wp/v2/posts", json=data, auth=credentials, headers=headers)
return response.json()
# 질문과 답변을 HTML로 저장하는 함수
def save_qa_to_html(question, answer, file_name="qa_document.html"):
html_content = f"""
<html>
<head><title>Q&A Document</title></head>
<body>
<h1>Question:</h1>
<p>{question}</p>
<h2>Answer:</h2>
<p>{answer}</p>
</body>
</html>
"""
with open(file_name, "w", encoding="utf-8") as file:
file.write(html_content)
# OpenAI API를 사용하여 질문에 답변하는 함수
openai.api_key = 'YOUR_OPENAI_API_KEY'
def answer_question(question, file_path="web_content.txt"):
with open(file_path, "r", encoding="utf-8") as file:
content = file.read()
response = openai.Completion.create(
engine="text-davinci-003",
prompt=f"Given the following content:\n\n{content}\n\nQ: {question}\nA:",
temperature=0.5,
max_tokens=100,
top_p=1.0,
frequency_penalty=0.0,
presence_penalty=0.0
)
return response.choices[0].text.strip()
# URL을 쉼표로 구분하여 입력 받고 웹 문서 크롤링
input_urls = input("URL을 쉼표로 구분하여 입력하세요 (예: http://example.com, http://example2.com): ")
urls = [url.strip() for url in input_urls.split(",")]
with open("web_content.txt", "w", encoding="utf-8") as file:
for url in urls:
try:
response = requests.get(url)
soup = BeautifulSoup(response.content, "html.parser")
text = soup.get_text(separator="\n", strip=True)
file.write(text + "\n\n---\n\n")
except Exception as e:
print(f"Error fetching {url}: {e}")
# 사용자로부터 질문 받기
question = input("질문을 입력하세요: ")
answer = answer_question(question)
# 질문과 답변을 HTML로 저장
save_qa_to_html(question, answer)
# 워드프레스에 포스팅 (실제 사용 전에 URL과 자격증명을 설정해야 함)
wp_url = 'YOUR_WORDPRESS_SITE_URL'
wp_username = 'YOUR_WP_USERNAME'
wp_password = 'YOUR_WP_PASSWORD'
post_to_wordpress("Q&A Document", f"<h1>{question}</h1><p>{answer}</p>", wp_url, wp_username, wp_password)
print("프로세스가 완료되었습니다.")
그렇게 나온 첫번째 코드고요. 무슨말인지 잘 모르지만 실행해 봅니다.
실행하면 버전오류나, API 문서 오류나 아주 다양한 오류가 발생하지만 그 오류까지도 모두 그리모어에 물어보면 어떻게든 해결은 됩니다.
몇 가지 오류를 수정하고 추가하고 싶은 부분이 있었습니다.
처음 짜준 코드는 입력 URL과 질문을 하나씩만 할 수 있도록 되어있어서 그 부분을 수정해달라고 하나씩 요청했습니다.
URL을 쉼표로 구분하여 입력하세요 (예: http://example.com, http://example2.com):이 형식으로 URL을 입력할 수 있게 수정해주세요.
import requests from bs4 import BeautifulSoup # 사용자로부터 쉼표로 구분된 URL 입력 받기 input_urls = input("URL을 쉼표로 구분하여 입력하세요 (예: http://example.com, http://example2.com): ") urls = [url.strip() for url in input_urls.split(",")] # 크롤링한 데이터를 저장할 파일 생성 with open("web_content.txt", "w", encoding="utf-8") as file: for url in urls: try: response = requests.get(url) soup = BeautifulSoup(response.content, "html.parser") # 웹 페이지의 본문 내용 추출 (태그 및 구조에 따라 수정 필요) text = soup.get_text(separator="\n", strip=True) file.write(text + "\n\n---\n\n") # 각 웹 페이지의 내용을 구분 except Exception as e: print(f"Error fetching {url}: {e}") print("웹 문서의 내용이 web_content.txt 파일에 저장되었습니다.")
나는 위 코드에서 질문을 여러번 할 수 있었으면 좋겠어. 텍스트를 넣으면 질문으로 인식하고 답변하고, 아무것도 입력하지 않으면 질문이 끝난것으로 처리하려면 어떻게 해야할까?
그리고 모든 질문과 답변을 하나의 HTML 파일에 순차적으로 저장하고 싶습니다.
def save_qa_to_html(qa_pairs, file_name="qa_document.html"): # 파일이 존재하지 않는 경우, 새로운 HTML 문서 구조를 생성 try: with open(file_name, 'x', encoding="utf-8") as file: file.write(""" <html> <head><title>Q&A Document</title></head> <body> """) except FileExistsError: pass # 파일이 이미 존재하면, 새로운 구조를 추가하지 않음 # 각 질문과 답변을 파일에 추가 with open(file_name, 'a', encoding="utf-8") as file: for question, answer in qa_pairs: file.write(f""" <h1>Question:</h1> <p>{question}</p> <h2>Answer:</h2> <p>{answer}</p> """) # HTML 문서를 닫는 태그는 마지막에 한 번만 추가 file.write(""" </body> </html> """) def interactive_question_answer_session(file_path="web_content.txt"): qa_pairs = [] # 질문과 답변을 저장할 리스트 while True: question = input("질문을 입력하세요 (종료하려면 엔터만 누르세요): ") if not question: # 질문이 비어있으면 반복 종료 break answer = answer_question(question, file_path) qa_pairs.append((question, answer)) # 질문과 답변 쌍을 리스트에 추가 return qa_pairs # 모든 질문과 답변 쌍을 반환 # 질문과 답변 세션을 실행하고 결과를 받음 qa_pairs = interactive_question_answer_session() # 모든 질문과 답변을 하나의 HTML 파일에 저장 save_qa_to_html(qa_pairs)
무슨일이 생겼나?
수정한 파이썬 코드를 실행하고 구글의 SEO 관련 문서 URL을 입력했습니다.
https://developers.google.com/search/docs/fundamentals/seo-starter-guide?hl=ko, https://developers.google.com/search/docs/crawling-indexing/sitemaps/overview?hl=ko, https://developers.google.com/search/docs/fundamentals/how-search-works?hl=ko
잠깐 시간이 지나면 URL의 내용이 저장된 'web_content.txt'라는 파일이 컴퓨터에 생성됩니다!
이제 질문을 해볼까요?
"URL을 어떻게 작성하는 것이 유리한가요?", "검색 결과에 영향을 미치려면 얼마나 걸리나요?" 라는 두 가지 질문을 했습니다.
그 결과로 생성된 HTML 파일에는 'Question'과 'Answer'에 h태그가 적용되어 있는데, 이 부분과 답변의 내용도 수정하고 싶지만 일단 넘어가기로 했습니다.
워드프레스에 글 올리기
네이버와 달리, 워드프레스 API를 이용하면 코드 몇 줄로 비교적 쉽게 글을 올릴 수 있습니다.
실제로 해보기 전까지는 어떤 원리로 작동하는지 이해하기 어려웠지만, 직접 해보니 이해가 되는 느낌입니다.
# 워드프레스 포스팅
wp_url = 'https://url/wp-json/wp/v2/'
wp_username = '사용자명'
wp_password = '비밀번호'
post_to_wordpress_with_qa_pairs("Q&A Document", qa_pairs, wp_url, wp_username, wp_password)
워드프레스 API 설정
url의 경우 https://url/wp-json/wp/v2/posts 까지가 맞지만
response = requests.post(f"{wp_url}posts", json=data, auth=credentials, headers=headers) posts가 붙도록 설정된 부분이 있어서 posts는 빼고 입렸했고요.
사용자와 패스워드는 워드프레스에서 사용자를 새로 만들어서 입력합니다.
새로 만들때 꼭 글쓰기 권한이 있는 역할로 지정해주세요.
비밀번호는 사용자를 추가한 뒤에 응용프로그램 비밀번호를 생성해서 입력해줍니다.
Status Code: 406, Response: <head><title>Not Acceptable!</title></head><body><h1>Not Acceptable!</h1><p>An appropriate representation of the requested resource could not be found on this server. This error was generated by Mod_Security.</p></body></html> 프로세스가 완료되었습니다.
이 과정에서 406 오류가 계속 발생해 발행이 되지 않았습니다. 이 오류는 서버 방화벽이나 설정 문제로 발생하는 것으로 알려져 있습니다. 과제 제출 시간이 얼마 남지 않아서, 다른 호스팅 서비스를 제공하는 도메인으로 변경하여 진행해보기로 했습니다.
그래서, 결과는?
임시저장으로 성공적으로 발행되었습니다!
내용도 아래와 같이 잘 반영되었습니다.
코드 작성은 챗GPT가 도와주기 때문에 어렵지 않 았지만, 예상치 못한 에러가 자주 발생해 그 부분이 가장 어려웠습니다.
박정기 파트너님과 토요일 오프라인 모임에서 이야기할 때, 에러에 대한 어려움을 토로했더니 "어떤 코드를 다 짜고 나서 보니 GPT에 약 3~400번 질문했더라"라고 말씀하셨어요.
포기하고 싶을 때마다 "그래, 나는 아직 50번도 안 물어봤잖아?"라고 생각하면서 버틸 수 있었습니다. 😭
마지막!
아래의 내용을 수정하면 조금 더 쓸만 한 컨텐츠가 만들어 질 것 같습니다.
Question,Answer 출력되지 않도록 수정
h태그가 질문에 적용되도록 수정
더 구체적이고 사람같은 글을 작성할 수 있도록 프롬프트 수정
질문1
현재 코드는 크롤링 파일을 바탕으로 답변을 생성할 뿐, 학습해서 처리하는 방식이 아닌 것 같습니다.
지난번 과제 때 openai API에 자료를 주고 그를 바탕으로 답변하는 방법에 대해서 '랭체인'을 언급해주셨는데요. 이 경우에도 랭체인을 활용해야 하는걸까요? 아니면 다른 방법이 있을까요?
질문 2
API 버전을 아래와 동일하게 입력해 GPT4이상으로 지정하면 이름이 잘못 지정되었다는 오류가 발생하는데 올 바른 모델명을 확인하는 다른방법이 있을까요?
#9기_문과생도AI