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

황성현님의 프로필 이미지
황성현

작성한 질문수

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

1단계 - class 선택자 고급 테크닉, 특수문자 처리 방법

주소창에 sports가 들어가 있어도 읽어서 출력해요ㅠㅠ

작성

·

170

·

수정됨

0

import requests
from bs4 import BeautifulSoup
import time

response = requests.get('https://search.naver.com/search.naver?ssc=tab.news.all&where=news&sm=tab_jum&query=%EC%86%90%ED%9D%A5%EB%AF%BC')
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를 추출
        
        # 다시 request 날려 준다
        response = requests.get(url, headers={'User-agent':'Mozila/5.0'})
        html = response.text
        soup = BeautifulSoup(html, 'html.parser')

        # 만약 연예 뉴스라면
        if "entertain" in response.url :
            title = soup.select_one(".end_tit")
            content = soup.select_one("#articeBody")

        elif "sports" in response.url :
            title = soup.select_one("h4.title")
            content = soup.select_one("#newsEndContents")
            # 본문 내용안에 불필요한 div, p 삭제
            divs = content.select('div')
            for div in divs :
                div.decompose()
            paragrahs = content.select('p')
            for p in paragrahs:
                p.decompose()

        else :
            title = soup.select_one(".media_end_head_headline")
            content = soup.select_one("#newsEndContents")

        print("==========링크==========\n", url)
        print("==========제목==========\n", title.text.strip())
        print("==========본문==========\n", content.text.strip())
        time.sleep(0.3)

==========링크==========

https://n.news.naver.com/mnews/article/005/0001678573?sid=102

==========제목==========

나이도 못 막았다… 8090 ‘은발의 손흥민’들

Traceback (most recent call last):

File "c:\Program Files\FirstPython\crawling\10.셀리니움_기본설정\Chapter04\04.스포츠뉴스크롤링하기.py", line 42, in <module>

print("==========본문==========\n", content.text.strip())

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

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

하면 이렇게 에러가 나요 선생님 ㅠ.ㅠ 주소창을 보니깐 sports가 안 들어가 있는데 출력이 되어서 나옵니다. 혹시 넘어갈려면 어떻게 해야 하는지 여쭤봐도 되겠습니까?!

 

답변 1

1

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

안녕하세요!!

 

HTML에서 약간 업데이트가 있었네요

연예, 스포츠 뉴스가 아닌 일반뉴스의 본문을 가져오려면 선택자를 다음과 같이 써야 합니다

 

<CSS Selector>

#dic_area

import requests
from bs4 import BeautifulSoup
import time

response = requests.get('https://search.naver.com/search.naver?ssc=tab.news.all&where=news&sm=tab_jum&query=%EC%86%90%ED%9D%A5%EB%AF%BC')
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를 추출
        
        # 다시 request 날려 준다
        response = requests.get(url, headers={'User-agent':'Mozila/5.0'})
        html = response.text
        soup = BeautifulSoup(html, 'html.parser')

        # 만약 연예 뉴스라면
        if "entertain" in response.url :
            title = soup.select_one(".end_tit")
            content = soup.select_one("#articeBody")

        elif "sports" in response.url :
            title = soup.select_one("h4.title")
            content = soup.select_one("#newsEndContents")
            # 본문 내용안에 불필요한 div, p 삭제
            divs = content.select('div')
            for div in divs :
                div.decompose()
            paragrahs = content.select('p')
            for p in paragrahs:
                p.decompose()

        else :
            title = soup.select_one(".media_end_head_headline")
            content = soup.select_one("#dic_area")

        print("==========링크==========\n", url)
        print("==========제목==========\n", title.text.strip())
        print("==========본문==========\n", content.text.strip())
        time.sleep(0.3)
황성현님의 프로필 이미지
황성현
질문자

감사합니다!!선생님 덕분에 크롤링 공부를 재미있게 하고 있습니다!! 오늘도 좋은 하루 보내세용~~!~!

황성현님의 프로필 이미지
황성현

작성한 질문수

질문하기