728x90
반응형

Slack api에 Bot을 만드는 과정을 매우 자세히 적어 놓아서 도움이 될 것이다!

 

cmd에 들어가 주피터 노트북 사용 위치 or 사용하는 가상 환경에서 설치를 해준다.

 

pip install slackclient

 

그다음 cmd에 jupyter notebook입력하고 생기는 url에 들어가면 jupyter notebook에 접속할 수 있다.

 

 

위 사진처럼 오류가 없다면 잘 설치가 된 것이다.

 

오류가 뜬다면 방법은 2가지 이다.

 

1. 파이썬의 버전 바꾸기
파이썬 3.9 버전은 오류가 있는 거 같다. 나는 3.6 버전을 쓰고 있다

2. pip install slackclient==1.0.7 로 설치하기

 

slack api 홈페이지에 들어가서 your Apps를 누른다.

 

 

 

create New App을 누른다. 밑에 있는 App들은 내가 미리 만들어 놓은 app이다.

 

 

처음 볼 때 뭘 눌러야 할지 난감했다. 그냥 맨 첫 줄에 있는 거 눌렀다.

 

봇 이름은 자유롭게 정해주자 나는 hello로 했다.

 

Create App을 누르면

 

 

화면이 전환된다. Bots를 누르자

 

 

권한을 설정하자

 

 

 

Workspace를 설치를 누른다

 

 

연결할 채널을 선택하고 허용을 누른다.

 

그러면 토큰이 뜨는데 이게 제일 중요하다.

 

 

복사해서 따로 저장해놓자!

 

그리고 스크롤을 내려 Scopes까지 간다.

 

 

이걸 꼭 추가해줘야 봇이 채팅할 수 있다.

 

그리고 다시 뒤로 가기 눌러서 Bot으로 들어가야 한다.

 

 

아까와 다르게 다른 게 뜰 것이다.

Online을 눌러야 한다.

 

 

 

와 세팅 다 끝났다. 이제 복잡한... 

 

다음 포스팅에서 파이썬 코딩으로 봇이 채팅 치는 것을 해보겠다!

 

2021.06.09 - [Data Analysis/web crawling] - [Crawling] 슬랙 파이썬 채팅

 

[Crawling] 슬랙 파이썬 채팅

2021.06.09 - [Data Analysis/web crawling] - [Crawling] Slack 연동하기 [Crawling] Slack 연동하기 cmd에 들어가 주피터 노트북 사용 위치 or 사용하는 가상환경에서 설치를 해준다. pip install slackclient..

hello-ming.tistory.com

 

728x90
반응형
728x90
반응형

* 본 포스팅은 주피터 노트북에서 진행되었다.

 

logging은 파이썬 내장 함수이므로 설치할 필요가 없다.

 

보통 log는 서버에서 많이 사용하는데, 어떤 형식으로든지 log를 출력하고 싶을 때 사용한다.

 

import logging

logging.info("I'm bear")
logging.warning("warnning")

 

logging 모듈의 단계

1. critical 가장 심각함

2. error

3. warning

4. info

5. debug -> 가장 심각하지 않음

 

logging 모듈은 기본적으로 1-3 단계까지만 출력한다.

 

logging.debug("debug")
logging.info("debug")
logging.warning("warning")
logging.error("error")
logging.critical("critical")

 

logging 내부 모듈에 있는 basicConfig로 변경할 수 있다.

 

level = logging.DEBUG
logger = logging.getLogger()
logger.setLevel(level)

 

파일에 문서 생성하기

import sys
import logging

logger = logging.getLogger()
logger.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s | %(levelname)s | %(message)s')

file_handler = logging.FileHandler('logs.log')
file_handler.setLevel(logging.DEBUG)
file_handler.setFormatter(formatter)


logger.addHandler(file_handler)
logger.info("이건 log 메세지")
logger.error("이건 error 메세지")
logger.error('잘되네')

728x90
반응형
728x90
반응형

* 본 포스팅은 주피터 노트북에서 진행되었다.

 

Selenium

사용자가 아닌 프로그램이 웹 브라우저를 제어할 수 있게 해주는 라이브러리이다.

서버와 클라이언트로 나누는데, 웹 브라우저 종류마다 클라이언트 프로그램이 별도로 필요하다.  

 

from selenium import webdriver
url = "https://pjt3591oo.github.io"
driver = webdriver.Chrome('chromedriver')
driver.get(url)
selected_link = driver.find_element_by_class_name('p')
print(selected_link)
print(selected_link.tag_name)
print(selected_link.text)

 

selected_selector = driver.find_element_by_css_selector('div.home div.p a')
print(selected_link)
print(selected_link.tag_name)
print(selected_link.text)

 

이제 웹을 제어해 보았다.

 

selected_selector.click() #코드를 이용하여 선택된 항목에 클릭 이벤트

이 코드를 실행하면 자동적으로 

 

위에 명시한 url로 이동한다.

 

키보드 제어

driver = webdriver.Chrome('chromedriver')
url = "https://pjt3591oo.github.io/search"
driver.get(url)
selected_tags_a = driver.find_element_by_css_selector('input#search-box')
selected_tags_a.send_keys('test')

 

자동으로 test를 입력한 search창이 뜬다.

 

 

javascript 실행

 

driver.get(url)
driver.execute_script('alert("test")')

alert 창이 뜬다.

 

url = "https://pjt3591oo.github.io/search"
search_keyword = 'db'
driver = webdriver.Chrome('chromedriver')
driver.get(url)
selected_tag_a = driver.find_element_by_css_selector('input#search-box')
selected_tag_a.send_keys(search_keyword)
selected_tag_a.send_keys(Keys.ENTER) #\UE007로 해도 엔터가 됨
soup = BeautifulSoup(driver.page_source, 'lxml')
items = soup.select('ul#search-results li')

for item in items:
    title = item.find('h3').text
    description = item.find('p').text
    print(title)
    print(description)

 

search에 db를 검색한 결과를 띄어준다. 자동으로 브라우저가 열린다.

728x90
반응형
728x90
반응형

* 본 포스팅은 주피터 노트북에서 진행하였다.

 

[ 용어 정리 ]

크롤링(crawling) 혹은 스크레이핑(scraping)은 웹 페이지를 그대로 가져와서 거기서 데이터를 추출해 내는 행위다. 크롤링하는 소프트웨어는 크롤러(crawler)라고 부른다.

 

requests와 bs4를 이용하여 크롤러를 만들 수 있지만 자바스크립트의 동작이 많은 웹 사이트일 경우 한계가 있기 때문에 selenium을 사용한다.

 

chrome driver가 필요한데 만약 설치가 안되어 있다면 아래 포스팅을 참고하면 좋을 것이다.

 

2021.06.09 - [Data Analysis/web crawling] - [Crawling] 크롬 드라이버(ChromeDriver) 설치하기

 

[Crawling] 크롬 드라이버(ChromeDriver) 설치하기

chrome driver를 설치한다. https://chromedriver.chromium.org/downloads ChromeDriver - WebDriver for Chrome - Downloads Current Releases If you are using Chrome version 91, please download ChromeDrive..

hello-ming.tistory.com

 

from selenium import webdriver
url = "https://pjt3591oo.github.io"
driver = webdriver.Chrome('chromedriver')
driver.get(url)

브라우저가 자동으로 열린다.

 

만약 selenium이 없다면 아래의 코드를 이용하면 된다.

!pip install selenium

 

요소를 가져오자

selected_id = driver.find_element_by_id('nav-trigger') #id로 요소 선택
print(selected_id)
print(selected_id.tag_name) #태그명
print(selected_id.text) #태그에 속한 문자

 

selected_p = driver.find_element_by_tag_name('p') #id로 요소 선택
print(selected_p)
print(selected_p.tag_name) #태그명
print(selected_p.text) #태그에 속한 문자

 

selected_tags_p = driver.find_elements_by_tag_name('p') #id로 요소 선택
print(selected_tags_p)

 

selected_link = driver.find_element_by_class_name('p')
print(selected_link)
print(selected_link.tag_name)
print(selected_link.text)

 

 

728x90
반응형
728x90
반응형

 

chrome driver를 설치한다.

https://chromedriver.chromium.org/downloads

 

ChromeDriver - WebDriver for Chrome - Downloads

Current Releases If you are using Chrome version 91, please download ChromeDriver 91.0.4472.19 If you are using Chrome version 90, please download ChromeDriver 90.0.4430.24 If you are using Chrome version 89, please download ChromeDriver 89.0.4389.23 If yo

chromedriver.chromium.org

 

위 url에 들어가면 이게 보이는데 제일 위에 있는 것을 눌러주었다. 

 

컴퓨터 사양에 맞춰 다운로드한다.

 

주피터 노트북에서 아래의 코드를 작성하고 실행한다.

 

pwd

실명이여서 가렸다

 

이 코드로 현재 주피터 노트북의 저장 위치를 확인한 뒤

 

다운로드한 것을 위 주소로 옮겨준다.

 

 

from selenium import webdriver
url = "https://hello-ming.tistory.com/"
driver = webdriver.Chrome('chromedriver')
driver.get(url)

 

아래의 코드를 실행하면 제시한 url로 브라우저가 열린다.

 

728x90
반응형
728x90
반응형

 

 지난 포스팅을 통해 앱 만들기의 기본 세팅을 완료했다. 지난 포스팅에 이어 계속해서 Django 공식 튜토리얼을 토대로 참고 자료로 내용을 덧붙여 포스팅하도록 하겠다.


2021.06.08 - [BACK-END/Django] - [Django] admin 커스터마이징 / MySQL 연동

 

[Django] admin 커스터마이징 / MySQL 연동

2021.06.07 - [BACK-END/Django] - [Django] 파이참 설치하고 장고 개발 서버 실행하기 [Django] 파이참 설치하고 장고 개발 서버 실행하기 2021.06.07 - [BACK-END/Django] - [Django] cmd로 가상환경 만들기 /..

hello-ming.tistory.com

이 포스팅 이후의 작업이다.

 

django를 이용해서 웹 사이트에서 투표하는 것을 만들 것이라

 

model은 2가지가 필요하다. Question과 Choice

 

Question은 질문이고 Choice는 선택해서 투표가 몇 번 되었는지 확인할 수 있게 진행할 것이다.

 

models.py

from django.db import models


# Create your models here. 모델만들기
class Question(models.Model):
    question_text = models.CharField(max_length=200) #데이터 타입 문자열
    pub_date = models.DateTimeField('date published') #데이터 타입 날짜

    def __str__(self):
        return self.question_text


class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE) # 칼럼은 외래키로 Question과 연결됨
    choice_text = models.CharField(max_length=200) #문자열
    votes = models.IntegerField(default=0) #정수

    def __str__(self):
        return self.choice_text

    # 테이블 두개 만드는 것 부모테이블 자식테이블

 

이제 터미널에서 migrations와 migrate를 해주면 된다.

 

 

migrations

 

모델 변경 내역 히스토리 관리

 

- 모델의 변경내역을 DB Schema(데이터베이스 데이터 구조)로 반영시킨다.

 

터미널에서 아래의 코드를 적용시킨다.

python manage.py makemigrations 

 

만약 오류가 뜬다면 아래의 포스팅에 해결방법을 써놔서 참고하면 된다.

 

2021.06.10 - [Tip] - [Django] python manage.py makemigrations 에러 no changes detected

 

[Django] python manage.py makemigrations 에러 no changes detected

python manage.py makemigrations 하는데 오류가 떴다... no changes detected 에러 발생 이유는 연동된 database에서 변경된 부분이 없을 때 발생한다고 한다... 해결방법은 setting.py의 INSTALLED_APPS에 추가..

hello-ming.tistory.com

 

migrations 적용 후 migrate는 아래의 코드를 터미널에 적용하면 된다.

 

python manage.py migrate

 

정리를 해보면

1. 마이그레이션 파일(초안) 생성하기 : makemigrations

 

2. 해당 마이그레이션 파일을 DB에 반영하기 : migrate

 

터미널에서 코드를 다 적용시킨 후 polls - migrations 폴더를 확인해 보면. py 형식의 파일이 새로 생겼음을 알 수 있다.

 

 

터미널에 runserver을 돌려 url에 들어가 /admin을 해주면

 

python manage.py runserver

 

polls 앱에 Choices와 Questions 모델이 생성됨을 확인할 수 있다.

 

다음 포스팅은 기능을 추가하여 직접 투표할 수 있도록 해보겠다!

728x90
반응형
728x90
반응형

2021.06.07 - [BACK-END/Django] - [Django] 파이참 설치하고 장고 개발 서버 실행하기

 

[Django] 파이참 설치하고 장고 개발 서버 실행하기

2021.06.07 - [BACK-END/Django] - [Django] cmd로 가상환경 만들기 / 기본환경셋팅 [Django] cmd로 가상환경 만들기 / 기본환경셋팅 cmd를 이용하여 Django에 필요한 가상환경을 만들것이다. 파이썬이 있어야한다..

hello-ming.tistory.com

 

이 포스팅 이후의 작업이다!

 

mysql연동을 위해  mysqlclient 를 설치해야한다.

 

[settings] - [python Interpreter]

 

mysite에 settings.py가 생긴걸 볼 수 있다.

localhost, databases 등록한다., time_zone도 바꿔야한다!

 

 

mysql 연결하기 위해 mysql workbench

django 데이터베이스 추가한다.

 

mysql에 만들어 주었다.

본인이 설정한 mysql의 정보를 입력한다.

파일을 저장한 뒤 terminal에 아래의 코드 추가한다.  관리자 권환 주는것이다!

 

데이터베이스를 적용해라? 정도의 뜻이다.

 

manage.py 가 있는 경로로 찾아가 코드를 입력한다.

실행이 다 도면

 

뭔가 알아서 테이블들을 만들어 준다.

 

manage.py가 있는 경로에서 runserver를 입력한다.

 

url이 뜨는데 ctrl을 누른채 클릭하면 새창으로 django창이 뜬다.

 


admin 계정으로 접근할 거 만들기

 

아까 로켓화면의 url창에 사진처럼 /admin을 붙여준다.

 

 

관리자 로그인 하라는 창으로 전환이된다.

 

 

어드민 계정을 만들어 주기 위해 createsuperuser을 해준다.

 

manage.py가 있는 경로에서 입력해야한다.

 

username과 email, password는 직접 정하는 것이다!

 

비밀번호 항목은 가려져있다! 입력하고 enter를 누르면 여러 창이 뜨는데 y를 쳐서 enter하면된다.

 

 

세팅을 마쳤으니 이제 /admin으로 가서 로그인을 해보자.

 

 

 

로그인을 하면 이러한 화면이 뜨는데 users를 생성해 보자

 

 

 

user의 이름과 비밀번호를 설정하고 save를 눌러주면 비밀번호가 너무 짧아서 다시 작성해야한다...

 

 

비밀번호를 한층 더 어렵게 설정했다.  @hong1234

 

 

사진속처럼 이메일을 설정하면 유효하지 않다고한다. @naver.com까지 하면 된다.

 

save 해준다.

 

 

생성되었다!

 

다시 /admin으로 가면 생성됨을 확인할 수 있다.

 

 

728x90
반응형
728x90
반응형

사이트 분석

base_url = 'https://pjt3591oo.github.io/'
page_path = '/page%d'
page=2
res = rq.get(base_url)
soup = BeautifulSoup(res.content,'lxml')
posts = soup.select('body main.page-content div.wrapper div.home div.p')
for post in posts:
    title = post.find('h3').text.strip()
    descript = post.find('h4').text.strip()
    author = post.find('span').text.strip()
    print(title,descript,author)

 


base_url = 'https://pjt3591oo.github.io/'
page_path = '/page%d'
page=2
res = rq.get(base_url)
soup = BeautifulSoup(res.content,'lxml')
while True:
    sub_path = page_path%(page)
    page += 1
    res = rq.get(base_url + sub_path) #https://pjt3591oo.github.io/page2/ => page3 이렇게 page 단위로 url 변경하여 크롤링 함
    
    if(res.status_code != 200):
        break
    soup = BeautifulSoup(res.content,'lxml')
    posts = soup.select('body main.page-content div.wrapper div.home div.p')
    
    for post in posts:
        title = post.find('h3').text.strip()
        descript = post.find('h4').text.strip()
        author = post.find('span').text.strip()
        print(title,descript,author)

 

위 페이지 사진을 나타낸것이다.

728x90
반응형
728x90
반응형

요소 찾기

import re
html = """<html> <head><title>test site</title></head> <body> <div><p id="i" class="a">test1</p><p class="d">test2</p></div><p class="d">test3</p></p> a tag <b>b tag</b></body></html>"""
soup = BeautifulSoup(html,'lxml')
print(soup.find_all(class_=re.compile('d'))) # 클래스 값에 d를 포함하는 요소 찾기

 

print(soup.find_all(id=re.compile('i'))) # id 값에 i를 포함하는 요소 찾기

print(soup.find_all(re.compile('t'))) #태그에 t가 포함되는 요소 찾기

 

print(soup.find_all(href=re.compile('/'))) #href에 /가 포함된 요소 찾기

 

정규식은 우리가 문자열을 다룰때 문자열에서 특정 패턴을 검색하거나 바꾸기 위해 사용하는 식이다.

 

파이썬에서 정규식을 사용하기 위해 re 라는 모듈을 사용한다.

 

re는 파이썬에 내장되어있으므로 pip를 이용하여 별도의 설치가 불필요하다.

 

 

정규식을 사용하기 위한 과정

 

1.  패턴 만들기, re compile(정규 표현식)을 이용하여 패턴 만들기

 

2. 만들어진 패턴을 이용하여 match(문자열), search(문자열), findall(문자열), finditer(문자열)을 한다.

 

3. 위의 과정에서 match(), search()를 통해 나온 결과물을 group(), start(), end(), span()을 이용하여 반환한다.

 

4. findall(), finditer()는 리스트와 객체로 반환하므로 반복문을 이용하여 group(), start(), end(), span()을 사용한ㄷ.

 

\w는 문자 \d는 숫자를 의미하고 앞에 {}는 반복횟수를 뜻한다.

\w{3}은 문자를 3자리씩 묶어서 찾는다.

\d{3}은 숫자를 3자리씩 묶어서 찾는다.

 

[^a-z], a부터 z까지 포함되지않는 것

[^A-Z], A부터 Z까지 포함되지 않는 것

^은 시작이라는 의미인데 [] 안에 있으면 포함되지 않음을 의미한다.

마침표(.)는 해당 자리를 의미한다. t.이면 t로 시작하는 2글자 t.t는 t로 시작하고 t로 끝나는 3글자의 문자열이다.

t?est는 test나 est를 찾는 패턴식이고 ?는 앞에 나온 값이 있어도 되고 없어도 된다.

\w는 문자를 의미하는데 +가 붙으면 test또는 est 이후에 문자가 반드시 나와야 하는 패턴을 찾고 *은 test 또는 est 이후에 문자가 반드시 있지 않아도 됨을 의미한다.

=> t?est\w+는 test를 찾지 못하고 t?est\w*은 test를 찾는다.

 

정규 표현식에서 사용하는 특수문자

^.[]{}()$^*

 

match, search,findall,finditer 비교

test_str= "t1sd test j test1 test"
pattern = re.compile('test')
a=pattern.match(test_str)
b=pattern.search(test_str)
c=pattern.findall(test_str)
d=pattern.finditer(test_str)
print('----match 결과----')
print(a)
print(a.group(), a.start(), a.end(), a.span())

 

print('----search 결과----')
print(b)
print(b.group(), b.start(), b.end(), b.span())

 

print('----findall 결과----')
print(c)

 

match와 search는 둘다 함수를 사용하고 일치한 객체가 있으면 반환하고 없으면 null 반환

 

print('----finditer 결과----')
print(d)


test_a = "a b c d"

 

예를 보면 알 수 있듯이

 

match는 문자열의 시작 부분에서만 일치를 확인하는 반면 search는 문자열의 모든 위치에서 일치를 확인한다.

 

test_str= """I am Park Jeong-tae. I live in Paju.
I lived in Paju for 25 years.
Sample text for testing:
abcdefghijklmnopqrsAvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ
0123456789 _+-.,!@#$%^&*();\/|<>"'
12345 -98.7 3.141 .6180 9,000 +42"""
pattern = re.compile('[a-z]')
pattern1 = re.compile('[a-z]+')

c = pattern.findall(test_str) #소문자를 포함하는 것
d = pattern1.findall(test_str) #소문자를 하나라도 포함하는 것

 

pattern = re.compile('[A-Z]')
pattern1 = re.compile('[A-Z]+')

c = pattern.findall(test_str) #대문자를 포함하는 것
d = pattern1.findall(test_str) #대문자를 하나라도 포함하는 것

 

pattern=re.compile('[a-zA-Z]')
pattern1 = re.compile('[a-zA-Z]')

c = pattern.findall(test_str) #영문자를 포함하는 것
d = pattern1.findall(test_str) #영문자를 하나라도 포함하는 것

 

# 전화번호 추출
test_num = "저의 전화번호는 010-6666-7777 입니다"

pattern = re.compile('[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]')  #숫자숫자숫자-숫자숫자숫자숫자-숫자숫자숫자숫자 형태
pattern1 = re.compile('\d\d\d-\d\d\d\d-\d\d\d\d')  #숫자숫자숫자-숫자숫자숫자숫자-숫자숫자숫자숫자 형태
pattern2 = re.compile('\d{3}-\d{4}-\d{4}')  #숫자숫자숫자-숫자숫자숫자숫자-숫자숫자숫자숫자 형태
c = pattern.findall(test_num)
d = pattern1.findall(test_num)
e = pattern2.findall(test_num)

 

pattern = re.compile('[a-zA-Z0-9]+') #a부터 z까지, A부터 Z까지, 0부터 9까지 포함된 것
pattern1 = re.compile('\w+') #단어 하나라도 포함된 것
c = pattern.findall(test_str)
d = pattern1.findall(test_str)

 

 

pattern = re.compile('t..t') #t문자문자t 패턴
pattern1 = re.compile('t...t') #t문자문자문자t 패턴

c = pattern.findall(test_str)
d = pattern1.findall(test_str) 

print(c)
print(d)

 

test_str = """I am Park Jeong-tae. I live in Paju.
I lived in Paju for 25 years. estadsffjkfad test
Sample text for testing:
abcdefghijklmestnopqrsAvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ
0123456789 +-.,!@#$%^&*();\/|<>"'
12345 -98.7 3.141 .6180 9,000 +42"""

pattern = re.compile('t?est\w+') #test나 est로 시작하는 문자열 뒤에 단어(word)가 있어야 함
pattern1 = re.compile('t?est\w*') #test나 est로 시작하는 문자열 뒤에 단어(word)가 없어도 됨

c = pattern.findall(test_str)
d = pattern1.findall(test_str) 

print(c)
print(d)

 

728x90
반응형
728x90
반응형
html = """<html> <head><title>test site</title></head> <body> <p>test1</p><p class="d">test2</p><p class="c">test3</p></p> </body></html>"""
soup = BeautifulSoup(html,'lxml')
print(soup.find_all('p',class_='d'))
print(soup.find_all('p',class_='c'))

 

기존 속성(attribute) class와 구분하기 위해 _가 추가되었다.

 

print(soup.find_all('p', text='test1'))
print(soup.find_all('p', text='t'))

 

하나의 요소만 가져오는 find

 

print(soup.find('p'))

 

제한을 가할때 limit 사용

print(soup.find_all('p', limit=1)[0])
print(soup.find_all('p', limit=2))

 

select () 함수를 이용하면 find_all() 처럼 리스트로 반환한다. 하지만 select()는 css 셀렉터를 활용하여 원하는 요소에 접근할 수 있다.

 

 

html = """<html> <head><title>test site</title></head> <body> <p id="i" class="a">test1</p><p class="d">test2</p><p class="d">test3</p></p> <a>a tag</a> <b>b tag</b></body></html>"""
soup = BeautifulSoup(html,'lxml')
print(soup.select('.d'))
print(soup.select('p.d'))
print(soup.select('#i'))
print(soup.select('p#i'))

 

태그를 지우는 extract

a=soup.body.extract()
a

 

 

soup = BeautifulSoup(html,'lxml')
for tag in soup.select('p'):
    print(tag.extract())
print('제거완료')
print(soup)

 

728x90
반응형

+ Recent posts