1. '더 나은미래 신문사'에 들어간 뒤 '봉사' 검색
https://futurechosun.com/page/1?s=%EB%B4%89%EC%82%AC 로 이동
1, 2, 3, 페이지를 넘겨보면,
https://futurechosun.com/page/1?s=%EB%B4%89%EC%82%AC
https://futurechosun.com/page/2?s=%EB%B4%89%EC%82%AC
https://futurechosun.com/page/3?s=%EB%B4%89%EC%82%AC
패턴인 것을 확인
2. 첫 페이지의 html코드를 파이썬으로 불러오기
#1 웹 스크롤링에 필요한 모듈 import
1 2 | from bs4 import BeautifulSoup import urllib.request |
#2 첫 페이지의 url을 파싱하기
1 2 3 4 | list_url = 'https://futurechosun.com/page/1?s=%EB%B4%89%EC%82%AC' url = urllib.request.Request(list_url) result = urllib.request.urlopen(url).read().decode("utf-8") print(result) | cs |
#3 웹 스크롤링 전문 모듈인 beautiful soup (find_all 사용) 을 이용할 수 있게끔
내려받은 html 코드를 파싱하기
1 2 3 4 5 6 7 | from bs4 import BeautifulSoup import urllib.request list_url = 'https://futurechosun.com/page/1?s=%EB%B4%89%EC%82%AC' url = urllib.request.Request(list_url) result = urllib.request.urlopen(url).read().decode("utf-8") soup = BeautifulSoup( result, "html.parser") print(soup) | cs |
3. 더 나은 미래 첫 페이지에 보이는 기사들로 이어지는 url을 찾기 위해
크롬 관리자 모드로 태그 이름과 클래스 이름 알아내기
태그 이름 : div
클래스 이름 : elementor_post-title
4. 태그 div, 클래스 이름 elementor-post_title에 해당되는 곳을 beautiful soup으로 파싱된 html 긁어오기
1 2 3 4 5 6 7 8 | from bs4 import BeautifulSoup import urllib.request list_url = 'https://futurechosun.com/page/1?s=%EB%B4%89%EC%82%AC' url = urllib.request.Request(list_url) result = urllib.request.urlopen(url).read().decode("utf-8") soup = BeautifulSoup( result, "html.parser") result1=soup.find_all('div',class_ ='elementor-post__title') print(result1) | cs |
이 때 코드를 하나씩 보면,
가장 먼저 리스트가 모두를 감싸고 있고, 안의 요소를 보면
<div class="elementor-post__title"> <a href="https://futurechosun.com/archives/52491"> “편견에 주눅 들었던 결혼 이주 여성들… ‘봉사’로 자존감 되찾았다죠” </a></div>
이렇게 나오는데, 우리는 리스트 안의 href를 가져와야 한다.
[ [1] ]에서 for문으로 1을 바로 찾으려고 하면 안되는 것과 같다.
즉 for문으로 1이라는 요소에 접근하려면 리스트를 한 번 벗긴 뒤 접근해야 한다.
그래서 for문을 사용해야 한다.
1 2 3 4 5 6 7 8 9 | from bs4 import BeautifulSoup import urllib.request list_url = 'https://futurechosun.com/page/1?s=%EB%B4%89%EC%82%AC' url = urllib.request.Request(list_url) result = urllib.request.urlopen(url).read().decode("utf-8") soup = BeautifulSoup( result, "html.parser") result1=soup.find_all('div',class_ ='elementor-post__title') for i in result1: print(i) | cs |
<div class="elementor-post__title"> <a href="https://futurechosun.com/archives/52491"> “편견에 주눅 들었던 결혼 이주 여성들… ‘봉사’로 자존감 되찾았다죠” </a></div>
그러면 이제, 리스트를 벗겼고, 이제는 href에 접근하기 위해서 <div> 태그를 벗겨야한다.
하지만 아직 파싱된 html 코드이기 때문에 아직 find_all을 사용할 수 있다.
이번에는 href를 담고 있는 <a>에 접근하기 위해서
find_all('a')를 해주자
1 2 3 4 5 6 7 8 9 | from bs4 import BeautifulSoup import urllib.request list_url = 'https://futurechosun.com/page/1?s=%EB%B4%89%EC%82%AC' url = urllib.request.Request(list_url) result = urllib.request.urlopen(url).read().decode("utf-8") soup = BeautifulSoup( result, "html.parser") result1=soup.find_all('div',class_ ='elementor-post__title') for i in result1: print(i.find_all('a')) |
[<a href="https://futurechosun.com/archives/52491"> “편견에 주눅 들었던 결혼 이주 여성들… ‘봉사’로 자존감 되찾았다죠” </a>]
div는 벗겨졌으나, 이번에도 리스트 형태로 다시 생겼기 때문에
다시 벗겨줘야 하는데 이번에는 리스트만 벗기면 되니
리스트[0]으로 리스트 안의 요소만 출력 해주면 된다.
1 2 3 4 5 6 7 8 9 | from bs4 import BeautifulSoup import urllib.request list_url = 'https://futurechosun.com/page/1?s=%EB%B4%89%EC%82%AC' url = urllib.request.Request(list_url) result = urllib.request.urlopen(url).read().decode("utf-8") soup = BeautifulSoup( result, "html.parser") result1=soup.find_all('div',class_ ='elementor-post__title') for i in result1: print(i.find_all('a')[0]) |
# 뽑아낸 a 태그의 html 문서에서 href의 값만 얻어내기
1 2 3 4 5 6 7 8 9 | from bs4 import BeautifulSoup import urllib.request list_url = 'https://futurechosun.com/page/1?s=%EB%B4%89%EC%82%AC' url = urllib.request.Request(list_url) result = urllib.request.urlopen(url).read().decode("utf-8") soup = BeautifulSoup( result, "html.parser") result1=soup.find_all('div',class_ ='elementor-post__title') for i in result1: print(i.find_all('a')[0].get("href")) |
# 위의 상세 기사 url을 params 라는 리스트에 담아 저장하기
1 2 3 4 5 6 7 8 9 10 11 | from bs4 import BeautifulSoup import urllib.request list_url = 'https://futurechosun.com/page/1?s=%EB%B4%89%EC%82%AC' url = urllib.request.Request(list_url) result = urllib.request.urlopen(url).read().decode("utf-8") soup = BeautifulSoup( result, "html.parser") result1=soup.find_all('div',class_ ='elementor-post__title') params=[] for i in result1: params.append(i.find_all('a')[0].get("href")) print(params) |
set 함수를 이용해서 혹시 모를 중복을 제거하고,
(이미지에도 해당 url이 있고, 클래스와 태그명이 같을 경우 중복될 수 있다)
for 문을 이용해서 1페이지뿐만 아니라 3페이지까지 긁어 저장하자.
https://futurechosun.com/page/1?s=%EB%B4%89%EC%82%AC -> 1페
https://futurechosun.com/page/2?s=%EB%B4%89%EC%82%AC -> 2페
https://futurechosun.com/page/3?s=%EB%B4%89%EC%82%AC -> 3페
였던 것을 활용하면 된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | from bs4 import BeautifulSoup import urllib.request params=[] for i in range(1,4): list_url = 'https://futurechosun.com/page/'+str(i)+'?s=%EB%B4%89%EC%82%AC' url = urllib.request.Request(list_url) result = urllib.request.urlopen(url).read().decode("utf-8") soup = BeautifulSoup( result, "html.parser") result1=soup.find_all('div',class_ ='elementor-post__title') for i in result1: params.append(i.find_all('a')[0].get("href")) my_result=set(params) # set 함수를 이용하면 중복이 제거된 요소만 남는다 my_result2=list(my_result) # 다시 리스트로 감싸기 print(params) |
# time.sleep() 활용해서 서버에 부하가 가지 않게끔 하기
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | from bs4 import BeautifulSoup import urllib.request import time # time이 들어있는 모듈 params=[] for i in range(1,4): time.sleep(5) # 5초간 휴식 list_url = 'https://futurechosun.com/page/'+str(i)+'?s=%EB%B4%89%EC%82%AC' url = urllib.request.Request(list_url) result = urllib.request.urlopen(url).read().decode("utf-8") soup = BeautifulSoup( result, "html.parser") result1=soup.find_all('div',class_ ='elementor-post__title') for i in result1: params.append(i.find_all('a')[0].get("href")) print(params) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | from bs4 import BeautifulSoup import urllib.request import time def bs_scroll(): params=[] for i in range(1,4): time.sleep(5) list_url = 'https://futurechosun.com/page/'+str(i)+'?s=%EB%B4%89%EC%82%AC' url = urllib.request.Request(list_url) result = urllib.request.urlopen(url).read().decode("utf-8") soup = BeautifulSoup( result, "html.parser") result1=soup.find_all('div',class_ ='elementor-post__title') for i in result1: params.append(i.find_all('a')[0].get("href")) my_result=set(params) my_result2=list(my_result) return my_result2 print(bs_scroll()) |
# 1페이지에 있던 상세 기사 하나를 골라 들어가서, 기사 내용의 태그와 클래스 확인하기
주소 : https://futurechosun.com/archives/52491
태그 : div
클래스 : elementor-element elementor-element-24e82692 elementor-widget__width-initial elementor-widget elementor-widget-theme-post-content
# 기사 내용 크롤링하기
1 2 3 4 5 6 7 8 | from bs4 import BeautifulSoup import urllib.request list_url = 'https://futurechosun.com/archives/52491' url = urllib.request.Request(list_url) result = urllib.request.urlopen(url).read().decode("utf-8") soup = BeautifulSoup( result, "html.parser") result1=soup.find_all('div',class_ ='elementor-element elementor-element-24e82692 elementor-widget__width-initial elementor-widget elementor-widget-theme-post-content') print(result1) |
# result1을 보면 이렇게 리스트로 둘러싸여 있고, 요소값은 한개이다.
# 여기서 result[0]으로 리스트를 벗긴 뒤, 텍스트만 쫙 긁어오면 그게 기사 내용이 된다.
1 2 3 4 5 6 7 8 | from bs4 import BeautifulSoup import urllib.request list_url = 'https://futurechosun.com/archives/52491' url = urllib.request.Request(list_url) result = urllib.request.urlopen(url).read().decode("utf-8") soup = BeautifulSoup( result, "html.parser") result1=soup.find_all('div',class_ ='elementor-element elementor-element-24e82692 elementor-widget__width-initial elementor-widget elementor-widget-theme-post-content') print(result1[0].get_text()) |
# 그럼 위 과정을 함수로 만들자
1 2 3 4 5 6 7 8 9 10 | from bs4 import BeautifulSoup import urllib.request def bs_detail_scroll(): list_url = 'https://futurechosun.com/archives/52491' url = urllib.request.Request(list_url) result = urllib.request.urlopen(url).read().decode("utf-8") soup = BeautifulSoup( result, "html.parser") result1=soup.find_all('div',class_ ='elementor-element elementor-element-24e82692 elementor-widget__width-initial elementor-widget elementor-widget-theme-post-content') return result1[0].get_text() print(bs_detail_scroll()) |
# 이제 위 함수의 url을 직접 받는게 아니라, 유동적으로 변하도록 아까 만들었던 다른 함수와 연동시키자
# 아까 만들었던 함수는 페이지에 있는 기사의 url을 리스트로 여러 개로 한 번에 주기 때문에 둘을 연동하면 페이지 별로 한꺼번에 할 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | from bs4 import BeautifulSoup import urllib.request def bs_scroll(): params=[] for i in range(1,3): list_url = 'https://futurechosun.com/page/'+str(i)+'?s=%EB%B4%89%EC%82%AC' url = urllib.request.Request(list_url) result = urllib.request.urlopen(url).read().decode("utf-8") soup = BeautifulSoup( result, "html.parser") result1=soup.find_all('div',class_ ='elementor-post__title') for i in result1: params.append(i.find_all('a')[0].get("href")) my_result=set(params) my_result2=list(my_result) return my_result2 def bs_detail_scroll(): list_url = bs_scroll() final=[] for i in list_url: url = urllib.request.Request(i) result = urllib.request.urlopen(url).read().decode("utf-8") soup = BeautifulSoup( result, "html.parser") result1=soup.find_all('div',class_ ='elementor-element elementor-element-24e82692 elementor-widget__width-initial elementor-widget elementor-widget-theme-post-content') final.append(result1[0].get_text()) return final print(bs_detail_scroll()) |
근데 중간에 기사 내용이 아닌 광고? 같은 것도 껴있는 것 같다...
뭔가 부족한 부분이 있는 것 같은데..
계속 연습해봐야겠다
'나 취준생 > 파이썬' 카테고리의 다른 글
감정 분석 + 워드 클라우드 (0) | 2020.12.18 |
---|---|
워드 클라우드 그리기 (0) | 2020.12.18 |
웹 스크롤링 연습 ( 중앙 일보 기사 ) (0) | 2020.12.16 |
실전 웹 스크롤링 해보기 1 ( 시청자 게시판 반응 ) (0) | 2020.12.16 |
크롤링 입문 - beautiful soup 모듈 (0) | 2020.12.15 |