프로젝트

[discord.py] 2. 웹 크롤링 구현하기

starcat37 2023. 2. 23. 23:53

기본적인 apod 기능을 구현하기 위해 웹 크롤링 파트 구현을 하였다.

 

1. 구현한 기능

 

~apod라는 명령어를 입력하면, 그 날의 apod 정보를 크롤링해서 메시지를 보낸다. 가시성을 위해 discord의 embed 형식을 사용하였다.

2. 구현 코드 및 설명

크롤링 방법 자체는 여러 웹사이트에도 나와있지만, 나는 BeautifulSoup4를 사용했다. 아래의 공식문서를 주로 참고하면서, 필요할 경우 구글링을 하였다.

 

뷰티플수프 문서 — 뷰티플수프 4.0.0 문서

find_all() 메쏘드는 태그의 후손들을 찾아서 지정한 여과기에 부합하면 모두 추출한다. 몇 가지 여과기에서 예제들을 제시했지만, 여기에 몇 가지 더 보여주겠다: 어떤 것은 익숙하지만, 다른 것

www.crummy.com

 

전체 코드는 다음과 같다. 기능 구현에만 초점을 두었기 때문에, 아직 번잡하다.

import discord
import requests
from bs4 import BeautifulSoup

bot_token = '봇 토큰'

intents = discord.Intents.default()
intents.message_content = True

client = discord.Client(intents=intents)

url = "https://apod.nasa.gov/"
response = requests.get(url)

@client.event
async def on_ready():
    print(f'Logged in as {client.user.name}')

@client.event
async def on_message(message):
    if message.author == client.user:
        return

    #~apod
    if message.content('~apod'):
        #~apod today
        response.encoding = 'utf-8' #인코딩 설정
        response_html = response.text #html 파일 추출
        response_soup = BeautifulSoup(response_html, features='lxml') #soup 객체로 변환

        apod_date = response_soup.body.center.p.next_sibling.get_text().replace("\n", "")
        apod_title = response_soup.select_one('center > b').get_text()
        apod_explanation = response_soup.select_one('body > p').get_text().replace("\n", " ")[14:]
        apod_image = response_soup.select_one('body center p a img')['src']

        apod_embed = discord.Embed(title="Astronomy Picture of the Day", url="https://apod.nasa.gov/", description=f"{apod_date}")
        apod_embed.set_image(url="https://apod.nasa.gov/apod/" + apod_image)
        apod_embed.add_field(name=apod_title, value=apod_explanation)

        await message.channel.send(embed = apod_embed)

    #~apod YY-MM-DD
    if message.content("~apod 00-00-00"):
        print()

    #~apod alarm
    if message.content("~apod alarm"):
        print()

    #~apod help
    if message.content("~apod help"):
        print()

client.run(bot_token)

 

기본적인 크롤링 과정은 다음과 같다.

 

0. robots.txt 확인하기

크롤링 전, 해당 사이트가 크롤링을 금지하고 있는지 확인한다. 꼭 지켜야 하는 건 아니지만, 웹사이트에서 권장하는 방식이 무엇인지 확인하기 위해 가능하면 크롤링 전 한 번 보고 넘어가는 편이다.

apod 사이트는 모든 페이지에 대한 접근을 허용한다.

 

1. requests 모듈로 GET 요청 보내기

url = "https://apod.nasa.gov/"
response = requests.get(url)

requests 모듈을 사용해 웹사이트에 GET 요청을 보낸다. response에는 상태 코드(200, 404...)와 html이 포함되어 있다.

 

2. GET한 결과인 response에서 html 코드를 가져와 BeautifulSoup 객체를 생성한다.

response.encoding = 'utf-8' #인코딩 설정
response_html = response.text #html 파일 추출
response_soup = BeautifulSoup(response_html, features='lxml') #soup 객체로 변환

3. BeautifulSoup 객체에서 필요한 내용이 들어있는 태그를 찾아가 각 변수에 할당해준다.

apod_date = response_soup.body.center.p.next_sibling.get_text().replace("\n", "")
apod_title = response_soup.select_one('center > b').get_text()
apod_explanation = response_soup.select_one('body > p').get_text().replace("\n", " ")[14:]
apod_image = response_soup.select_one('body center p a img')['src']

 

각 메서드에 대한 내용은 공식 문서에서 확인할 수 있다.

 

뷰티플수프 문서 — 뷰티플수프 4.0.0 문서

find_all() 메쏘드는 태그의 후손들을 찾아서 지정한 여과기에 부합하면 모두 추출한다. 몇 가지 여과기에서 예제들을 제시했지만, 여기에 몇 가지 더 보여주겠다: 어떤 것은 익숙하지만, 다른 것

www.crummy.com

4. discord embed를 만든 후 원하는 대로 변수를 추가해주고, message를 보낸다.

apod_embed = discord.Embed(title="Astronomy Picture of the Day", url="https://apod.nasa.gov/", description=f"{apod_date}")
apod_embed.set_image(url="https://apod.nasa.gov/apod/" + apod_image)
apod_embed.add_field(name=apod_title, value=apod_explanation)

await message.channel.send(embed = apod_embed)

 

3. 참고 사이트

https://www.jongung.com/200

https://luran.me/547

https://velog.io/@chaejm55/%EB%B2%88%EC%99%B82.-embed-%EC%9D%B4%EB%AF%B8%EC%A7%80

https://domdom.tistory.com/270

'프로젝트' 카테고리의 다른 글

[pymyrep] python pep8, docstring  (0) 2023.10.03
[discord.py] 1. 기본 Discord Bot 만들기  (0) 2023.02.19