Today's

길을 나서지 않으면 그 길에서 만날 수 있는 사람을 만날 수 없다

파이썬 스크립트

웹 스크래핑에도 GEMINI AI 을 도입해 보기

Billcorea 2024. 3. 14. 15:13
반응형

https://play.google.com/store/apps/details?id=com.billcoreatech.opdgang1127&pli=1

 

옵데강 (제주맛집 리스트 모아보기) - Google Play 앱

인터넷에 널린(?) 제주 맛집 정보를 모아 봅니다.

play.google.com

 

조금은 허접한(?) 앱 이기는 합니다만... 그래도 나름 재미있는 프로젝트 이기는 합니다.   이 앱을 구동하기 위해서는 

1. python 을 이용한 앱 스크래핑을 해야 합니다. 

2. firebase RealtimeDatabase에 저장을 해야 합니다.

3. android 앱이 realtime database 의 정보를 수신해 보여주는 기능을 구현해야 합니다.

4. 덤으로 제주버스정보을 API 호출을 통해 수신하고 관리합니다.

5. 앱에서는 구글 지도를 이용해 해당 정보를 표시해 줄 수 있어야 합니다.

 

이걸 하기 위해서는 24시간 구동이 가능한 서버 구성이 필요하기도 합니다. python을 24시간 구동하는 방법으로는 Google Cloud Function을 이용할 수 도 있겠지만, 시간 단위로 트리거를 해야 하는 등등 절차가 필요합니다.  그래서 현재는 raspberry pi 4를 이용해서 집에서 구동해 보고 있습니다.

 

그럼 오늘의 이야기는  python으로 주소 정보를 수집하는 것에 대한 이야기를 적어 보겠습니다.

 

 

import urllib
import requests
from bs4 import BeautifulSoup

searchKey = '제주맛집'
for idx in range(1, 100):
    print(idx)
    url = "https://search.daum.net/search?w=fusion&nil_search=btn&DA=STC&q={0}&p={1}&col=blog".format(
        urllib.parse.quote_plus(searchKey), idx)
    response = requests.get(url, verify=True)
    # print(response.text)
    bs = BeautifulSoup(response.text, 'html.parser')
    # print(bs)
    # print('---------------------------------------------------------------------------------------------')
    for item in bs.find_all('c-menu-share'):
        print(item['data-link'])

 

다음 포털의 검색을 위해서 '제주맛집'이라는 검색을 입력해 보면 위 URL을 통해서 검색된 정보를 노출하고 있는 것을 알 수 있었습니다.   html을 파싱 하기 위해서 BeautifulSoup을 이용해 보았습니다. 

 

이제 결과를 통해서 제주맛집으로 검색되는 블로그의 URL 임을 확인해 볼 수 있었습니다.

 

실행 결과

 

다음은 저 URL을 읽어서 해당 페이지의 html을 읽어 보도록 하겠습니다.

 

def parseText(baseUrl):
    try:
        response = requests.get(baseUrl, verify=True)
        bs = BeautifulSoup(response.text, 'html.parser')
        text1 = ''
        if 'blog.naver' in baseUrl:
            iframexx = bs.find_all('iframe')
            for iframe in iframexx:
                res = requests.get('https://blog.naver.com/' + iframe.attrs['src'])
                bs = BeautifulSoup(res.text, 'html.parser')
                text1 = re.sub('(<([^>]+)>)', '', bs.get_text())
        else:
            text1 = re.sub('(<([^>]+)>)', '', bs.get_text())

 

 

html 에서 text 만 html tag 을 다 제거한 경우의 결과값

 

이렇게 해서 블로그 페이지에서 text 만 추출하는 작업을 해 보았습니다.   

 

이제 오늘 해 보고 싶었던 이야기... 저 글에서 추출해 보고 싶은 정보인  블로그 안에서 찾을 수 있는 맛집 정보를 GEMINI AI을 활용해서 추출하는 프롬프트를 작성해 보겠습니다. 

 

def getGeminiResponse(text):
    # Or use `os.getenv('GOOGLE_API_KEY')` to fetch an environment variable.
    GOOGLE_API_KEY = 'AIz....................TQ3A'
    genai.configure(api_key=GOOGLE_API_KEY)
    prompt = '''
    From now on, you will be analyzing sentences and finding addresses in South Korea within them. 
    You will also be tasked with finding out the name of the store located at that address. 
    Are you familiar with the address format in Korea? 
    The address will be written separately into street number address and road name address. 
    Although it is not possible to know which address is contained in the following sentence, 
    you will be able to find it well.
    And find a phone number or cell phone number where you can be contacted.
        
    The response format is
    "상호: Company name or Business name, 주소: Korean address, 전화: Phone Number or Telephone Number"
        
    The answer must always be in Korean.
    Now, find the address and business name and phone number or telephone number in the next sentence and let me know. 
    {0}
    '''.format(text)

    model = genai.GenerativeModel(model_name='gemini-pro',
                                  generation_config = generation_config,
                                  safety_settings = safety_settings)
    response = model.generate_content(prompt)
    return response.text

 

나름 한글로 정리한 요건을 영문으로 번역해 프롬프트를 만들어 보았습니다. 아직 한글로 요청하면 이해도가 떨어지기 때문이기 때문입니다.   아직 까지는 비용 발생 없이 잘 활용하고 있습니다. 

 

이 코드들을 잘 활용한 결과를 만들어야 할 텐데... 걱정입니다.   현재 운영 중이 앱은 xml layout으로 구현되어 앱을 수정해야 할 필요성을 느끼고 있어서(?) 수정 작업을 해 볼 예정입니다. 

 

다음 이야기는 정리가 되면 다시 적어 보겠습니다.

 

 

반응형