인프런 커뮤니티 질문&답변

sek95041143님의 프로필 이미지
sek95041143

작성한 질문수

[2024 개정판] 이것이 진짜 크롤링이다 - 실전편 (인공지능 수익화)

뉴스기사크롤링중 이런 오류가 나올 경우엔 어떻게 해야 하나요?

작성

·

556

0

잘 따오다가 갑자기 오류가 나더니 그 뒤로 계속 이 오류창이 뜹니다ㅠㅠ

isLastPage = soup.select_one("a.btn_next").attrs['aria-disabled']

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

AttributeError: 'NoneType' object has no attribute 'attrs'

 

코드는 이렇게 작성했어요

9월뉴스 결과가 필요한데

400페이지까지 밖에 못 긁어온다고 그래서 대충 여러번에 나눠서 작업중입니다

ㅠㅠ

#네이버기사 크롤링 엑셀저장
import requests
from bs4 import BeautifulSoup
import time
import pyautogui
from openpyxl import Workbook


#사용자입력
keyword = pyautogui.prompt("검색어를 입력하세요")
lastpage = int(pyautogui.prompt("몇 페이지까지 크롤링 할까요?"))

#엑셀생성하기
wb = Workbook()

#엑셀 시트 생성하기
ws = wb.create_sheet(keyword)

#열 너비 조절
ws.column_dimensions['A'].width = 60
ws.column_dimensions['B'].width = 60
ws.column_dimensions['C'].width = 30


#행 번호
row = 1

#페이지 번호
pageNum = 1
for i in range(1, lastpage*10, 10) :
    print(f"{pageNum}페이지 크롤링중입니다 =================")
    response = requests.get(f"https://search.naver.com/search.naver?where=news&query=%EC%95%94&sm=tab_opt&sort=1&photo=0&field=0&pd=3&ds=2023.09.01&de=2023.09.07&news&query={keyword}&start={i}")
    html = response.text
    soup = BeautifulSoup(html, 'html.parser')
    articles = soup.select("div.info_group") #뉴스기사 div 10개 추출

    for article in articles:
        links = article.select("a.info") #리스트
        if len(links) >= 2: #링크가 2개 이상이면
            url = links[1].attrs['href'] #두번째 링크의 href를 추출
            response = requests.get(url, headers={'User-agent': 'Mozilla/5.0'})
            html = response.text
            soup_sub = BeautifulSoup(html, 'html.parser')

            title = None
            date = None

            #만약 연예 뉴스라면
            if "entertain" in response.url: 
                title = soup_sub.select_one(".end_tit")
                date = soup_sub.select_one("div.article_info > span > em")
                

            #만약 스포츠 뉴스라면
            elif "sports" in response.url:
                title = soup_sub.select_one("h4.title")
               
            else: 
                title = soup_sub.select_one(".media_end_head_headline")
                date = soup_sub.select_one("span.media_end_head_info_datestamp_time._ARTICLE_DATE_TIME")
                

            print("=======링크======= \n", url)
            print("=======제목======= \n", title.text.strip() if title else "제목을 찾을 수 없습니다.")
            print("=======날짜======= \n", date.text if date else "날짜를 찾을 수 없습니다.")

            # 'else' 블록에서 'date' 변수 정의는 여기서 끝나도록 수정

            ws['A1'] = 'URL'
            ws['B1'] = '기사제목'
            ws['C1'] = '업로드날짜'

            ws[f'A{row}'] = url
            ws[f'B{row}'] = title.text.strip() if title else "제목을 찾을 수 없습니다."

            if date:
             ws[f'C{row}'] = date.text.strip()
            else:
                ws[f'C{row}'] = "날짜를 찾을 수 없습니다."
            
            row=row+1
    #마지막 페이지 여부 확인하기
    isLastPage = soup.select_one("a.btn_next").attrs['aria-disabled']
    if isLastPage == 'true':
        print("마지막 페이지 입니다.")
        break

    pageNum = pageNum+1
wb.save(r'/Users/eunkyungsong/Desktop/코딩/10월 셀레니움 크롤링/실전/9월뉴스기사크롤링/' + f'{keyword}_result.9월.본문x.9.07.xlsx')

답변 2

0

스타트코딩님의 프로필 이미지
스타트코딩
지식공유자

https://projectlog-eraser.tistory.com/9

네이버 검색결과는 400페이지가 최대네요

 

끝까지 크롤링했으니 마지막 페이지 버튼이 없어서

계속 오류 나는 상황인 것 같습니다.

 

더 많은 정보가 필요하다면 이전 질문에서 대답 드렸듯이

네이버 뉴스 API 를 활용해 보시기 바랍니다. ㅎㅎ

 

그럼 즐거운 크롤링 되세요 :)

0

안녕하세요, 인프런 AI 인턴이에요.

오류 메시지를 살펴보면 ‘NoneType’ 객체는 ‘attrs’ 속성을 가지고 있지 않다는 내용입니다. 즉, soup.select_one(“a.btn_next”)의 결과가 None인 케이스가 있다는 뜻입니다. 이런 경우에는 ‘a.btn_next’ 요소가 페이지에 없는 것일 수 있습니다.

해결 방법으로는 “a.btn_next” 요소가 있는지 확인한 후에 속성을 가져오도록 조건문을 추가해 주세요. 예를 들면 다음과 같은 코드로 수정할 수 있을 것입니다.

next_button = soup.select_one("a.btn_next")
if next_button is not None:
    isLastPage = next_button.attrs['aria-disabled']
else:
    isLastPage = True

이렇게 수정하면 “a.btn_next”가 존재하지 않을 경우에는 isLastPage 변수에 True를 할당하게 됩니다.

이렇게 수정한 코드를 적용하면 오류가 발생하지 않고 실행이 가능할 것입니다. 어떤 페이지에서는 “a.btn_next” 요소가 없을 수도 있으므로, 추가적으로 예외처리를 넣어준다면 더욱 안전한 코드가 될 것입니다. 예를 들면 다음과 같습니다.

try:
    next_button = soup.select_one("a.btn_next")
    if next_button is not None:
        isLastPage = next_button.attrs['aria-disabled']
    else:
        isLastPage = True
except Exception:
    isLastPage = True

다시 한번, 코드 수정 후에 오류가 발생하지 않는지 테스트해보세요. 만약 이외에도 다른 오류가 발생한다면, 오류 메시지와 함께 질문을 다시 올려주시면 도움을 드리겠습니다. 감사합니다.

sek95041143님의 프로필 이미지
sek95041143

작성한 질문수

질문하기