• 카테고리

    질문 & 답변
  • 세부 분야

    프로그래밍 언어

  • 해결 여부

    미해결

list index out of range

20.04.21 13:50 작성 조회수 312

1

항상 좋은 강의 감사합니다. 따라 하는중에 아래와 같은 메시지와 함께 에러가 납니다. 직접 올려주신 소스코드로 실행해도 동일한 메세지가 나옵니다. 다음강의와 연결이 되는것 같아서.. 에러 해결하고 넘어갈려고 합니다. 

D:\Python36\python.exe D:/workpy/Practice/강좌-소스코드/09.크롤링/magnet.py

Traceback (most recent call last):

  File "D:/workpy/Practice/강좌-소스코드/09.크롤링/magnet.py", line 45, in <module>

    results = search_google("리눅스", 0)

  File "D:/workpy/Practice/강좌-소스코드/09.크롤링/magnet.py", line 17, in search_google

    counts = bs.select("div#resultStats")[0].text.replace("검색결과 약", "").replace("개", "").replace(",", "").split("(")[0].strip()

IndexError: list index out of range

Process finished with exit code 1

참고로 아래는 실행했던 코드(직접 올려주신 소스코드)입니다. 

import requests
from bs4 import BeautifulSoup
import re

"리눅스 magent:?xt="

def search_google(keyword, start_page, end_page=None):
url = "https://www.google.com/search?q={0}+magnet%3A%3Fxt%3D&oq={0}+magnet%3A%3Fxt%3D".format(keyword)
header = {"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36,gzip(gfe)"}
r = requests.get(url, headers=header)
bs = BeautifulSoup(r.text, "lxml")
links = bs.select("div.g > div > div.rc > div.r > a")

results = []

if end_page is None:
counts = bs.select("div#resultStats")[0].text.replace("검색결과 약", "").replace("", "").replace(",", "").split("(")[0].strip()
end_page = int(int(counts) / 10)
if end_page > 20:
end_page = 20

for a in links:
href = a["href"]
text = a.select("h3")
if len(text) <= 0:
continue
title = text[0].text

try:
r = requests.get(href)
bs = BeautifulSoup(r.text, "lxml")
magnets = bs.find_all("a", href=re.compile(r'magnet:\?xt=*'))

if len(magnets) > 0:
magnet = magnets[0]["href"]
results.append((title, magnet))
except:
pass
if start_page < end_page:
start_page += 10
results.extend(search_google(keyword, start_page, end_page=end_page))

return results

results = search_google("리눅스", 0)

for r in results:
print(r)

답변 3

·

답변을 작성해보세요.

1

맞습니다. 원래 강좌도 영화나 드라마 같은 검색어를 예시로 들면 더 좋은데 이게 참 공개적인 강좌에서 그런 부분을 다루는게 아무래도 여러가지 고려할 사항이 있어서 어거지로 만들어낸 예시 검색어였습니다. ㅎㅎㅎ

그리고 해당 코드를 다시한번 수정해서 업데이트 했습니다. 기존의 코드에서 페이징 하는 구간에 누락된 코드가 있어서 변경 적용하였으니 참고하시기 바랍니다.

1

크롤링 코드는 대상 사이트가 항상 변할 수 있기 때문에 내용을 확실히 이해하고 있어야 변화된 사이트에 맞게 수정을 할 수 있습니다. 확인해보니 위 코드는 구글 검색 결과 페이지의 내용이 전과 달라져 몇 군데를 수정해야 정상적으로 동작합니다.

links = bs.select("div.g > div > div.rc > div.r > a") 이 부분에서 첫 div 가 사라졌습니다 따라서

links = bs.select("div.g > div.rc > div.r > a") 로 변경되야 합니다.

그리고 검색 결과가 나오는 태그의 ID 값이 변경되었습니다. div#resultStats 에서 div#result-stats 로 변경되었습니다.

import requests
from bs4 import BeautifulSoup
import re

"리눅스 magent:?xt="


def search_google(keyword, start_page, end_page=None):
    url = "https://www.google.com/search?q={0}+magnet%3A%3Fxt%3D&oq={0}+magnet%3A%3Fxt%3D".format(keyword)
    header = {"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36,gzip(gfe)"}
    r = requests.get(url, headers=header)
    bs = BeautifulSoup(r.text, "lxml")
    links = bs.select("div.g > div.rc > div.r > a")

    results = []

    if end_page is None:
        counts = bs.select("div#result-stats")[0].text.replace("검색결과 약", "").replace("개", "").replace(",", "").split("(")[0].strip()
        end_page = int(int(counts) / 10)
        if end_page > 20:
            end_page = 20

    for a in links:
        href = a["href"]
        text = a.select("h3")
        if len(text) <= 0:
            continue
        title = text[0].text

        try:
            r = requests.get(href)
            bs = BeautifulSoup(r.text, "lxml")
            magnets = bs.find_all("a", href=re.compile(r'magnet:\?xt=*'))

            if len(magnets) > 0:
                magnet = magnets[0]["href"]
                results.append((title, magnet))
        except:
            pass
    if start_page < end_page:
        start_page += 10
        results.extend(search_google(keyword, start_page, end_page=end_page))

    return results

results = search_google("리눅스", 0)

for r in results:
    print(r)

위 코드가 제가 수정 테스트한 코드의 전체 코드 입니다.

0

페파님의 프로필

페파

질문자

2020.04.22

항상 친절한 답변 감사드립니다. links = bs.select("div.g > div.rc > div.r > a") 은 보고 변경했는데, 검색결과 태그가 변경된 것을 놓쳤네요.

그외 추가적으로 수정한 사항들은,

1) "검색결과 약 xxx개 (x.xx)"문자가 중국어로 나와서(이유는 알수없으나) 기존 replace 문자 변경

2) 아무 결과물없이 프로세스가 완료되어 검색어 변경(리눅스 -> 영화제목등). 리눅스는 a태그 링크로 마그넷주소를 남겨두지 않은 사이트들이 많아서, 조건에 맞는 결과물이 많지 않은듯함. 검색어를 변경해서 실행해보니 결과물이 나옴. 

혹시나 같은문제로 고민하시는 분들이 있을까 남겨둡니다.