데보션앱 소개페이지 바로가기
로그인 선택

신고하기

CLOSE
신고사유 (대표 사유 1개)
상세내용 (선택)
0/200
  • 신고한 게시글은 더 이상 보이지 않습니다.
  • 이용약관과 운영정책에 따라 신고사유에 해당하는지 검토 후 조치됩니다.
  • 허위 신고인 경우, 신고자의 서비스 이용이 제한될 수 있으니 유의하시어 신중하게 신고해 주세요.
(이 회원이 작성한 모든 댓글과 커뮤니티 게시물이 보이지 않고, 알림도 오지 않습니다.)

미리보기

커뮤니티

      1,234

      badge 23.06.15

      글 등록

      카테고리를 선택해주세요.

      DEVOTEE를 활성화 시키면
      지금 작성한 커뮤니티 글에 대해 1개의 댓글을 달아줍니다.

      버튼을 누르면 글 수정 시 ChatGPT가 작성한 댓글이 수정됩니다.

      임시저장함에 저장되었습니다. 저장일시 : 2022.5.17 14:29:08

      임시저장함

      제목을 선택하시면 이어서 작성이 가능하며,
      최대 20건까지 저장합니다.
      컨텐츠 유형, 제목, 저장일시, 삭제로 이뤄진 임시저장 목록
      컨텐츠 유형 제목 저장일 삭제

      데보션 블로그 게재 요청

      CLOSE
      • *
      • *

      본인인증

      효율적인 데보션 서비스 이용 및
      고객님의 소중한 개인정보보호를 위해
      본인인증을 진행해주세요. 본인인증 미 진행 시 로그인이 제한됩니다.
      본인인증 실패

      본인인증 로그인에 실패하였습니다.
      회원이 아니시거나 본인인증 등록이
      완료되지 않은 사용자입니다.

      회원정보 연결

      LangChain으로 크롤링을 해보자

      jako 23.10.18
      7,911 20 2
      DEVOTEE 요약
      최근 AI를 활용한 크롤링 방법에 대해 연구하고, 파이썬에서 크롤링에 활용할 수 있는 'LangChain' 라이브러리를 설치해 보았다. 이를 이용해 네이버 뉴스 기사를 제목, 서론, 본론, 결론으로 요약하도록 크롤링을 진행했다. 그러나 원하는 결과를 빠르게 추출하기 위해선 여전히 HTML Tag 분석과 가공 단계에서 수작업이 필요하다는 것을 깨달았다.
      DEVOTEE 추천 블로그

      개요

      최근 사이드 프로젝트에서 크롤링을 맡아 작업하게 됐다. 크롤링에 관한 글을 읽던 중 AI를 이용해 크롤링을 할 수 있다는 정보들이 눈에 띄었다.


      과거에 크롤링을 할 때는 HTML Tag를 하나하나 분석해서 데이터를 얻는 노가다성 작업이 이제는 AI를 통해 간편하게 이뤄지는 건가라는 생각과 함께 간단히 튜토리얼을 맛보기로 했다.


      튜토리얼로서는 네이버의 뉴스 기사를 "제목", "서론", "본론", "결론"에 따라 요약해 주는 크롤러를 만들어보는 것을 목표로 했다.



      1. LangChain 설치와 초기화

      Python에서 AI를 이용해 크롤링을 하기 위해서 다운받은 라이브러리는 langchain이다.

      $ pip install langchain
      $ pip install tiktoken

      Langchain은 "대규모 언어 모델과 애플리케이션의 통합을 간소화하는 SDK"라 소개되어있다. Langchain을 사용하기 전에 'openai'도 사용해 봤지만 LangChain 쪽이 제공되는 도구가 다양하기에 이를 선택했다. tiktoken은 langchain을 돌리다가 error가 나서 설치했는데 조사해 본 결과 langchain이 데이터를 가공처리할 때 필요한 라이브러리 정도로 이해했다.

       

      다음 작업으로 LangChain에서 사용할 Model을 선택하자.

      from langchain.chat_models import ChatOpenAI
      
      # LLM 객체 생성
      llm = ChatOpenAI(
          temperature=0,
          model_name='gpt-3.5-turbo-16k-0613',
          openai_api_key=''
      )


      2. WebBaseLoader를 이용해 HTML 불러오기

      대개 크롤링이라고 하면 URL을 통해 웹 페이지의 태그를 불러와야 하기에 requests나 urllib를 사용했지만 langchain은 "WebBaseLoader"라는 객체가 이 역할을 해준다.


      사용법은 다음과 같다.

      loader = WebBaseLoader("https://n.news.naver.com/article/119/0002758949")

      이제 load()라는 Method를 사용하면 Document 객체를 돌려준다.

      loader = WebBaseLoader("https://n.news.naver.com/article/119/0002758949")
      
      loader.load()
      
      # OutPut
      [Document(page_content='\n\n\n ... 'ko'})]


      3. 방대한 HTML Source를 분리하자.

      Document 객체는 langchain 문서에 따르면 "비정형 데이터와 메타데이터를 담고 있는 객체"라고 가이드하고 있다.


      그런데 "굳이 그럴 거면 객체로 담는 이유가 있나?"라는 의문이 생겼다. 사용해 본 후 느낀 점은 Document 객체는 "비정형 데이터와 메타 데이터 분리하기 용도"라는 점이다.


      다음은 주관적인 사고 방식으로서 정리한 내용이다.

      웹 페이지의 HTML Tag는 굉장히 많은 양의 텍스트로 이루어져있다. 이를 한 번에 AI에 입력한다면 필시 입력 제한에 걸릴 것이다.

      그러니 적절히 분리하여 AI에게 입력한 다음 합치는 것이 필요하다. 이 단위를 Document라는 객체로서 관리하는 것

      그렇다면 WebBaseLoader를 통해 Document를 적절히 분리한다는 건 어떻게 하는 걸까?


      이는 langcahin의 text_splitter에서 제공되는 객체와 WebBaseLoader의 메서드인 load_and_split()을 이용해 가능했다.

      text_splitter = CharacterTextSplitter(
          separator="\n",
          chunk_size=1500,  # 쪼개는 글자수
          chunk_overlap=500,  # 오버랩 글자수
          length_function=len,
          is_separator_regex=False,
      )
      
      loader = WebBaseLoader("https://n.news.naver.com/article/119/0002758949").load_and_split()

      예제만 보고 따라했기에 chunk_size와 chunk_overlap을 어떤 기준으로 정하는지는 잘 모르겠지만 위 코드의 결과 여러 Document로 분리된다.

      [Document(page_content='경찰 ...'),
       Document(page_content='이전 ...'),
       Document(page_content='구독 ...'),
       Document(page_content='구독 ...'),
       Document(page_content='디저트 ...'),
       Document(page_content="스몰 ...')]


      4. Prompt 와 결과 뽑아내기

      ChatGPT를 이용하면서 경험해 봤듯이 AI에게 작업을 요청해야 된다. 이는 Prompt라는 객체를 통해서 사용이 가능하다.

      from langchain.prompts import PromptTemplate

      지금까지 작업에서 고려할 점이 존재한다. Document가 쪼개졌기에 각 Document에 대한 "요약"과 이를 "합치는" Prompt 두 개를 작성해야 한다는 점이다. 만약 Document가 한 개였다면 요청을 한 번에 했지만 앞서 언급했듯 HTML Tag를 AI에게 입력하기 위해 분리했다는 점에서 이러한 처리를 해줘야 한다.

      summary_prompt = PromptTemplate(
          template="""다음 내용을 요약해줘
          {text}
          """,
          input_variables=['text']
      )
      combine_prompt = PromptTemplate(
          template="""다음 내용을 제목,서론,본론,결론에 따라 요약해줘
          {text}
          """,
          input_variables=['text']
      )

      Prompt Engineering이라는 말이 화두로 떠오르는 추세던데 관련하여 책을 읽거나 정보를 접하진 않아 일단 요청할 작업만 작성했다. prompt까지 코드를 작성했으면 load_summarize_chain 함수를 통해 원하는 결과를 받아올 수 있다.

      from langchain.chains.summarize import load_summarize_chain
      
      # 요약을 도와주는 load_summarize_chain
      chain = load_summarize_chain(llm,
                                   map_prompt=summary_prompt,
                                   combine_prompt=combine_prompt,
                                   chain_type='map_reduce',
                                   verbose=False)
      chain.run(docs)

      결과는 다음과 같다.

      제목: 경기남부경찰청, 수원 전세사기 의혹에 대한 강제수사 착수
      서론: 경기남부경찰청 반부패·경제범죄수사대가 수원 전세사기 의혹을 수사 중인 임대인 일가에 대한 강제수사에 착수했다고 밝혔다.
      본론: 경찰은 이들의 법인 사무실 등에 대해 압수수색을 진행하고, 확보한 자료를 분석한 뒤 피의자 신분으로 소환해 조사할 예정이다. 이 사건과 관련해 경찰은 지난달 5일부터 134건의 고소장을 접수했으며, 피해 금액은 190억원에 이른다.
      결론: 경기남부경찰청은 수원 전세사기 의혹에 대한 강제수사를 진행하고 있으며, 이에 관련된 법인 사무실 등을 압수수색하고 조사할 예정이다. 이 사건은 지난달부터 134건의 고소장이 접수되었으며, 피해 금액은 190억원에 이른다.


      5. 삽질

      5.1  LangChain의 UserWarning

      langchain을 처음 설치하고 나서 다음과 같은 경고가 뜬다.


      뭔가 cache 관련하여 문제가 있는 듯한데 왜 이런 경고가 발생하는지는 찾지 못했다. 그러나 상단에 다음과 같은 코드로 해결할 수 있었다

      from langchain.cache import InMemoryCache
      from langchain.globals import set_llm_cache
      
      set_llm_cache(InMemoryCache())


      5.2 LangChaing은 SQLALchemy 2.0을 사용한다.

      하나의 실험으로써 FastAPI에다 LangChain 코드만 가져다 사용하려고 시도했지만 계속 실패했다.


      SQLALchemy 1.4를 사용하고 있었는데 Langchain이 내부적으로 사용하는 라이브러리를 보니 그중에 SQLALchemy 2.0을 사용하고 있었다. FastAPI에서 SQLAlchemy 2.0을 사용하는 것으로 코드를 모두 대체하여 해결했지만 LangChain을 사용하게 된다면 아예 분리시켜 사용하는 것이 좋을 듯 싶다.


      5.3 여전히 수작업은 필요하다.

      이 튜토리얼은 웹 페이지 전체를 대상으로 입력한 것을 가정하고 있는데 현실적인 부분을  고려한다면 이는 사실 불명확한 일이다. 특정 영역의 데이터를 뽑아서 AI에게 입력한다고 해도 그 "특정 영역"이 입력제한을 넘어버리는 경우가 발생한다. 즉, HTML Tag를 분석하고 원하는 결과를 빠르게 추출해내려면 어느정도 가공하는 단계는 여전히 수작업을 필요로 한다는 것이다.



      6. 마치며

      LangChain을 사용하면서 확실히 코드를 작성하는 방식에 특이점이 오고 있음을 체감했다. 그러나 입력부터 결과를 뽑기까지 시간이 걸리는 탓에 중간중간 답답한 맛도 있다.


      크롤링 외에도 다양한 분야에서 사용하고 있는 추세던데 다음에는 다른 튜토리얼을 맛보는 것으로 하고 이만 글을 마친다.

      댓글 0

      DEVOTEE를 활성화 시키면
      지금 작성한 댓글에 AI가 댓글을 달아줍니다.

      jako 님의 최신 블로그

      더보기

      DEVOTEE 추천 블로그

      동영상 기고하기