Python2.7 코드 질문..

조회수 1660회

이미지 URL 을 추출하는 프로그램인데요, 2가지 문제때문에 애를 먹고 있습니다.

  1. .gif 형식은 제외를 하고 추출을 하고 싶은데 잘 안되네요 ㅜ
  2. 특정 사이트의 경우, 에러가 나오는데요 , key error 가 나옵니다. Traceback (most recent call last): File "jung.py", line 8, in <module> for url in img_urls: print(url) File "jung.py", line 7, in <genexpr> img_urls = (img['src'] if img['src'].startswith('http') else "{}{}".format(_url, img['src']) for img in imgs) File "/Users/eunhyulkim/opt/anaconda3/envs/eun/lib/python2.7/site-packages/bs4/element.py", line 1011, in __getitem__ return self.attrs[key] KeyError: 'src'

https://stackoverflow.com/questions/14587728/what-does-this-error-in-beautiful-soup-means

이쪽 증상이랑 비슷한것 같은데, 제가 고쳐도 계속 에러가 멈추지 않아서 문의 드려요 .

어떻게 수정을 해야 할까요 .. 참고로 저는 python 2.7 버전입니다.

import requests, bs4

_url = 'https://twitter.com/'


content = requests.get(_url).content
imgs = bs4.BeautifulSoup(content, 'html.parser', parse_only=bs4.SoupStrainer('img'))                             
img_urls = (img['src'] if img['src'].startswith('http') else "{}{}".format(_url, img['src']) for img in imgs)
for url in img_urls: print(url)

1 답변

  • 파이썬에 pdb 라는 디버거가 내장되어 있습니다.

    사용법은 단순합니다. 파이썬 3.7 부터는 breakpoint 라는 내장함수가 제공되므로 그것을 사용하면 됩니다만 그 이전버전은 아래와 같이 사용합니다.

    • pdb_test.py
    import requests, bs4
    
    _url = 'https://twitter.com/'
    
    
    content = requests.get(_url).content
    imgs = bs4.BeautifulSoup(content, 'html.parser', parse_only=bs4.SoupStrainer('img'))
    import pdb; pdb.set_trace()
    img_urls = (img['src'] if img['src'].startswith('http') else "{}{}".format(_url, img['src']) for img in imgs)
    for url in img_urls: print(url)
    

    pdb_test.py 파일을 실행하면 import pdb; pdb.set_trace() 를 설정한 다음 라인에서 프로그램이 일시 멈춤이 되며 입력이 가능한 상태가 됩니다.

    여기서 list 라고 커맨드를 주면 소스를 display 하게 되며 실행한 현재상황까지의 변수들을 확인할 수 있습니다.

    python pdb_test.py    # cmd 창에서 pdb_test.py 파일 실행
    > d:\pdb_test.py(9)<module>()
    -> img_urls = (img['src'] if img['src'].startswith('http') else "{}{}".format(_url, img['src']) for img in imgs)
    (Pdb) list
      4
      5
      6     content = requests.get(_url).content
      7     imgs = bs4.BeautifulSoup(content, 'html.parser', parse_only=bs4.SoupStrainer('img'))
      8     import pdb; pdb.set_trace()
      9  -> img_urls = (img['src'] if img['src'].startswith('http') else "{}{}".format(_url, img['src']) for img in imgs)
     10     for url in img_urls: print(url)
    [EOF]
    (Pdb) imgs
    <img alt="" class="avatar size32"/><img alt="" class="avatar size32"/><img alt="" class="avatar size32"/>
    

    imgs 값을 확인해보니 아래와 같습니다. src 속성이 없으므로 key 에러가 맞습니다.

    (Pdb) imgs
    <img alt="" class="avatar size32"/><img alt="" class="avatar size32"/><img alt="" class="avatar size32"/>
    

    즉 html 문서에서 img tag를 사용했지만 src 속성은 사용하지는 않았습니다. 즉 프로그래밍을 할 때 src가 없을수도 있다는 가정을 하고 프로그래밍 해야 합니다.

    import requests, bs4
    
    _url = 'https://twitter.com/'
    
    
    content = requests.get(_url).content
    imgs = bs4.BeautifulSoup(content, 'html.parser', parse_only=bs4.SoupStrainer('img'))
    img_urls = (img['src'] if img['src'].startswith('http') else "{}{}".format(_url, img['src'])
                                for img in imgs
                                    if img.has_attr('src'))    # 각 tag 마다 src 속성이 있는지 확인하여 존재하는 것만 취함.
    for url in img_urls:
        if url.rfind('.') > -1 and url[url.rfind('.'):].lower() != '.gif':    # .gif 가 아닌 것만 추출
            print(url)
    

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

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

(ಠ_ಠ)
(ಠ‿ಠ)