728x90

행정안전부 RSS 데이터를 가져오기 위한 기초 이미지이다.

 

 

 

#GET 방식 데이터 통신
import urllib.request
import urllib.parse
 
# 행정안전부
API = "https://www.mois.go.kr/gpms/view/jsp/rss/rss.jsp"
params = []
 
for num in [1001,1002,1003,1004]:
    params.append(dict(ctxCd=num))
 
#중간 확인
#print(params)
 
# 연속해서 4번 요청하기
for c in params:
    # 파리미터 출력
    #print(c)
    #URL 인코딩
    param = urllib.parse.urlencode(c)
 
    # URL 완성
    url = API + "?" + param
    # URL 출력
    print("url : ", url)
 
    # 요청
    res_data = urllib.request.urlopen(url).read()
    #print(res_data)
 
    #수신 후 디코딩
    contents = res_data.decode("UTF-8")
 
    # 출력
    print("-" * 100)
    print(contents)
    print("-" * 100)
 
 

 

테스트 파이썬 코드

crawling_07.py
0.00MB

728x90
블로그 이미지

Link2Me

,
728x90

크롤링 기초가 되는 파이썬 정보 확인 코드 예제이다.

#GET 방식 데이터 통신
import urllib.request
from urllib.parse import urlparse
 
# 기본 요청
url = "http://www.encar.com"
 
mem = urllib.request.urlopen(url)
 
# 여러정보 출력
print('type : {}'.format(type(mem)))
print('geturl : {}'.format(mem.geturl()))
print('status : {}'.format(mem.status))
print('header : {}'.format(mem.getheaders()))
print('getcode : {}'.format(mem.getcode()))
print('read : {}'.format(mem.read(100).decode('utf-8')))
print('parase : {}'.format(urlparse('http://www.encar.com/index.do?id=test&pw=1111').query))
 
# 기본요청(ipify)
API = "https://api.ipify.org"
 
# GET 방식 파라미터
values = {
    'format' : 'json'
}
 
print('before param : {}'.format(values))
params = urllib.parse.urlencode(values)
print('after param : {}'.format(params))
 
# 요청 URL 생성
URL = API + "?" + params
print("요청 URL = {}".format(URL))
 
# 수신 데이터 읽기
data = urllib.request.urlopen(URL).read()
 
# 수신 데이터 디코딩
text = data.decode('UTF-8')
print('response : {}'.format(text))
 

 

테스트 코드 파일

crawling_06.py
0.00MB

 

728x90
블로그 이미지

Link2Me

,
728x90

XML이란 내부적으로 트리 구조를 가지고 있는 파일을 표현하기 위해 사용하는 마크업 언어다.
웹페이지를 보여주기 위해 사용되는 html 파일이 XML의 가장 대표적인 예시다.

 

네이버 뉴스 가져오기는 실패하여 일단 기능 테스트를 위해 네이버지식인 정보가져오기를 시도했더니 잘된다.

#파이썬 크롤링 기초
# pip install lxml 을 윈도우 cmd 창에서 실행한다.
# pip install --upgrade pip
# pip list
# pip install requests
# pip install cssselect
 
from typing import get_args
import requests
from lxml.html import fromstring, tostring
 
def main():
    """
    네이버 지식인 스크랩핑 메인 함수
    """
 
    # 세션 사용
    session = requests.Session()
 
    # 스크랩핑 대상 URL (GET, POST)
    response = session.get("https://kin.naver.com/search/list.nhn?query=%ED%8C%8C%EC%9D%B4%EC%8D%AC")
 
    # 신문사 링크 리스트 획득
    urls = scrape_news_list_page(response)
 
    # 딕셔너리 확인
    # print(urls)
 
    # 결과 출력
    for name, url in urls.items():
        # url 출력
        print(name, url)
 
        # 파일 쓰기
        # 생략
 
def scrape_news_list_page(response):
    # url 리스트 선언
    urls = {}
 
    # 태그 정보 문자열 저장
    #print(response.content)
    root = fromstring(response.content)
    #print(root)
 
    for a in root.xpath('//ul[@class="basic1"]/li/dl/dt/a[@class="_nclicks:kin.txt _searchListTitleAnchor"]'):
        # a 구조 확인
        # print(a)
 
        # a 문자열 출력
        # print(tostring(a, pretty_print=True))
 
        name, url = extract_conents(a)
        # 딕셔너리 삽입
        urls[name] = url
        
    return urls
 
def extract_conents(doc):
    # 링크 주소
    link = doc.get("href")  
    name = doc.text_content()
    return name, link
 
 
# 스크랩핑 시작
if __name__ == "__main__":
    main()
 
 

 

크롤링을 위한 Chrome 브라우저 개발자 모드 html 코드보기 예시이다.

테스트에 사용한 파이썬 소스 코드

crawling_02.py
0.00MB

 

위 코드와 아래 BeautifulSoup4 를 이용한 코드 비교를 해보면 훨씬 더 간단하다는 걸 알 수 있다.

# 네이버 검색결과 크롤러 만들기
# BeautifulSoup은 HTML 과 XML 파일로부터 데이터를 수집하는 라이브러리
# pip install bs4
# pip install requests
 
import requests
from bs4 import BeautifulSoup
#import ssl
 
url = 'https://kin.naver.com/search/list.nhn?query=%ED%8C%8C%EC%9D%B4%EC%8D%AC'
 
response = requests.get(url)
 
if response.status_code == 200:
    html = response.text
    soup = BeautifulSoup(html, 'html.parser')
    ul = soup.select_one('ul.basic1')
    titles = ul.select('li > dl > dt > a')
    for a in titles:
        print(a.get_text(), end=' : ')
        print(a.get('href'))
else : 
    print(response.status_code)
 

 

728x90
블로그 이미지

Link2Me

,
728x90

파이썬을 배우는 중인데 헤드라인 뉴스 가져오기를 시도했는데 실패했다.

실패한 기록도 저장하고, 나중에 더 배우면 그때 해결해보련다. ==> 크롤링 다른 라이브러리를 이용하여 해결

#파이썬 크롤링 기초
# pip install lxml 을 윈도우 cmd 창에서 실행한다.
# pip install --upgrade pip
# pip list
# pip install requests
# pip install cssselect
# pip install bs4 (BeautifulSoup 4)
 
import requests
import lxml.html
 
def main():
    """
    네이버 메인 뉴스 스탠드 스크랩핑 메인 함수
    """
 
    # 세션 사용
    session = requests.Session()
 
    # 스크랩핑 대상 URL (GET, POST)
    response = session.get("https://news.naver.com/")
 
    # 신문사 링크 리스트 획득
    urls = scrape_news_list_page(response)
 
    # 딕셔너리 확인
    #print(urls)
 
    # 결과 출력
    for url in urls:
        # url 출력
        print(url)
        # 파일 쓰기
        # 생략
 
def scrape_news_list_page(response):
    # url 리스트 선언
    urls = {}
 
    # 태그 정보 문자열 저장
    print(response.content)
    root = lxml.html.fromstring(response.content)
    #print(root)
 
    # for a in root.cssselect('#today_main_news > div.hdline_news > ul > li > div > a'):
 
    for a in root.xpath('//div[@class="hdline_news"]/ul[@class="hdline_article_list"]/li/div[@class="hdline_article_tit"]/a[@class="lnk_hdline_article"]'):
        # 링크
        url = a.get('href')
        urls.append(url)
    return urls
 
 
# 스크랩핑 시작
if __name__ == "__main__":
    main()
 
 

 

 

위 방법으로 해결이 안되어서 selenium 으로 실시간 뉴스 가져오는 걸 해결했다.

Update : 2021.6.28(월)

# 네이버 실시간 뉴스 정보 가져오기
# BeautifulSoup은 HTML 과 XML 파일로부터 데이터를 수집하는 라이브러리
# pip install selenium
# pip install chromedriver-autoinstaller 
# pip install bs4
 
from selenium import webdriver
import chromedriver_autoinstaller
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from bs4 import BeautifulSoup
 
options = Options()
# options.add_experimental_option('excludeSwitches', ['enable-logging'])
options.add_argument('headless'); # headless는 화면이나 페이지 이동을 표시하지 않고 동작하는 모드
 
# webdirver 설정(Chrome, Firefox 등)
chromedriver_autoinstaller.install()
driver = webdriver.Chrome(options=options) # 브라우저 창 안보이기
# driver = webdriver.Chrome() # 브라우저 창 보이기
 
# 크롬 브라우저 내부 대기 (암묵적 대기)
driver.implicitly_wait(5)
 
# 브라우저 사이즈
driver.set_window_size(1920,1280)
 
# 페이지 이동(열고 싶은 URL)
baseURL = 'https://news.naver.com/'
driver.get(baseURL)
 
soup = BeautifulSoup(driver.page_source, 'html.parser')
headline_new_list = soup.select('ul.hdline_article_list > li')
 
print('-' * 55, end=' ')
print('네이버 실시간 뉴스',end=' ')
print('-' * 55)
for v in headline_new_list:
    # print(v)
    title = v.select_one('div.hdline_article_tit > a').text.strip()
    news_url = v.select_one('div.hdline_article_tit > a').get('href')
    news_url = '{}{}'.format(baseURL,news_url)
    print(title, ', ', news_url)
print('-' * 130)
 

 

crawling_22.py
0.00MB

728x90
블로그 이미지

Link2Me

,
728x90

beautifulSoup 의 기본적인 사항을 알아보자.

# bs4 초기화
soup = BeautifulSoup(html, 'html.parser')
 
# 타입 확인
print('soup', type(soup))
 
# 코드 정리
print('prettify', soup.prettify())
 
# h1 태그 접근
h1 = soup.html.body.h1
print('h1', h1)
 
# p 태그 접근
p1 = soup.html.body.p
print('p1', p1)
 
# 다음 태그
p2 = p1.next_sibling.next_sibling
print('p2', p2)

 

link1 = soup.find_all("a", class_='sister')  # {} 다중 조건
print(link1)
 
# 다중 조건
link1 = soup.find("a", {"class""sister""data-io""link1"})
 
 
# CSS 선택자
# 태그 + 클래스 + 자식 선택자
link1 = soup.select_one("p.title > b")
 
# 태그 + id 선택자
link1 = soup.select_one("a#link1")
 
# 태그 + 속성 선택자
link1 = soup.select_one("a[data-io='link1']")

 

soup.find('a')  # <a href="www.google.com">구글</a>
 
soup.find('a').get('href')  # www.google.com
soup.find('a').get_text()  # 구글

 

 

 

필요 자료는 구글 크롬브라우저 개발자 도구를 이용하면 html 구조를 파악할 수 있다.

예제로 https://kin.naver.com/search/list.nhn?query=%ED%8C%8C%EC%9D%B4%EC%8D%AC 사이트를 선택했다.

 

ul 태그 하위 요소로 li 태그가 10개 인것을 확인할 수 있다.

 

 

DOM 트리 구조를 보면 ul > li > dl > dt > a 태그 순으로 되어 있다.

원하는 정보를 추출하기 위한 정보 파악은 된 거 같다.

 

파이썬 코드 및 pip 인스톨 사항

파이썬에서 기본적으로 내장된 함수가 아니기 때문에 pip 인스톨을 해준 후에 해당 라이브러리를  import 해준다.

# 네이버 검색결과 크롤러 만들기
# BeautifulSoup은 HTML 과 XML 파일로부터 데이터를 수집하는 라이브러리
# pip install bs4
# pip install requests
 
import requests
from bs4 import BeautifulSoup
#import ssl
 
url = 'https://kin.naver.com/search/list.nhn?query=%ED%8C%8C%EC%9D%B4%EC%8D%AC'
 
response = requests.get(url)
 
if response.status_code == 200:
    html = response.text
    soup = BeautifulSoup(html, 'html.parser')
    ul = soup.select_one('ul.basic1')
    titles = ul.select('li > dl > dt > a')
    for title in titles:
        print(title.get('href'))
else : 
    print(response.status_code)

find(복수는 find_all)와 select(한 개 찾을때에는 select_one) 를 이용한 방법으로 나눌 수 있다.

링크는 <a href = '주소'> 누르면 다운</a> 이런 형태로 되어있다.

soup.select('a')[0]['href'] 이런 식으로 한정한 이후 [속성명] 을 넣어주면 속성 값을 가져올 수 있다.

# 링크 주소를 가져올때(첫 번째 꺼 하나만)

select('a')[0]['href']

 

SELECT 설명

select(), select_one() 설명

태그이름 태그이름으로 찾음
.클래스이름 클래스이름으로 찾음
#아이디이름 아이디이름으로 찾음 (아이디는 연속X)
상위태그이름 > 자식태그 > 자식태그 부모 자식간의 태그 조회' >' 로 구분
상위태그이름 자손태그 부모 자손간의 태그 조회 #띄어쓰기(공백) 로 구분 #자식을 건너 띈다.
[속성] 태그 안의 속성을 찾음
태그이름.클래스이름 해당태그의 클래스이름을 찾음
#아이디이름 > 태그이름.클래스이름 아이이디 이름으로 찾고 자식태그와 클래스이름으로 찾음

 

 

 

실행 결과

 

 

 

페이지를 파싱처리 하다보면 iframe을 사용한 코드를 만날 수 있다.

<iframe src="삽입할페이지주소" width="너비" height="높이"></iframe>

아래 코드는 네이버 증권 정보를 파싱처리하는 코드 예시다.

import requests
from fake_useragent import UserAgent
# BeautifulSoup은 HTML 과 XML 파일로부터 데이터를 수집하는 라이브러리
from bs4 import BeautifulSoup
import pymysql
import re
import os, sys
from io import StringIO
 
# PHP로부터 전달받은 코드변수
code = sys.argv[1]
 
 
def coinInfoData(code):
    url = f'https://finance.naver.com/item/coinfo.naver?code={code}'
    ua = UserAgent()
    headers = {'User-agent': ua.ie}
    res = requests.get(url, headers=headers)
 
    if res.status_code == 200:
        html = res.text
 
        # HTML 페이지 파싱 BeautifulSoup(HTML데이터, 파싱방법)
        soup = BeautifulSoup(html, 'html.parser')
 
        # 보유지분이 포함된 페이지 iframe
        frame = soup.find('iframe', id="coinfo_cp")
 
        # iframe의 url 추출
        frameaddr = frame['src']
 
        frame_res = requests.get(frameaddr, headers=headers)
 
        if frame_res.status_code == 200:
 
            # HTML 페이지 파싱
            frame_soup = BeautifulSoup(frame_res.text, 'html.parser')
 
            # #cTB13 > tbody
            coinfo = frame_soup.find_all('td',{'class':'noline-right num'})
            # print(coinfo)
            sum = 0
            for val in coinfo:
                info = val.text.strip()
                if not info == '':
                    info = float(info)
                    sum = sum + info
            # print(sum)
 
            conn = pymysql.connect(host="localhost", user="", password="", db="", charset="utf8")
            curs = conn.cursor()
            sql = "update stocks SET LSholdings=%s where code=%s"
            val = (sum,str(code))
            curs.execute(sql, val)
            conn.commit()
            conn.close()
            print('Finished')
 
        else:
            print(frame_res.status_code)
 
    else:
        print(res.status_code)
 
 
if __name__ == '__main__':
    coinInfoData(code)
    

 

 

728x90
블로그 이미지

Link2Me

,
728x90

파이썬 강의를 듣고 그대로 따라 적어본 코드이다.

경로명은 C:/ 로 하니까 퍼미션 에러가 발생해서 User 폴더로 지정했다.

from urllib import response
import urllib.request as req
from urllib.error import URLError, HTTPError
 
# 다운로드 경로 및 파일명
path_list = ["c:/Users/zx/Documents/Python/test1.jpg""c:/Users/zx/Documents/Python/index.html"]
 
# 다운로드 리소스 url
target_url = ["https://search.pstatic.net/sunny/?src=https%3A%2F%2Fi.pinimg.com%2F736x%2F7a%2F89%2F24%2F7a8924ac188a415140c0c564ec7687c5--plans-lions-club.jpg","https://google.com"]
 
for i, url in enumerate(target_url):
    # 예외 처리
    try:
        # 웹 수신 정보 읽기
        response = req.urlopen(url)
 
        # 수신 내용
        contents = response.read()
 
        print("-----------------------------")
 
        # 상태 정보 중간 출력
        print('Header Info-{} : {}'.format(i, response.info()))
        print('HTTP Status Code: {}'.format(response.getcode()))
        print()
        print("--------------------------------------------")
 
        with open(path_list[i], 'wb'as c:
            c.write(contents)
        
    except HTTPError as e:
        print("Download failed.")
        print("HTTPError code : ", e.code)
    except URLError as e:
        print("Download failed.")
        print("URL Error Reason : ", e.reason)
    # 성공
    else:
        print()
        print("Download Succeed.")
 

 

728x90
블로그 이미지

Link2Me

,