중복 출력과 TypeError: unhashable type: 'ResultSet'

조회수 923회

아래와 같이 코드를 작성했는데, 10개까지 가져오게 했는데 같은 값만 100개 출력하고 TypeError: unhashable type: 'ResultSet' 라는 메세지가 나옵니다..

어디를 만져야할지 모르겠네요.. 도움 부탁드립니다...

import requests
from bs4 import BeautifulSoup
from apscheduler.schedulers.blocking import BlockingScheduler

sched = BlockingScheduler()

old_reports = []

def extract_reports(old_reports=[]):
    url = 'http://dart.fss.or.kr/dsac001/mainAll.do'
    r = requests.get(url)
    soup = BeautifulSoup(r.text, 'html.parser')

    lists = soup.select('div.table_list > table > tr')

    reports = []
    for dart in lists[:10]:
        report = dart.find_all("a")
        reports.append(report)

    new_reports = []
    for dart in lists:
        if report not in old_reports:
            new_reports.append(report)

    return new_reports

def send_reports():
    global old_reports
    new_reports = extract_reports(old_reports)
    if new_reports:
        for report in new_reports:
            if ('href' in report[1].attrs):
                print('[{}][{}][{}]'.format(report[0].text.strip(), report[1].text.strip(), report[1].attrs['href'].strip()))
    else :
        print('[공시 없음]')

    old_reports += new_reports.copy()
    old_reports = list(set(old_reports))

send_reports()

sched.add_job(send_reports, 'interval', minute=5)

sched.start()

1 답변

  • 좋아요

    3

    싫어요
    채택 취소하기

    1. 같은 값만 출력되는 이유

    extract_reports()에서 마지막에 중복을 검사할 때 for dart in lists가 아닌 for report in reports로 바꿔 주셔야 합니다. 아마 실수하신 것 같네요.

    2. TypeError: unhashable type: 'ResultSet' 오류가 발생하는 이유

    BeautifulSoup 객체를 set 집합으로 변환하려고 하여 생기는 오류입니다.

    BeautifulSoup 객체를 tuple로 변환한 후 set 집합으로 변환하면 정상적으로 작동합니다.

    map(tuple, old_reports) 명령어를 호출하여 쉽게 old_reports 안의 모든 BeautifulSoup 객체를 변환할 수 있습니다.

    3. 추가 오류

    sched.add_job(send_reports, 'interval', minute=5)을 호출할 때 인자 이름이 minute가 아닌 minutes입니다.


    다음은 위 내용을 반영한 전체 코드입니다.

    import requests
    from bs4 import BeautifulSoup
    from apscheduler.schedulers.blocking import BlockingScheduler
    
    sched = BlockingScheduler()
    
    old_reports = []
    
    def extract_reports(old_reports=[]):
        url = 'http://dart.fss.or.kr/dsac001/mainAll.do'
        r = requests.get(url)
        soup = BeautifulSoup(r.text, 'html.parser')
    
        lists = soup.select('div.table_list > table > tr')
    
        reports = []
        for dart in lists[:10]:
            report = dart.find_all("a")
            reports.append(report)
    
        new_reports = []
        for report in reports:  # 바뀐 부분
            if not report in old_reports:
                new_reports.append(report)
    
        return new_reports
    
    def send_reports():
        global old_reports
        new_reports = extract_reports(old_reports)
        if new_reports:
            for report in new_reports:
                if ('href' in report[1].attrs):
                    print('[{}][{}][{}]'.format(report[0].text.strip(), report[1].text.strip(), report[1].attrs['href'].strip()))
        else :
            print('[공시 없음]')
    
        old_reports += new_reports.copy()
        old_reports = list(map(list, set(map(tuple, old_reports))))  # 바뀐 부분
    
    send_reports()
    
    sched.add_job(send_reports, 'interval', minutes=5)  # 바뀐 부분
    
    sched.start()
    
    • (•́ ✖ •̀)
      알 수 없는 사용자
    • 정말 감사합니다!! 실수들이 정말 부끄러울 뿐입니다... 반복되는 질문에 죄송하지만 else 값을 출력하는 경우 else 값이 아닌 []만을 출력하는데 한 번 봐주실 수 있을까요...?? 초보자 2020.2.21 09:49
    • 앗! 죄송합니다. 디버깅 구문 삭제한다는 걸 깜빡했네요; 수정했으니 다시 한번 확인해 주시겠어요? 알 수 없는 사용자 2020.2.21 10:24
    • 감사합니다..!! 많은 배움 얻고 갑니다. 좋은 하루 되세요! 초보자 2020.2.21 10:45

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)