바른 생각 바른 글

블로그 글목록 가져오기 python 블로그 스크래퍼

지구빵집 2022. 11. 30. 11:32
반응형

 

 

 

신변잡기 블로그 글을 올리다 가끔은 어떤 글을 썼는지 목록을 가져오고 싶을 때가 있다. 물론 수정할 필요도 있고, 과감히 삭제할 글도 있으니 상황에 맞게 구성할 필요도 있다. 세상이 점점 사람이 하는 일을 스마트, 자동화, 로봇으로 대체하는 분위기가 늘어나니 자연스럽게 적응하기 마련이다. 

 

전체 코드를 맨 밑바닥에 올리고 전체적인 코드를 나누어 설명한다. 강의를 듣고 따라 하고 몸에 익히고, 나중에는 눈감고도 할 수 있는 배움의 과정을 모두 합쳐 '학습 관행' (學習慣行, 배우고 익히고 젖어들어 행함)이라고 한다. 제대로 배운다는 것은 바로 몸으로 행하는 것을 말한다. 알고 보니 죄다 헛 것만 배웠고, 눈으로 배우고, 글로 배우고, 입으로 배운 것뿐이다. 몸으로 행동하는 것이 적으니 얻는 것도 없다. 태도는 사람을 상대하고 처신하는 것만이 아니라 모든 것에서 배어 나온다. 배우는 데 얼마나 태도가 좋지 않았는지 새삼 깨달았다. 

 

모든 것을  구현한 소스 코드는 아래와 같다. 출력 파일을 보면 아래와 같이 아름답게 나오는데 인코딩을 UTF-8로 설정했는데도 엑셀에서 직접 열면 한글이 깨진다. 만약 엑셀에서 CSV 파일을 열 경우 새로운 탭을 만들어 메뉴에서 데이터 > 텍스트 선택하고 쉼표 분리, 시작할 줄은 3열로 하고 불러오면 제대로 나온다. 

 

Number	 Date	 Category	 Title	 URL
1	   2010. 2. 16. 15:13	   무한정보제공	   외국 많이 나오는 여자이름	    https://com/1
2	   2010. 2. 16. 15:22	   무한정보제공	   외국 많이 나오는 남자이름	    https://com/2
3	   2010. 2. 17. 11:04	   사진 갤러리	   한밤중에 현대 미술관 배회	    https://com/3

 

어떤 블로그라도 상관없지만 서버에 부하가 가면 탄소 발생 문제도 있고 하니 적당히 사용해야 한다.

 

from requests import get
from bs4 import BeautifulSoup

from datetime import datetime
now = datetime.now()

 

파이선에서 서버에 HTTP 연결을 요청하는 패키지인 requests 모듈과 웹 페이지에서 태그로 둘러싸인 데이터를 쉽게 추출할 수 있는 beautifulsoup 모듈을 설치해 import 한다. 아래의 날짜 데이터 연산을 도와주는 datetime 모듈은 파일 이름을 붙여주기 위해 임포트 한다. 파일 이름을 시간 기반으로 만들면 알아보기 쉽고 테스트할 때도 자동으로 구분이 되어 편하다.

 

def extract_fishpoint(startblognum, lastblognum):  
  base_url = "https://blog address/"
  #base_url = "https://blog address/"
  results = []
  lastblognum = lastblognum + 1
  for textnum in range (startblognum, lastblognum):
    response = get(f"{base_url}{textnum}")
    if response.status_code != 200:
      print(f"Can't request website {base_url}{textnum}")
    else:
      #print(response.status_code)
      soup = BeautifulSoup(response.text, "html.parser")
      #list = soup.select_one('div.article_content') # https://xxxxxx.xxxxx.com/
      list = soup.select_one('div.post-meta')
      category = soup.select_one('div.category').get_text()
      date = list.select_one('span.date').get_text()
      #list = soup.find('div', class_ = "date")
      print(date)
      
      #print(f"{soup.title.string} {base_url}{textnum+1}")

      title_data = {
          'number': textnum,
          'date': date,
          'category': category,
          'title': soup.title.string.replace(","," "),
          'link': f"{base_url}{textnum}"  #글 목록 출력
          #'link': f"<a href=\"{base_url}{textnum}\" target=\"_blank\" rel=\"noopener\"" #링크 출력포맷
        }
      print(textnum)
      results.append(title_data)
      
  return results

 

블로그에 접속해 목록 데이터를 가져다가 리스트에 저장하는 코드다. 블로그 주소를 넣고 html 코드를 가져와 추출할 데이터를 넘버, 카테고리, 글 제목, 링크 순으로 저장한다. 블로그 주소가 두 개인 것과 태그를 뽑아 오는 것이 두 개인 것은 저장된 글 형태에 따라 다르게 뽑아오기 위해 하나는 주석으로 남겨두었다. 마지막엔 포맷에 맞게 리스트를 만들어 반환한다.

 

startblognum = int(input("Input start Blog Number?"))
lastblognum = int(input("Input last Blog Number?"))
title_lists = extract_fishpoint(startblognum, lastblognum)
#print(title_lists)

savedtime = now.strftime('%Y%m%d%H%M%S%Z')
print(savedtime)

file = open(f"{savedtime}.csv", "w", encoding="utf-8")
file.write(f"Start Num: {startblognum}\n")
file.write(f"Last Num: {lastblognum}\n")
file.write("Number, Date, Category, Title, URL\n")

for title_list in title_lists:
  file.write(f"{title_list['number']}, \
  {title_list['date']}, \
  {title_list['category']}, \
  {title_list['title']},  \
  {title_list['link']}\n")

file.close()

 

이제 데이터를 뽑아왔으니 파일로 만든다. 블로그 글의 시작 넘버와 마지막 넘버를 받아와서 0번부터 시작하는 데이터를 +1 해서 리스트를 반환하는 위 함수를 호출한다. 받아온 리스트를 CSV 파일로 저장하면 끝난다.

 

from requests import get
from bs4 import BeautifulSoup

from datetime import datetime
now = datetime.now()

def extract_fishpoint(startblognum, lastblognum):  
  base_url = "https://blog address/"
  #base_url = "https://blog address/"
  results = []
  lastblognum = lastblognum + 1
  for textnum in range (startblognum, lastblognum):
    response = get(f"{base_url}{textnum}")
    if response.status_code != 200:
      print(f"Can't request website {base_url}{textnum}")
    else:
      #print(response.status_code)
      soup = BeautifulSoup(response.text, "html.parser")
      #list = soup.select_one('div.article_content') # https://xxxxxx.xxxx.com/
      list = soup.select_one('div.post-meta')
      category = soup.select_one('div.category').get_text()
      date = list.select_one('span.date').get_text()
      #list = soup.find('div', class_ = "date")
      print(date)
      
      
      #pubdate = find("div", class_="mosaic-zone")
      
      #print(f"{soup.title.string} {base_url}{textnum+1}")

      title_data = {
          'number': textnum,
          'date': date,
          'category': category,
          'title': soup.title.string.replace(","," "),
          'link': f"{base_url}{textnum}"  #글 목록 출력
          #'link': f"<a href=\"{base_url}{textnum}\" target=\"_blank\" rel=\"noopener\"" #링크 출력포맷
        }
      print(textnum)
      results.append(title_data)
      
  return results


startblognum = int(input("Input start Blog Number?"))
lastblognum = int(input("Input last Blog Number?"))
title_lists = extract_fishpoint(startblognum, lastblognum)
#print(title_lists)

savedtime = now.strftime('%Y%m%d%H%M%S%Z')
print(savedtime)

file = open(f"{savedtime}.csv", "w", encoding="utf-8")
file.write(f"Start Num: {startblognum}\n")
file.write(f"Last Num: {lastblognum}\n")
file.write("Number, Date, Category, Title, URL\n")

for title_list in title_lists:
  file.write(f"{title_list['number']}, \
  {title_list['date']}, \
  {title_list['category']}, \
  {title_list['title']},  \
  {title_list['link']}\n")

file.close()

 

 

아름다운 블로그

 

 

 

 

반응형