Python (38)

반응형

 

selenium

 

 

MVVM(ajax 사용) 패턴의 경우 나중에 코드를 새로 뿌리기 때문에 크롤링이 불가능함

=> 새로운 방법으로 진행한다.

 

 

 

  • 테스트 전 작업

cmd 창에서 아래 코드 기입

 

pip install selenium

 

 

 

  • 테스트

my_selenium.py

from selenium import webdriver
from time import sleep
driver = webdriver.Chrome()
url = 'https://www.google.com'
driver.get(url)

sleep(5)

 

결과 화면1 : 실행 후 5초 뒤에 꺼짐

 

 

 

기존 소스로 응용하기

 

 

my_flask.py

from flask import Flask,request,render_template, redirect, jsonify
from flask.helpers import make_response

from day12.daoemp import Daoemp

app = Flask(__name__)

@app.route('/')
def main():
   return redirect("static/emp.html")

@app.route('/axios', methods=['POST'])
def axios():
    data = request.get_json()
    # print(data)
    print(data['menu'])
    return jsonify(message = "ok")

@app.route('/emp_list', methods=['POST'])
def emp_list():
    de = Daoemp()
    list = de.selectList()
    return jsonify(list=list)

@app.route('/emp_one', methods=['POST'])
def emp_one():
    data = request.get_json()
    e_id = data['e_id']
    
    de = Daoemp()
    vo = de.select(e_id);
    return jsonify(vo=vo)

@app.route('/emp_add', methods=['POST'])
def emp_add():
    data = request.get_json()
    e_id = data['e_id']
    e_name = data['e_name']
    gen = data['gen']
    addr = data['addr']
    
    de = Daoemp()
    cnt = de.insert(e_id, e_name, gen, addr);
    return jsonify(cnt=cnt)

@app.route('/emp_mod', methods=['POST'])
def emp_mod():
    data = request.get_json()
    e_id = data['e_id']
    e_name = data['e_name']
    gen = data['gen']
    addr = data['addr']
    
    de = Daoemp()
    cnt = de.update(e_id, e_name, gen, addr);
    return jsonify(cnt=cnt)

@app.route('/emp_del', methods=['POST'])
def emp_del():
    data = request.get_json()
    e_id = data['e_id']
    
    de = Daoemp()
    cnt = de.delete(e_id);
    return jsonify(cnt=cnt)

if __name__ == '__main__':
  app.run(debug=True, port=80, host='0.0.0.0')

 

 

my_selenium.py

from selenium import webdriver
from time import sleep
driver = webdriver.Chrome()
url = 'http://127.0.0.1/static/emp.html'
driver.get(url)

sleep(60)

 

결과 화면2 : 60초 후에 화면 꺼짐

 

 

 

 

  • 데이터 값만 출력하기 (find_elemnt 방법)

my_selenium.py

from selenium import webdriver
from time import sleep
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
url = 'http://127.0.0.1/static/emp.html'
driver.get(url)
# print(driver.page_source)

table = driver.find_element(By.CSS_SELECTOR, "table")

trs = table.find_elements(By.CSS_SELECTOR, "tr")

for idx,tr in enumerate(trs):
    if idx == 0 :
        continue

    tds = tr.find_elements(By.CSS_SELECTOR, "td")
    myname = tds[1].text
    addr = tds[3].text
    print("{}\t{}".format(myname,addr))

 

결과 화면3

 

 

 

  • 데이터 값만 출력하기 (select 방법)

my_selenium_bs_select.py

from selenium import webdriver
from time import sleep
from selenium.webdriver.common.by import By
from bs4 import BeautifulSoup

driver = webdriver.Chrome()
url = 'http://127.0.0.1/static/emp.html'
driver.get(url)
sleep(1)

html = driver.page_source
soup = BeautifulSoup(html, "lxml")
table = soup.select_one('table')

trs = table.select('tr')
for idx,tr in enumerate(trs) :
    if idx == 0:
        continue
    tds = tr.select('td')

    myname = tds[1].text
    addr = tds[3].text
    print("{}\t{}".format(myname,addr))

sleep(60)

 

결과 화면4

 

 

 

  • 데이터 값만 출력하기 (find 방법)
from selenium import webdriver
from time import sleep
from selenium.webdriver.common.by import By
from bs4 import BeautifulSoup

driver = webdriver.Chrome()
url = 'http://127.0.0.1/static/emp.html'
driver.get(url)

html = driver.page_source
soup = BeautifulSoup(html, "lxml")
table = soup.find('table')

trs = table.find_all('tr')
for idx,tr in enumerate(trs) :
    if idx == 0:
        continue
    tds = tr.find_all('td')

    myname = tds[1].text
    addr = tds[3].text
    print("{}\t{}".format(myname,addr))

sleep(60)

 

결과 화면5

 

 

반응형
반응형

 

매일 경제 전종목 게시판

 

 

daostock.py

import pymysql

class DaoStock:
    def __init__(self):
        self.con = pymysql.connect(host='localhost', port=3305, user='root',
                              password='python', db='python', charset='utf8')

        self.cur = self.con.cursor(pymysql.cursors.DictCursor)

    def insert(self,s_code,s_name,price,ymd):
        sql = f"""
            INSERT INTO 
                stock (s_code,s_name,price,ymd)
            VALUES ("{s_code}","{s_name}","{price}","{ymd}")
        """
        cnt = self.cur.execute(sql)
        self.con.commit()
        return cnt
        
    def __del__(self):
        self.cur.close()
        self.con.close()
        
if __name__ == '__main__':
    de = DaoStock()
    cnt = de.insert('1', '1', '1', '1')
    print("cnt",cnt)

 

 

mybs01.py

import requests, datetime
from bs4 import BeautifulSoup
from day18.daostock import DaoStock

ds = DaoStock()
ymd = datetime.datetime.today().strftime('%Y%m%d_%H%M')
print("ymd",ymd)

res = requests.get('https://stock.mk.co.kr/domestic/all_stocks')

soup = BeautifulSoup(res.text, "lxml")
divs = soup.find_all("div", {'class':"st_name"})

for idx,div in enumerate(divs):
    s_name = div.text.strip()
    s_code = div.find("a")['href'].split("/")[3]
    price = div.parent.find_all("div")[1].text.strip().replace(",","")
    cnt = ds.insert(s_code, s_name, price, ymd)
    print(idx,s_name,s_code,price,ymd,cnt)

 

결과 화면1

 

결과 화면2

 

 

반응형
반응형

 

네이버 개발자 이용하여 크롤링하기

 

 

1

 

1. 네이버 개발자 검색 > Products 클릭 > 검색 클릭

 

2

 

2. 오픈 API 이용 신청 클릭

 

3

 

3. 이용약관 진행 > 계정 정보 등록 진행

 

4

 

4. 이름, API, 환경 등 기입 > 등록하기 버튼 클릭

 

5

 

5. 붉은 표시 해 놓은 코드 복사

 

6

 

6. 뒤로 가기로 해당 페이지 이동 > 개발 가이드 보기 클릭

 

7

 

7. 아래로 내려서 Python 내용 복사하기

client_id에 붉은 네모 코드 기입

client_secret에 붉은 테두리로 된 코드 기입

 

 

 

  • 코드 실행
# 네이버 검색 API 예제 - 블로그 검색
import os
import sys
import urllib.request
client_id = "코드변경1"
client_secret = "코드변경2"
encText = urllib.parse.quote("오류동 맛집")
url = "https://openapi.naver.com/v1/search/blog?query=" + encText # JSON 결과
# url = "https://openapi.naver.com/v1/search/blog.xml?query=" + encText # XML 결과
request = urllib.request.Request(url)
request.add_header("X-Naver-Client-Id",client_id)
request.add_header("X-Naver-Client-Secret",client_secret)
response = urllib.request.urlopen(request)
rescode = response.getcode()
if(rescode==200):
    response_body = response.read()
    print(response_body.decode('utf-8'))
else:
    print("Error Code:" + rescode)

 

결과 화면5 : JSON 결과로 출력

 

 

 

XML 결과로 출력하기

 

 

# 네이버 검색 API 예제 - 블로그 검색
import os
import sys
import urllib.request
client_id = "코드변경1"
client_secret = "코드변경2"
encText = urllib.parse.quote("오류동 맛집")
# url = "https://openapi.naver.com/v1/search/blog?query=" + encText # JSON 결과
url = "https://openapi.naver.com/v1/search/blog.xml?query=" + encText # XML 결과
request = urllib.request.Request(url)
request.add_header("X-Naver-Client-Id",client_id)
request.add_header("X-Naver-Client-Secret",client_secret)
response = urllib.request.urlopen(request)
rescode = response.getcode()
if(rescode==200):
    response_body = response.read()
    print(response_body.decode('utf-8'))
else:
    print("Error Code:" + rescode)

 

결과 화면6

 

 

=> 결과 화면6 코드를 복사해서 xml 파일로 생성

안에 있는 title와 bloggername의 값을 출력해야함

<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
	<channel>
		<title>Naver Open API - blog ::&apos;오류동 맛집&apos;</title>
		<link>https://search.naver.com</link>
		<description>Naver Search Result</description>
		<lastBuildDate>Wed, 17 Apr 2024 15:40:00 +0900</lastBuildDate>
		<total>60673</total>
		<start>1</start>
		<display>10</display>
		<item>
			<title>&lt;b&gt;오류동&lt;/b&gt;역 &lt;b&gt;맛집&lt;/b&gt; &apos;김사부&apos;
				서울3대 돼지갈비 &lt;b&gt;맛집&lt;/b&gt;</title>
			<link>https://blog.naver.com/ivy5hn/223372878563</link>
			<description>^^ 오류동역 맛집, 서울 &lt;b&gt;오류동 맛집&lt;/b&gt; 서울 3대 돼지갈비 맛집
				김사부 였습니다. 이 글은 리뷰노트를 통하여 본 업체에서 제품 또는 서비스를 제공받아 작성된 글 입니다.
			</description>
			<bloggername>오늘도 라랄라~</bloggername>
			<bloggerlink>blog.naver.com/ivy5hn</bloggerlink>
			<postdate>20240305</postdate>
		</item>
		<item>
			<title>[&lt;b&gt;오류동&lt;/b&gt; 횟집] 회먹는날 / 가성비 &lt;b&gt;맛집&lt;/b&gt; </title>
			<link>https://blog.naver.com/jisu9328/223344108597</link>
			<description>_ ; 새로 두병 깔끔하게 클리어 했습니다! 영업시간: 11:00 - 23:00 (일요일은
				22:00) 전화번호: 02-2615-9888 포장, 배달 가능 오류동역 1번출구에서 도보 3분 거리 #오류동횟집
				#&lt;b&gt;오류동맛집&lt;/b&gt; #구로구맛집 #회먹는날</description>
			<bloggername>룰루랄라</bloggername>
			<bloggerlink>blog.naver.com/jisu9328</bloggerlink>
			<postdate>20240205</postdate>
		</item>
		<item>
			<title>대전 &lt;b&gt;오류동 맛집&lt;/b&gt; 서대전네거리 고기 넙딱집 메뉴 주차</title>
			<link>https://blog.naver.com/jthinkl/223410036399</link>
			<description>대전 오류동 고기 맛집 넙딱집 고급고기를 전문으로 하고, 한 번 먹으면 또 찾게되는 질 좋은 고기라고
				하셨는데, 맛있게 잘 먹고 왔습니다..♥ #대전맛집 #&lt;b&gt;오류동맛집&lt;/b&gt; #오류동고기맛집
				#서대전네거리역맛집...
			</description>
			<bloggername>일기쓰기</bloggername>
			<bloggerlink>blog.naver.com/jthinkl</bloggerlink>
			<postdate>20240409</postdate>
		</item>
		<item>
			<title>대전 &lt;b&gt;오류동 맛집&lt;/b&gt; 곱창명가 한우 곱창모듬구이</title>
			<link>https://blog.naver.com/jseonggyun/223356056270</link>
			<description>프리미엄 한우 곱창에 푸짐한 야채가 듬뿍 곱창명가 요새 오류동 먹자촌인 서대전네거리역 맛집에 잘...
				#대전&lt;b&gt;오류동맛집&lt;/b&gt; #&lt;b&gt;오류동맛집&lt;/b&gt; #서대전네거리역맛집
				#대전곱창구이맛집 #대전곱창구이 #대전곱창모듬...
			</description>
			<bloggername>뽀동이의 유쾌한 정보공간~♬</bloggername>
			<bloggerlink>blog.naver.com/jseonggyun</bloggerlink>
			<postdate>20240216</postdate>
		</item>
		<item>
			<title>대전 &lt;b&gt;오류동 맛집&lt;/b&gt; 구워주는 고기가 끝내준 임대장 대전오류점</title>
			<link>https://blog.naver.com/mangotech_/223397170066</link>
			<description>대전 &lt;b&gt;오류동 맛집&lt;/b&gt; 구워주는 고기가 끝내준 &amp;quot;임대장
				대전오류점&amp;quot; 대전 중구 계백로 1725-22 크럭스빌 105호 ⏰ 매일 16:00 ~ 24:00 (준비된
				고기 소진 시 조기마감) 오늘 소개드릴 곳은 오류동 먹자골목맛집인 임대장...
			</description>
			<bloggername>고슐랭가이드</bloggername>
			<bloggerlink>blog.naver.com/mangotech_</bloggerlink>
			<postdate>20240327</postdate>
		</item>
		<item>
			<title>대전 &lt;b&gt;오류동 맛집&lt;/b&gt; 쿠쿠마라탕 대전 마라탕 무한리필집 훠궈... </title>
			<link>https://blog.naver.com/rlaskfo86/223389786137</link>
			<description>대전 &lt;b&gt;오류동 맛집&lt;/b&gt;에서 무한리필로 즐깁니다요 고영쓰가 좋아하는 피쉬볼
				새우꼬치 싹 넣고 아웅 또먹고... 대전 오류동 점심 맛집 찾으시는 분들 식사하러 다녀오세요~ *업체에서 음식을
				제공받아...
			</description>
			<bloggername>햄볶는베짱이♩</bloggername>
			<bloggerlink>blog.naver.com/rlaskfo86</bloggerlink>
			<postdate>20240320</postdate>
		</item>
		<item>
			<title>[내돈내산] &lt;b&gt;오류동 맛집&lt;/b&gt; &amp;lt;명륜진사갈비 서울오류점&amp;gt;
			</title>
			<link>https://blog.naver.com/marobabo/223404105333</link>
			<description>식사 후 2차 필요하심 가기 좋으니 참고해보세요~ #명륜진사갈비 #서울 #구로 #오류동
				#&lt;b&gt;오류동맛집&lt;/b&gt; #서울&lt;b&gt;오류동맛집&lt;/b&gt; #구로로맛집 #회식장소
				#가족모임 #단체 #모임장소 #이용시간 #주차 #놀이방 #아이동반
			</description>
			<bloggername>영원이네 - 일상 여행 맛집 리뷰</bloggername>
			<bloggerlink>blog.naver.com/marobabo</bloggerlink>
			<postdate>20240403</postdate>
		</item>
		<item>
			<title>대전 &lt;b&gt;오류동 맛집&lt;/b&gt; 초월짬뽕 솔직후기</title>
			<link>https://blog.naver.com/sugark89/223409087684</link>
			<description>중구 오류동에 위치한 초월짬뽕 오룡역 2번 출구 인근에 자리하고 있어요 면과 육수를 직접 만드는...
				대전 짬뽕 맛집, 대전 탕수육 맛집, 대전 &lt;b&gt;오류동 맛집&lt;/b&gt;을 찾으신다면 초월짬뽕 어떠세요?
				맛있는 식사하시길...
			</description>
			<bloggername>김설탕의 보물창고</bloggername>
			<bloggerlink>blog.naver.com/sugark89</bloggerlink>
			<postdate>20240408</postdate>
		</item>
		<item>
			<title>대전 &lt;b&gt;오류동&lt;/b&gt; 삼겹 항정 육즙 팡팡
				연탄구이&lt;b&gt;맛집&lt;/b&gt; [고깃리88번지... </title>
			<link>https://blog.naver.com/zzinauling/223415114397</link>
			<description>#&lt;b&gt;오류동맛집&lt;/b&gt; #대전맛집 #서대전역맛집 #대전코스트코맛집
				#오류동고기집 #오류동고기맛집 대전오류동 육즙팡팡 연탄구이 맛집 [고깃리88번지 오류점] 주소 대전 중구 계룡로882번길
				14 1층 영업시간 매일 16:00...
			</description>
			<bloggername>인생은 주링이처럼 (p≧w≦q)</bloggername>
			<bloggerlink>blog.naver.com/zzinauling</bloggerlink>
			<postdate>20240414</postdate>
		</item>
		<item>
			<title>대전 &lt;b&gt;오류동 맛집&lt;/b&gt;, 서대전네거리 맛집, 아이와 먹자골목에서... </title>
			<link>https://blog.naver.com/ddong177/223388359361</link>
			<description>걸림 영업 타임 : 매일 11:30~23:00 브레이크 타임 : 오후 3시~ 5시까지 대전
				&lt;b&gt;오류동 맛집&lt;/b&gt; 에서 저희 가족 폭풍흡입한 리뷰였습니다. ㅋㅋ 서대전네거리 맛집을 찾으시면
				대전 &lt;b&gt;오류동 맛집&lt;/b&gt;인 서울갈비 한번 오시죠</description>
			<bloggername>스마일 북리치 블로그</bloggername>
			<bloggerlink>blog.naver.com/ddong177</bloggerlink>
			<postdate>20240319</postdate>
		</item>
	</channel>
</rss>

 

 

 

  • XML 파일의 특정 값만 출력하기

my_naver.py

# 네이버 검색 API 예제 - 블로그 검색
import os
import sys
import urllib.request
import requests
from bs4 import BeautifulSoup
client_id = "코드변경1"
client_secret = "코드변경2"
encText = urllib.parse.quote("오류동 맛집")
# url = "https://openapi.naver.com/v1/search/blog?query=" + encText # JSON 결과
url = "https://openapi.naver.com/v1/search/blog.xml?query=" + encText # XML 결과
request = urllib.request.Request(url)
request.add_header("X-Naver-Client-Id",client_id)
request.add_header("X-Naver-Client-Secret",client_secret)
response = urllib.request.urlopen(request)
rescode = response.getcode()

response_body = response.read()
html = response_body.decode('utf-8')
soup = BeautifulSoup(html, "lxml")
items = soup.find_all('item')
print(items)
print()

for idx,item in enumerate(items):
    title = item.find('title').text
    bloggername = item.find('bloggername').text
    print("{}\t{}\t{}".format(idx,title, bloggername))

 

결과 화면7

 

 

 

XML 결과로 출력하기

 

 

my_naver_json.py

# 네이버 검색 API 예제 - 블로그 검색
import os
import sys
import urllib.request
import requests
from bs4 import BeautifulSoup
import json
client_id = "코드변경1"
client_secret = "코드변경2"
encText = urllib.parse.quote("오류동 맛집")
url = "https://openapi.naver.com/v1/search/blog?query=" + encText # JSON 결과
# url = "https://openapi.naver.com/v1/search/blog.xml?query=" + encText # XML 결과
request = urllib.request.Request(url)
request.add_header("X-Naver-Client-Id",client_id)
request.add_header("X-Naver-Client-Secret",client_secret)
response = urllib.request.urlopen(request)
rescode = response.getcode()

response_body = response.read()
my_json = response_body.decode('utf-8')

oj = json.loads(my_json)
items = oj["items"]
print(items)
print()

for idx,item in enumerate(items):
    title = item["title"]
    bloggername = item["bloggername"]
    print("{}\t{}\t{}".format(idx,title, bloggername))

 

결과 화면8

 

 

 

DAO를 이용하여 크롤링한 데이터 집어넣기

 

 

blog 테이블 생성

생성한 테이블 정보 확인

 

 

daoblog.py

import pymysql

class Daoblog:
    def __init__(self):
        self.con = pymysql.connect(host='localhost', port=3305, user='root',
                              password='python', db='python', charset='utf8')

        self.cur = self.con.cursor(pymysql.cursors.DictCursor)

    def insert(self,title,link,description,bloggername,bloggerlink,postdate):
        sql = f"""
            INSERT INTO 
                blog (title, link, description, bloggername, bloggerlink, postdate)
            VALUES ("{title}","{link}","{description}","{bloggername}","{bloggerlink}","{postdate}")
        """
        cnt = self.cur.execute(sql)
        self.con.commit()
        return cnt
        
    def __del__(self):
        self.cur.close()
        self.con.close()
        
if __name__ == '__main__':
    de = Daoblog()
    cnt = de.insert('1', '1', '1', '1', '1', '1')
    print("cnt",cnt)

 

 

my_naver_todb.py

# 네이버 검색 API 예제 - 블로그 검색
import os
import sys
import urllib.request
import requests
from bs4 import BeautifulSoup
from day17.daoblog import Daoblog

db = Daoblog()

client_id = "코드변경1"
client_secret = "코드변경2"
encText = urllib.parse.quote("오류동 맛집")
# url = "https://openapi.naver.com/v1/search/blog?query=" + encText # JSON 결과
url = "https://openapi.naver.com/v1/search/blog.xml?query=" + encText # XML 결과
request = urllib.request.Request(url)
request.add_header("X-Naver-Client-Id",client_id)
request.add_header("X-Naver-Client-Secret",client_secret)
response = urllib.request.urlopen(request)
rescode = response.getcode()

response_body = response.read()
html = response_body.decode('utf-8')
soup = BeautifulSoup(html, "xml")
items = soup.find_all('item')
print(items)
print()

for idx,item in enumerate(items):
    title = item.find('title').text
    link = item.find('link').text
    description = item.find('description').text
    bloggername = item.find('bloggername').text
    bloggerlink = item.find('bloggerlink').text
    postdate = item.find('postdate').text
    
    cnt = db.insert(title,link,description,bloggername,bloggerlink,postdate)
    print("{}\t{}\t{}".format(idx,cnt,title))

 

결과 화면9

 

추가된 DB 값 확인

 

 

반응형
1 2 3 4 ··· 13