파이썬 웹 크롤링(Web Crawling) 웹페이지 긁어오기

반응형

파이썬 웹 크롤링(Web Crawling) - Basic

웹 크롤러(Web Crawler)는 자동화된 방식으로 웹 페이지들을 탐색하는 컴퓨터 프로그램입니다.
웹 크롤러가 하는 작업을 웹 크롤링(Web Crawling)이라고 부릅니다.

Beautiful Soup

기본 세팅
기본적으로 패키지 import를 통해서 가져오며 html파일을 가져오거나 urllib 혹은 requests 모듈을 통해서 직접 웹에서 소스를 가져올 수도 있습니다.

주요 함수

find() 및 find_all()함수

  • 함수 인자로는 찾고자 하는 태그의 이름, 속성 기타 등등이 들어갑니다.

  • find_all(name, attrs, recursive, string, limit, **kwargs)
    find_all() : 해당 조건에 맞는 모든 태그들을 가져옵니다.

html = urlopen('url 주소') 
soup = BeautifulSoup(html, 'html.parser')
all_divs = soup.find_all("div")
print(all_divs)
------------------
# find_all('태그명', {'속성명' : '값' ...})
ex_id_divs = soup.find('div', {'id' : 'ex_id'})
print(ex_id_divs)

find(name, attrs, recursive, string, **kwargs)
find() : 해당 조건에 맞는 하나의 태그를 가져온다. 중복이면 가장 첫 번째 태그를 가져온다.

html = urlopen('url 주소') 
soup = BeautifulSoup(fp, 'html.parser')
ex_id_divs = soup.find('div', {'id' : 'ex_id'})
print(ex_id_divs)
-----------------
#find('태그명', {'속성명' : '값' ...})
first_div = soup.find("div")
print(first_div)

예제 1) 웹 문서 전체 가져오기


$ pip install requests
$ pip install beautifulsoup4

request : Requests를 사용하면 간단한 코드만으로 웹페이지의 html 소스를 가져올 수 있습니다.
beautifulsoup4 : 파이썬 웹 크롤링 라이브러리


from urllib.request import urlopen
from bs4 import BeautifulSoup
html = urlopen("http://www.naver.com")  
bsObject = BeautifulSoup(html, "html.parser") 
print(bsObject) # 웹 문서 전체가 출력

print(bsObject.head.title) # <title>NAVER</title> 출력

for meta in bsObject.head.find_all('meta'):
    print(meta.get('content')) # 모든 메타 데이터의 내용 출력

print (bsObject.head.find("meta", {"name":"description"})) # 원하는 태그의 내용 출력

for link in bsObject.find_all('a'):
    print(link.text.strip(), link.get('href')) #a 태그로 둘러싸인 텍스트와 a 태그의 href 속성을 출력

urlopen 함수를 사용하여 원하는 주소로부터 웹페이지를 가져온 후, BeautifulSoup 객체로 변환합니다.

BeautifulSoup 객체는 웹문서를 파싱한 상태입니다. 웹 문서가 태그 별로 분해되어 태그로 구성된 트리가 구성됩니다.
포함하는 태그가 부모가 되고 포함된 태그가 자식이 되어 트리를 구성하고 있습니다.

예제 2) 교보문고 베스트셀러 책이름 , 저자 , 가격 출력하기


from urllib.request import urlopen
from bs4 import BeautifulSoup as bs

# 교보문고의 베스트셀러 웹페이지를 가져옵니다.

html = urlopen('http://www.kyobobook.co.kr/bestSellerNew/bestseller.laf')
bsObject = bs(html, "html.parser")

# 책의 상세 웹페이지 주소를 추출하여 리스트에 저장합니다.
book_page_urls = []
for cover in bsObject.find_all('div', {'class':'detail'}):
    link = cover.select('a')[0].get('href')
    book_page_urls.append(link)

# 메타 정보로부터 필요한 정보를 추출합니다.메타 정보에 없는 저자 정보만 따로 가져왔습니다.   
for index, book_page_url in enumerate(book_page_urls):
    html = urlopen(book_page_url)
    bsObject = bs(html, "html.parser")
    title = bsObject.find('meta', {'property':'rb:itemName'}).get('content')
    author = bsObject.select('span.name a')[0].text
    image = bsObject.find('meta', {'property':'rb:itemImage'}).get('content')
    url = bsObject.find('meta', {'property':'rb:itemUrl'}).get('content')
    originalPrice = bsObject.find('meta', {'property': 'rb:originalPrice'}).get('content')
    salePrice = bsObject.find('meta', {'property':'rb:salePrice'}).get('content')

    print(index+1, title, author, image, url, originalPrice, salePrice)

2020년 02월 기준

1 흔한남매. 2 흔한남매 (원작), 백난도 http://image.kyobobook.co.kr/images/book/large/454/l9791164132454.jpg http://www.kyobobook.co.kr/product/detailViewKor.laf?mallGb=KOR&ejkGb=KOR&barcode=9791164132454 11000 9900
2 90년생이 온다 임홍택 http://image.kyobobook.co.kr/images/book/large/674/l9791188248674.jpg http://www.kyobobook.co.kr/product/detailViewKor.laf?mallGb=KOR&ejkGb=KOR&barcode=9791188248674 14000 12600
3 여행의 이유 김영하 http://image.kyobobook.co.kr/images/book/large/972/l9788954655972.jpg http://www.kyobobook.co.kr/product/detailViewKor.laf?mallGb=KOR&ejkGb=KOR&barcode=9788954655972 13500 12150
4 당신은 뇌를 고칠 수 있다 톰 오브라이언 http://image.kyobobook.co.kr/images/book/large/414/l9791135442414.jpg http://www.kyobobook.co.kr/product/detailViewKor.laf?mallGb=KOR&ejkGb=KOR&barcode=9791135442414 19800 17820
5 혼자가 혼자에게 이병률 http://image.kyobobook.co.kr/images/book/large/026/l9791158161026.jpg http://www.kyobobook.co.kr/product/detailViewKor.laf?mallGb=KOR&ejkGb=KOR&barcode=9791158161026 15500 13950
6 설민석의 삼국지. 1 설민석 http://image.kyobobook.co.kr/images/book/large/792/l9788933870792.jpg http://www.kyobobook.co.kr/product/detailViewKor.laf?mallGb=KOR&ejkGb=KOR&barcode=9788933870792 22000 19800
7 베스트 셀프 마이크 베이어 http://image.kyobobook.co.kr/images/book/large/968/l9791135444968.jpg http://www.kyobobook.co.kr/product/detailViewKor.laf?mallGb=KOR&ejkGb=KOR&barcode=9791135444968 18700 16830
8 추리 천재 엉덩이 탐정. 8: 괴도와 납치된 신부 사건 트롤 http://image.kyobobook.co.kr/images/book/large/914/l9791164131914.jpg http://www.kyobobook.co.kr/product/detailViewKor.laf?mallGb=KOR&ejkGb=KOR&barcode=9791164131914 12000 10800
9 Go Go 카카오프렌즈. 10: 이집트 김미영 http://image.kyobobook.co.kr/images/book/large/369/l9788950983369.jpg http://www.kyobobook.co.kr/product/detailViewKor.laf?mallGb=KOR&ejkGb=KOR&barcode=9788950983369 12000 10800
10 오늘은 이만 좀 쉴게요(한정판 스페셜 에디션) 손힘찬(오가타 마리토) http://image.kyobobook.co.kr/images/book/large/786/l9791162141786.jpg http://www.kyobobook.co.kr/product/detailViewKor.laf?mallGb=KOR&ejkGb=KOR&barcode=9791162141786 13000 11700
11 지쳤거나 좋아하는 게 없거나 글배우 http://image.kyobobook.co.kr/images/book/large/706/l9791196797706.jpg http://www.kyobobook.co.kr/product/detailViewKor.laf?mallGb=KOR&ejkGb=KOR&barcode=9791196797706 13500 12150
12 나는 나로 살기로 했다(200쇄 기념 스페셜 에디션) 김수현 http://image.kyobobook.co.kr/images/book/large/845/l9791187119845.jpg http://www.kyobobook.co.kr/product/detailViewKor.laf?mallGb=KOR&ejkGb=KOR&barcode=9791187119845 13800 12420
13 빨강 머리 앤 루시 모드 몽고메리 http://image.kyobobook.co.kr/images/book/large/084/l9791164450084.jpg http://www.kyobobook.co.kr/product/detailViewKor.laf?mallGb=KOR&ejkGb=KOR&barcode=9791164450084 16800 15120
14 직지. 1 김진명 http://image.kyobobook.co.kr/images/book/large/322/l9788965708322.jpg http://www.kyobobook.co.kr/product/detailViewKor.laf?mallGb=KOR&ejkGb=KOR&barcode=9788965708322 14000 12600
15 어떻게 살아야 할지 막막한 너에게 우쥔 http://image.kyobobook.co.kr/images/book/large/901/l9791196756901.jpg http://www.kyobobook.co.kr/product/detailViewKor.laf?mallGb=KOR&ejkGb=KOR&barcode=9791196756901 15500 13950
16 죽음의 에티켓 롤란트 슐츠 http://image.kyobobook.co.kr/images/book/large/741/l9791188331741.jpg http://www.kyobobook.co.kr/product/detailViewKor.laf?mallGb=KOR&ejkGb=KOR&barcode=9791188331741 15800 14220
17 룬의 아이들 블러디드. 2 전민희 http://image.kyobobook.co.kr/images/book/large/556/l9788954657556.jpg http://www.kyobobook.co.kr/product/detailViewKor.laf?mallGb=KOR&ejkGb=KOR&barcode=9788954657556 14500 13050
18 봉제인형 살인사건 다니엘 콜 http://image.kyobobook.co.kr/images/book/large/931/l9788998274931.jpg http://www.kyobobook.co.kr/product/detailViewKor.laf?mallGb=KOR&ejkGb=KOR&barcode=9788998274931 15000 13500
19 아주 작은 습관의 힘 제임스 클리어 http://image.kyobobook.co.kr/images/book/large/640/l9791162540640.jpg http://www.kyobobook.co.kr/product/detailViewKor.laf?mallGb=KOR&ejkGb=KOR&barcode=9791162540640 16000 14400
20 돈의 감각 이명로(상승미소) http://image.kyobobook.co.kr/images/book/large/985/l9791162540985.jpg http://www.kyobobook.co.kr/product/detailViewKor.laf?mallGb=KOR&ejkGb=KOR&barcode=9791162540985 16800 15120

 

예제 3) 네이버 베스트셀러 책이름, 저자, 가격 출력하기

from urllib.request import urlopen
from bs4 import BeautifulSoup


# 네이버의 베스트셀러 웹페이지를 가져옵니다.
html = urlopen('https://book.naver.com/bestsell/bestseller_list.nhn')
bsObject = BeautifulSoup(html, "html.parser")


# 책의 상세 웹페이지 주소를 추출하여 리스트에 저장합니다.
book_page_urls = []
for index in range(0, 25):
    dl_data = bsObject.find('dt', {'id':"book_title_"+str(index)})
    link = dl_data.select('a')[0].get('href')
    book_page_urls.append(link)



# 메타 정보와 본문에서 필요한 정보를 추출합니다.  
for index, book_page_url in enumerate(book_page_urls):
    html = urlopen(book_page_url)
    bsObject = BeautifulSoup(html, "html.parser")


    title = bsObject.find('meta', {'property':'og:title'}).get('content')
    author = bsObject.find('dt', text='저자').find_next_siblings('dd')[0].text.strip()
    image = bsObject.find('meta', {'property':'og:image'}).get('content')
    url = bsObject.find('meta', {'property':'og:url'}).get('content')

    dd = bsObject.find('dt', text='가격').find_next_siblings('dd')[0]
    salePrice = dd.select('div.lowest strong')[0].text
    originalPrice = dd.select('div.lowest span.price')[0].text

    print(index+1, title, author, image, url, originalPrice, salePrice)

예제 4) 네이버 블로그 검색결과 가져오기

from urllib.request import urlopen
from bs4 import BeautifulSoup as bs
import urllib.parse


# 네이버 검색 후 검색 결과
baseUrl = 'https://search.naver.com/search.naver?where=post&sm=tab_jum&query='
plusUrl = input('검색어를 입력하세요 : ')
# 한글 검색 자동 변환
url = baseUrl + urllib.parse.quote_plus(plusUrl)
html = urlopen(url)
bsObject = bs(html, "html.parser")

# 조건에 맞는 파일을 다 출력해라
title = bsObject.find_all(class_='sh_blog_title')


for i in title:
    print(i.attrs['title'])
    print(i.attrs['href'])
    print()

결과

검색어를 입력하세요 : 크롤링
웹크롤링 [금통위의사록 파이썬으로 다운받기]
https://blog.naver.com/jjys9047?Redirect=Log&logNo=221584977592

웹 구조를 이해한 자의 웹크롤링은 데이터를 다루는 디테일부터 다르다. By >파이썬을 활용한 실전 웹크롤링과 자동화 CAMP 박두진 강사님
http://blog.fastcampus.co.kr/221586197326

[Week 1] 데이터 사이언스 기초: 웹페이지에서 데이터 수집하기 (데이터 크롤링)
https://piry777.blog.me/221662360000

[파이썬 활용] 크롤링
https://blog.naver.com/mathesis_time?Redirect=Log&logNo=221525076829

▣ 웹크롤링 / 스크래핑 프로그램 OCTOPARSE 사용기
https://blog.naver.com/no1_devicemart?Redirect=Log&logNo=221539107537

발리 여행, 길리 트라왕안, 파티섬, 펍 크롤링, Pub Crawling 후기
https://blog.naver.com/grang353?Redirect=Log&logNo=221576202119

광고,홍보 위주로 활용이 가능한 웹크롤링 젠서버 컴퓨터 입니다.
https://blog.naver.com/kukuri0_0?Redirect=Log&logNo=221510474601

[Python] 파이썬 웹 크롤링 #1. 네이버 실시간 검색어 가져오기
https://dsz08082.blog.me/221587474567

10.1 R로 다음(Daum) 네티즌 리뷰 크롤링하기
https://blog.naver.com/pmw9440?Redirect=Log&logNo=221590746010

에브리타임 자동 크롤링 / 봇 시스템
https://blog.naver.com/kbs4674?Redirect=Log&logNo=221460241196

cf) 여러 페이지 블로그 게시물 가져오기

from urllib.request import urlopen
from bs4 import BeautifulSoup as bs
from urllib.parse import quote_plus

plusUrl = quote_plus(input('검색어를 입력하세요 : '))
pageNum = 1
count = 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={plusUrl}&sm=tab_pge&srchby=all&st=sim&where=post&start={pageNum}'

i = input('몇 페이지를 크롤링 할까요? : ')
lastPage = int(i) * 10 - 9
while pageNum < lastPage + 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={plusUrl}&sm=tab_pge&srchby=all&st=sim&where=post&start={pageNum}'
    html = urlopen(url)
    soup = bs(html, "html.parser")
    
    # 조건에 맞는 파일을 다 출력해라
    title = soup.find_all(class_='sh_blog_title')

    print(f'---{count}페이지 결과입니다 --------')
    for i in title:
        print(i.attrs['title'])
        print(i.attrs['href'])
        print()
    pageNum += 10
    count += 1

예제 5) 네이버 이미지 검색결과 저장하기

from urllib.request import urlopen
from bs4 import BeautifulSoup as bs
from urllib.parse import quote_plus

baseUrl = 'https://search.naver.com/search.naver?where=image&sm=tab_jum&query='
plusUrl = input('검색어를 입력하세요 : ')
# 한글 검색 자동 변환
url = baseUrl + quote_plus(plusUrl)
html = urlopen(url)
soup = bs(html, "html.parser")
img = soup.find_all(class_='_img')

n = 1
for i in img:
    imgUrl = i['data-source']
    with urlopen(imgUrl) as f:
        with open('./img/' + plusUrl + str(n)+'.jpg','wb') as h: # w - write b - binary
            img = f.read()
            h.write(img)
    n += 1
print('다운로드 완료')

예제 6) 인스타그램 해시태그 검색 시 이미지 다운로드하기

Crome Driver 설치 링크

cf) Chrome 버전과 맞는 Crome Driver 설치를 해야합니다. (맞지 않으면 오류))

instagram은 javascript 기반의 환경이므로 BeautifulSoup으로 크롤링이 불가합니다.

-> selenium 사용

pip install selenium
from urllib.request import urlopen
from bs4 import BeautifulSoup as bs
from selenium import webdriver
from urllib.parse import quote_plus
import time


baseUrl = 'https://www.instagram.com/explore/tags/'
plusUrl = input('검색할 태그를 입력하세요 : ')
# 한글 검색 자동 변환
url = baseUrl + quote_plus(plusUrl)

# Crome 드라이버 지정
driver = webdriver.Chrome()
driver.get(url)

# 
time.sleep(3)

html = driver.page_source
soup = bs(html, "html.parser")

insta = soup.select('.v1Nh3.kIKUG._bz0w') # 태그
# print(insta[0]) # 한개 데이터만 가지고와라 
n = 1
for i in insta:
    print('https://www.instagram.com' + i.a['href'])
    imgUrl = i.select_one('.KL4Bh').img['src']
    with urlopen(imgUrl) as f:
        with open('./img/' + plusUrl + str(n)+'.jpg','wb') as h:
            img = f.read()
            h.write(img)
    n += 1
    print(imgUrl)
    print()
driver.close()

예제 7) 네이버 블로그 검색결과 CSV(엑셀) 파일로 저장하기

import csv
from urllib.request import urlopen
from bs4 import BeautifulSoup as bs
from urllib.parse import quote_plus

# class="api_txt_lines total_tit" 
# - 네이버 모바일 VIEW탭에 제목 class

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

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

html = urlopen(url).read()
soup = bs(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']) # 링크
    searchList.append(temp)
# 엑셀에서 열때 utf-8 표준이면 깨짐현상이 일어남
f = open(f'{search}.csv', 'w', encoding = 'cp949', newline='')
csvWriter = csv.writer(f)
for i in searchList:
    # 한줄씩 써 내려감
    csvWriter.writerow(i)
f.close()

print('완료 되었습니다.')

예제 8) 구글 검색결과 CSV(엑셀) 파일로 저장하기

import csv
from bs4 import BeautifulSoup as bs
from selenium import webdriver
from urllib.parse import quote_plus


baseUrl = 'https://www.google.co.kr/search?q='
plusUrl = input('검색어를 입력하세요 : ')
# 한글 검색 자동 변환
url = baseUrl + quote_plus(plusUrl)

driver = webdriver.Chrome()
driver.get(url)


html = driver.page_source
soup = bs(html, "html.parser")

r = soup.select('.r')
searchList = []

for i in r:
    temp = []
    temp.append(i.select_one('.LC20lb').text) # 제목
    temp.append(i.a.attrs['href']) # 링크
    print()
    searchList.append(temp)

driver.close()

f = open(f'{plusUrl}.csv', 'w', encoding = 'cp949', newline='')
csvWriter = csv.writer(f)
for i in searchList:
    # 한줄씩 써 내려감
    csvWriter.writerow(i)
f.close()

print('완료 되었습니다.')

크롤링을 검색해서 나온 10개의 결과 값을 저장했습니다.(구글)