듀랑이 공부 블로그

[데린이의 TIL] 파이썬 for 문을 활용해 URL 여러개 크롤링 (기사제목 & 언론사 가져오기 실습) 본문

Today I Learned/Python

[데린이의 TIL] 파이썬 for 문을 활용해 URL 여러개 크롤링 (기사제목 & 언론사 가져오기 실습)

듀랑이 2020. 10. 24. 23:27

FOR문으로 URL 여러개 크롤링하기

💡 데린이의 파이썬 여정은 멀고도 험난하다... 이번 포스트는 복수의 URL에서 데이터를 가지고 오고 싶을 때, for 문을 사용해서 한 번에 해결하는 숙제를 하며 복습 + 새롭게 알게 된 내용이다. 이번 수업 숙제였는데, 내가 처음에 짠 코드와 숙제 리뷰를 통해 얻은 내용을 비교해보면서 정리할 예정이다.

 

목표 : 아래 URL 세 개에서 기사 제목과 언론사를 추출해 데이터프레임 만들기

크롤링에 필수인 라이브러리 BeautifulSoup을 불러온다. 마지막에 데이터프레임으로 담아줄거라서 pandas도 불러왔다.

from bs4 import BeautifulSoup
import requests
import pandas as pd

 

첫 번째 코드 : 목으로 나는 비둘기

딱 봐도 엄청 길고 복잡하게 짠 코드... 하지만 어쨌든 돌아는 간다 ㅋㅋㅋ 유명한 meme인 비둘기가 목으로 날아가는 짤이 자동으로 떠오른다 ㅋㅋㅋ 하지만 나름 뿌듯했던 게, 이 코드를 짤 당시는 반복문, 리스트 등 기본적인 개념에 대해 지식이 거의 없는 상태였어서, 스스로 작성해보았다는 데에 의미를 두었다.

 

우선 처음에는 URL 세 개를 동시에 어떻게 불러와야하나, 고민이 되어서 URL이 앞 부분은 다 동일하고 끝 부분이 날짜 + 기사 고유번호로 다르다는 것을 파악, 끝 부분을 리스트로 담아주고 문자열 포맷팅으로 하나씩 불러오고자 했다.

crawl_url = ["https://news.v.daum.net/v/20201004215700006", "https://news.v.daum.net/v/20201020153505519", "https://news.v.daum.net/v/20201020153609574"]
number = ['04215700006','20153505519','20153609574']
base_url = 'https://news.v.daum.net/v/202010{}'

for 문에서 URL의 끝 부분을 하나하나씩 불러와서 기사 제목과 언론사를 추출해주었다. 여기서 조금 잘 한 점이라면, 언론사의 경우 페이지 상단의 언론사 로고 안에 들어있는 텍스트를 추출해 온 것인데, 맨 아래 'get('alt')'를 활용해서 alt에 쌓여진 언론사 텍스트를 가져왔다.

titles = []
companys = []

for n in number:
    url = base_url.format(n)
    res = requests.get(url)
    soup = bs(res.content, 'html.parser')
    h3s = soup.select('#cSub > div > h3')
    company = soup.select('#cSub > div > em > a > img')
    for i in range(0,1):
        titles.append(h3s[i].text)
    for c in company:
        companys.append(c.get('alt'))

기사제목과 언론사 이름을 append 함수를 통해서 리스트를 만들어줬으니 이를 데이터 프레임에 담아 완성했다. 제대로 나오긴 했지만, 비효율적인데, 아래 좀 더 나은 코드로 리뷰해보았다.

df = pd.DataFrame(
    {'title': titles,
    'company': companys,
    'url': crawl_url})
df

 

두 번째 코드 : 그래도 좀 나는 닭둘기

이번에는 좀 다르게... 좀 더 낫게.... 수업과 셀프 리뷰를 통해서 코드를 좀 더 간결하게 고쳐보았다. 메서드 체이닝을 통해서 불필요한 중첩 for 문을 없앴다. 또 첫 번째 코드에서는 for 문을 여러개 쓰다보니 변수 (i, c, n...)가 많았는데, for 문이 어떻게 작동하는지 알게 되어서 이것 또한 개선할 수 있었다. range (0,3)에서 url 리스트에 들어가있는 url이 하나씩 불러와지고 코드가 끝까지 작동한 후, 두번째로 넘어가고, 또 다시 세번째로 넘어가는 등 순서대로 반환되므로 뒤의 title과 comapny의 경우 인덱스를 [0]으로 지정해도 무방한 것!

url = ['https://news.v.daum.net/v/20201004215700006', 'https://news.v.daum.net/v/20201020153505519', 'https://news.v.daum.net/v/20201020153609574']
titles = []
companys = []

for i in range (0,3):
	res = requests.get(url[i])
    soup = BeautifulSoup(res.content, 'html.parser')
    title = soup.select('#cSub > div > h3')[0].text
    company = soup.select('#cSub > div > em > a > img')[0].get('alt')
    titles.append(title)
    companys.append(company)

마지막엔 이렇게 데이터프레임을 생성해주었음! 아직은 파이썬 많이 어렵지만 차근차근 따라가봐야겠다.

df = pd.DataFrame({
    'title': titles,
    'company': companys,
    'url': url
})
df

 

이번 학습을 통해 배운 점:

  • .text, .get처럼 크롤링할 때도 메서드 체이닝을 통해서 코드를 간결하게 줄일 수 있다
  • 코드는 한 줄 한 줄씩 실행되기 때문에 i와 같은 변수가 for 문의 모든 곳에 들어갈 필요는 없다
  • for 문을 통해 반환되는 값을 list에 넣는 형식이 많이 사용된다
Comments