반응형

 응용】 파이썬 웹 크롤링#3 (Web Crawling) - 원하는 페이지 수만큼 검색하여 저장하기 

 크롤링이란,  인터넷에서 특정 검색(어)으로 검색하여 (자료를) 긁어(스크랩) 모우는 행위를 일컫는다. 이를 파이썬 코드나 시스템을 이용해서 반자동으로 긁어 모으고 과정을 일컫는다.  

 이 번 내용에서는 웹 검색 결과를 스크래핑하여 쉼표 단위로 저장이 되는 csv 형태로 저장하고자 한다. 

csv 형태로 저장하는 이유는 메모장에서도 열수 있고, 엑셀에서 군더더기 없이 셀(cell) 별로 읽어 들여, 이후의 가공이나 편집이 용이하기 때문이다. 

 

 지난시간에는 네이버 M이라 하여 모바일 버전에서 검색되는 내용을 csv 파일로 저장해 보았다. 

이번에는 코드가 조금 더 복잡하지만, 일반 PC 화면에서의 네이버 검색 결과를 저장해보려 한다.

블로그를 기준으로 특정 명령어를 검색하는 것을 기준으로 다루어 보겠다. 

필요에 따나, 카페 검색이나, 웹 검색을 원한다면 아래 코드를 살짝만 맞추어 주면 된다.

  

 검색결과는 보통 한 페이지당 10개의 내용(제목과 간단한 설명과 링크)이 담겨 있다. 검색 내용이 많은 경우 이런 페이지가 수십 페이지를 넘어가게 되는데,  직전 크롤링 코드로는 첫 페이지에 나오는 내용만 담을 수 있는 코드여서 2페이지 이상의 내용을 저장할 수 없었다.  그래서 한 페이지에 몰아서 출력되는 네이버 모바일 M의 View 메뉴 검색 페이지를 이용하였던 것이다. 

 

 그러나 이번에는, 원하는 검색페이지 수만큼 결과를 저장해 보는 크롤링 코드를 짜 보려 한다. 

예를 들아 네이버 검색창에 '파이썬'이라 검색하면, 수십페이지의 검색 결과가 뜨는데,  원하는 페이지 수를 예를 들어 '10'이라고 추가로 입력하면,  1페이지부터 10페이지까지의 검색된 결과 중에서, 타이틀 제목과, 링크 주소를  csv 파일로 저장해 보는 파이썬 코드를 다루고자 한다. (콘솔 창에도 해당 결과를 출력해보자)

 

그럼 이제 코딩을 해보자. 

먼저, 크롤링이 처음 이라면, 선수학습 자료를 먼저 살펴보기 바란다.

[선수학습]

2020/01/01 - [Language/파이썬 Python] - 【파이썬 응용】파이썬 웹 크롤링(Web Crawling)

2020/01/02 - [Language/파이썬 Python] - 【파이썬 응용】 파이썬 웹 크롤링#2(Web Crawling) -검색결과를 csv파일로 저장하기

 

# 먼저 선수학습에 있는 내용을 참고하여,  핵심내용(타이틀 제목과 링크 주소)만 집어 내기 위해,  웹페이지에서 F12키를 눌러 웹 분석도구를 이용해서 'sh_blog_title',  title',  'href' 같은 요소들을 파악해 낸다. 

그런 다음, 아래코드를 주석을 참고하면서 작성한다. 

# 아래 url 주소 부분은 네이버 검색창에서 '파이썬'으로 검색 후 블로그 항목 클릭한 상태에서, 검색 하단에 보면, 검색 페이지들이 숫자로 되어 있는 부분이 있다.  여기 페이지 숫자 아무거나 하나를 클릭한다. 

그런 다음 나타나는 웹브라우저의 주소창의 주소를 복사해서 붙여 넣으면 되고,  주황색부분을 보면 기존에 있는 내용은 삭제를 하고 아래처럼 바꾸어 주면 된다.

 

주소 부분 : https://search.naver.com/search.naver?date_from=&date_option=0&date_to=&dup_remove=1&nso=&post_blogurl=&post_blogurl_without=&query=%ED%8C%8C%EC%9D%B4%EC%8D%AC&sm=tab_pge&srchby=all&st=sim&where=post&start=1

 

위 주소부분을 카피해보면, 한글 검색의 경우 '파이썬'의 아스키코드 변환 값인 '%ED%8C%8C%EC%9D%B4%EC%8D%AC' 형태로 되어 있는데,  이 부분을 삭제하면 된다. 

이 부분을 삭제하고 변수로 입력받아 원하는 검색어로 검색하게 하려는 것이다. 

 

또한 검색하단에 검색 페이지 숫자를 클릭해서 나오는 값은 주소 끝부분에 나타나는데, 이 부분만 페이지를 바꾸어 누를 때마다 달라진다.   어떻게 변하는지 각 페이지를 클릭해보면 파악할 수 있다. 

1 페이지 끝 부분 숫자는 '1' 로 되어 있다.
2 페이지 끝 부분 숫자는 '11' 로 되어 있다.
3 페이지 끝 부분 숫자는 '21' 로 되어 있다.

위의 캡쳐 이미지를 살펴보면,  첫 페이지 끝 부분 숫자는 '1'로 되어 있고,  2페이지 끝 부분 숫자는 '1' 로 되어 있으며, 3 페이지 끝 부분 숫자는 '21' 로 되어 있음을 알 수 있다.

그렇다면, 4페이지는 숫자가 '31', 5페이지는 숫자가 '41'이런 식으로 바뀐다는 것을 짐작할 수 있게 된다. 

따라서, 이 숫자 부분을 변수 처리하여 원하는 페이지를 입력받아 해당 페이지까지만 검색결과를 저장하는 코드를 작성해 볼 수 있다. 

 

1. 코드 code

~~~~~~~~~~~~~~~~~~~~~~~~~~~

import csv

import urllib.request

from urllib.parse import quote_plus

from bs4 import BeautifulSoup

 

search = input('검색어를 입력하세요:')

pageNum = 1

i = input('검색할 페이지 수? :')   # 숫자를 입력받아도 input()함수는 문자로 저장된다.

# 블로그 검색 1페이지는 끝에 숫자가 01,  2페이지는 11, 5페이지는 41... 10페이지는 91 붙는다

lastPageNum = int(i) * 10 - 9

f = open(f'{search}.csv''w'encoding='utf-8'newline='' # 검색 제목을 입력하면 그 이름으로 파일 오픈(저장)

searchList = []

 

# 아래 주소 줄에서 주황색 부분, quote_plus() 를 추가하여 search에 한글 제목이 입력될 경우 , 한글제목.csv로 저장되도록 한다  '한글 검색어에 대한 대응(변환)을 위해 quote_plus( ) 함수 사용하여 변환.

# 검색 페이지별로 url이 달라지는 부분은 아래 주황색 부분인 것을 클릭해보면 알아 낼 수 있다. 

 

while pageNum < lastPageNum + 1:

    url = f'https://search.naver.com/search.naver?date_from=&date_option=0&date_to=&dup_remove=1&nso=&post_blogurl=&post_blogurl_without=&query={quote_plus(search)}&sm=tab_pge&srchby=all&st=sim&where=post&start={pageNum}'

    html = urllib.request.urlopen(url).read()

    soup = BeautifulSoup(html, 'html.parser')

    title = soup.find_all(class_='sh_blog_title')

    

    for i in title:

        temp = []

        temp.append(i.text)       # 각 타이틀 제목 저장

        temp.append(i.attrs['href'])  # 각 타이틀 제목의 링크 저장

        searchList.append(temp)

        print(i.attrs['title'])    # 콘솔창에 출력

        print(i.attrs['href'])      # 콘솔창에 출력

        print()  # 공백(빈줄) 출력

    pageNum += 10   # 페이지마다 주소 끝에 붙는 숫자가(pageNum) 10 단위씩 변하기 때문

 

f = open(f'{search}.csv', 'w'encoding='utf-8'newline='')

csvWriter = csv.writer(f)

for i in searchList:

    csvWriter.writerow(i)

f.close()

 

 출력 결과 :

1. 콘솔창 출력 결과

 

2. 엑셀 파일 출력 결과

아래와 같은 형태의 파일이 저장되었다. 

 이 파일을 엑셀과 같은 프로그램으로 열어 보면 저장이 되어 있다.  다만, 아래처럼 깨져 열리게 된다.

 이럴 때는 리브레 오피스 같은 걸로 열 경우(유니코드 UTF-8) 형식으로 옵션을 맞추어 열면 한글이 깨지지 않게 열린다. 

만약 MS엑셀 같은 걸로 열 경우는 열기 전에 Utf-8로 미리 설정하는 옵션이 없기 때문에, 

파이썬.csv 파일을 메모장으로 열고 메모장에서 열면 아래처럼 한글이 깨지지 않게 열리고, 

이를 다른 이름(파이썬 1.csv)으로 저장할 때 '인코딩(E)' 옵션 부분을 눌러 ANSI로 저장한다. 

그런 다음 MS 엑셀에서 열면 맨 아래 그림처럼 한글이 깨지지 않게 잘 열리게 된다.   

 

최종 엑셀 파일을 열어 보면,

(블로그 항목에서)  검색명은 '파이썬'으로 하였고,  검색 페이지 수는 '3'을 입력한 결과가 엑셀로 깔끔하게 저장된 것을 알 수 있다. 

검색 한 페이지당 10개의 내용(링크)이 있으니,  '3'페이지면 30개의 내용이 저장되어야 하니, 정확히 잘 저장된 것을 알 수 있다. 

 

이런 웹 스크래핑을 통하여, 일일이 검색하거나 일일이 캡처하지 않아도, 특정 검색 자료를 목록으로 정리할 수 있어, 활용도가 높다고 할 수 있겠다. 

 

파이썬, 코드 다운로드 :

webcrawling3-multipage.py
0.00MB

반응형
반응형

 응용】 파이썬 웹 크롤링#2(Web Crawling) -검색결과를 csv파일로 저장하기 

 

크롤링이란,  인터넷에서 특정검색(어)로 검색하여 (자료를) 긁어(스크랩) 모우는 행위를 일컫는다. 이를 파이썬코드나 시스템을 이용해서 반자동으로 긁어 모으로 과정을 일컫는다.  

 이 번 내용에서는 웹 검색 결과를 스크래핑하여 쉼표 단위로 저장이 되는 csv 형태로 저장하고자 한다. 

csv 형태로 저장하는 이유는 메모장에서도 열수 있고, 엑셀에서 군더더기 없이 셀(cell)별로 읽어 들여, 이후의 가공이나 편집이 용이하기 때문이다. 

 

이번에는 지난시간과 달리 검색되는 내용을 전체페이지 모두 긁어 저장하려 하는데,  PC버전 네이버로 검색하지 않고 모바일 버전인 네이버 M 버전으로 PC에서 검색하는 형태로 코딩을 구성하려 한다. 

왜냐하면 모바일 M 네이버의 (VIEW 메뉴 클릭) 하면, 검색 결과를 10개씩 페이지 별로 나타 내지 않고, 한 페이지에 모든 검색 결과를 담아 보여주기 때문인데,  스크롤 내리는 족족 검색되는 결과를 보여주기 때문에,  페이지 단위별 스크래핑을 고려 할 필요가 없기 때문이다. 

PC에서 모바일 버전 네이버 검색을 해보려면  m.naver.com 으로 접속을 하면 되며, 

검색창에 '파이썬' 검색을 입력하고 검색한 후 메뉴에서 View 를 클릭해서 보면, 

검색결과가 계속 내려도 한 페이지에 모두 표시 되도록 스크롤이 계속 내려가는 것을 알 수 있다.

 

그럼 이제 코딩을 해보자. 

먼저, 크롤링이 처음 이라면, 선수학습 자료를 먼저 살펴보기 바란다.

[선수학습]

2020/01/01 - [Language/파이썬 Python] - 【파이썬 응용】파이썬 웹 크롤링(Web Crawling)

 

 

# 먼저 네이버 모바일(M) 페이지에서 F12키를 눌러 웹 분석도구로 아래와(api_tx....) 같은 주요 특징(타이틀 제목 인근의 HTML 문법)을 파악해 낸다.

# api_txt_lines dsc_txt  

1. 기본 검색 코드

~~~~~~~~~~~~~~~~~~~~~~

import csv

from urllib.request import urlopen

from urllib.parse import quote_plus

from bs4 import BeautifulSoup

search = input('검색어를 입력하세요? :')

# 아래와 같이 하면 search 부분에 입력문자를 직접 대응시킬 수 있다.

# url = f'https://m.search.naver.com/search.naver?where=m_view&sm=mtb_jum&query={search}'

# 하지만, search 부분에는 입력된 한글이 웹에 사용하는 형식으로 인코딩 된 된 문자가 들어가야 한다. (quote_... 사용)

url = f'https://m.search.naver.com/search.naver?where=m_view&sm=mtb_jum&query={quote_plus(search)}'

html = urlopen(url).read()

soup = BeautifulSoup(html, 'html.parser')

total = soup.select('.api_txt_lines.total_tit'# 내용이 두 개임, 공백을 없애고 점을 찍어 붙여준다

print(total[0])

~~~~~~~~~~~~~~~~~~

여기까지의 '자바'라는 검색어를 넣어 결과를 출력해보면 아래와 같다.

2. 이제 반복문(for)을 넣어 검색결과를 모두 출력해보자.

~~~~~~~~~~~~~~~~~~~~~~

import csv

from urllib.request import urlopen

from urllib.parse import quote_plus

from bs4 import BeautifulSoup

search = input('검색어를 입력하세요? :')

# 아래와 같이 하면 search 부분에 입력문자를 직접 대응시킬 수 있다.

# url = f'https://m.search.naver.com/search.naver?where=m_view&sm=mtb_jum&query={search}'

# 하지만, search 부분에는 입력된 한글이 웹에 사용하는 형식으로 인코딩 된 된 문자가 들어가야 한다. (quote_... 사용)

url = f'https://m.search.naver.com/search.naver?where=m_view&sm=mtb_jum&query={quote_plus(search)}'

html = urlopen(url).read()

soup = BeautifulSoup(html, 'html.parser')

total = soup.select('.api_txt_lines.total_tit' # 내용이 두 개임, 공백을 없애고 점을 찍어 붙여준다

for i in total:

    print(i.text)

    print(i.attrs['href'])

    print()

~~~~~~~~~~~~~~~~~~

출력결과 :

 

3. 이제 여기에 

 

~~~~~~~~~~~~~~~~~~~~~

import csv

from urllib.request import urlopen

from urllib.parse import quote_plus

from bs4 import BeautifulSoup

# api_txt_lines dsc_txt  // 클래스가 두 개임.  따라서 아래 부분에 공백을 없애고 점을 찍어 붙여준다

search = input('검색어를 입력하세요? :')

# 아래와 같이 하면 search 부분에 입력문자를 직접 대응시킬 수 있다.

# url = f'https://m.search.naver.com/search.naver?where=m_view&sm=mtb_jum&query={search}'

# 하지만, search 부분에는 입력된 한글이 웹에 사용하는 형식으로 인코딩 된 된 문자가 들어가야 한다. (quote_... 사용)

url = f'https://m.search.naver.com/search.naver?where=m_view&sm=mtb_jum&query={quote_plus(search)}'

html = urlopen(url).read()

soup = BeautifulSoup(html, 'html.parser')

total = soup.select('.api_txt_lines.total_tit')

searchList = []

 

for i in total:

    temp = []

    temp.append(i.text)    # 텍스트 부분만 추출하여 저장(추가)함

    temp.append(i.attrs['href'])  # href '주소' 부분만 추출하여 저장(추가)함

    searchList.append(temp)

 

# newline=''는 첫번째 데이터다음 한줄 내려주는 역할이다.

# 한글 때문에 utf-8로 엔코딩한다.

f = open(f'{search}.csv''w'encoding='utf-8'newline='')

csvWriter = csv.writer(f)

# 반복문을 만들어 csv 파일에 하나씩 데이터를 추가(기록)해준다.

for i in searchList:

    csvWriter.writerow(i)

f.close()


 출력 결과 :

아래와 같은 형태의 파일이 저장 되었다. 

 이 파일을 엑셀과 같은 프로그램으로 열어 보면 저장이 되어 있다.  다만, 아래 처럼 깨져 열리게 된다.

 이럴때는 리브레 오피스 같은 걸로 열 경우(유니코드UTF-8) 형식으로 옵션을 맞추어 열면 한글이 깨지지 않게 열린다. 

만약 MS엑셀 같은 걸로 열경우는 열기전에 Utf-8로 미리 설정하는 옵션이 없기 때문에, 

파이썬.csv 파일을 메모장으로 열고 메모장에서 열면 아래처럼 한글이 깨지지 않게 열리고, 

이를 다른이름(파이썬1.csv)으로 저장할 때 '인코딩(E)' 옵션 부분을 눌러 ANSI로 저장한다. 

그런 다음 MS엑셀에서 열면 맨 아래 그림처럼 한글이 깨지지 않게 잘 열리게 된다.   

※ 컴파일 과정에서 에러가 난다면, url 부분에 공백이 들어가면 안 되니 확인해보면 된다. 

 

여기에서 일반 PC용 네이버 페이지를 이용하지 않고, M.naver 페이지의 View 메뉴를 이용한 이유는 검색어로 검색했을 때 페이지 단위로 검색이 되면 그 한 페이지(약 10개) 정도의 내용만 페이지 별로 분류가 되기 때문에 좀더 복잡한 코드(방법)을 사용해야 하기 때문이다.   

 

파이썬, 코드 다운로드 :

WebCrawlingCSV.py
0.00MB

반응형