2017-05-15 1 views
0

어떤 웹 사이트에서나 이미지를 다운로드 할 수있는 Python 스크립트를 작성하려고합니다. 그것은 효과가 있지만 일치하지 않습니다. 특히 find_all ("img")은 두 번째 url에 대해 그렇게하지 않습니다. 스크립트는 다음과 같습니다.BeautifulSoup find_all ("img")이 모든 사이트에서 작동하지 않습니다.

# works for http://proof.nationalgeographic.com/2016/02/02/photo-of-the-day-best-of-january-3/ 
# but not http://www.nationalgeographic.com/photography/proof/2017/05/lake-chad-desertification/ 
import requests 
from PIL import Image 
from io import BytesIO 
from bs4 import BeautifulSoup 

def url_to_image(url, filename): 
    # get HTTP response, open as bytes, save the image 
    # http://docs.python-requests.org/en/master/user/quickstart/#binary-response-content 
    req = requests.get(url) 
    i = Image.open(BytesIO(req.content)) 
    i.save(filename) 

# open page, get HTML request and parse with BeautifulSoup 
html = requests.get("http://proof.nationalgeographic.com/2016/02/02/photo-of-the-day-best-of-january-3/") 
soup = BeautifulSoup(html.text, "html.parser") 

# find all JPEGS in our soup and write their "src" attribute to array 
urls = [] 
for img in soup.find_all("img"): 
    if img["src"].endswith("jpg"): 
     print("endswith jpg") 
     urls.append(str(img["src"])) 
    print(str(img)) 

jpeg_no = 00 
for url in urls: 
    url_to_image(url, filename="NatGeoPix/" + str(jpeg_no) + ".jpg") 
    jpeg_no += 1 
+0

이상한 ... 디렉토리 PhantomJS와 –

답변

1

이미지는 실패한 페이지에서 JavaScript로 렌더링됩니다.

예를 (당신이 Web-scraping JavaScript page with Python을 볼 dryscrape 사용하지 않을 경우) 먼저 dryscrape

로 페이지를 렌더링

import requests 
from PIL import Image 
from io import BytesIO 
from bs4 import BeautifulSoup 
import dryscrape 

def url_to_image(url, filename): 
    # get HTTP response, open as bytes, save the image 
    # http://docs.python-requests.org/en/master/user/quickstart/#binary-response-content 
    req = requests.get(url) 
    i = Image.open(BytesIO(req.content)) 
    i.save(filename) 

# open page, get HTML request and parse with BeautifulSoup 

session = dryscrape.Session() 
session.visit("http://www.nationalgeographic.com/photography/proof/2017/05/lake-chad-desertification/") 
response = session.body() 
soup = BeautifulSoup(response, "html.parser") 

# find all JPEGS in our soup and write their "src" attribute to array 
urls = [] 
for img in soup.find_all("img"): 
    if img["src"].endswith("jpg"): 
     print("endswith jpg") 
     urls.append(str(img["src"])) 
     print(str(img)) 

jpeg_no = 00 
for url in urls: 
    url_to_image(url, filename="NatGeoPix/" + str(jpeg_no) + ".jpg") 
    jpeg_no += 1 

그러나 나는 또한 당신이 절대 URL이 아닌 상대 일이 있는지 확인합니다 :

import requests 
from PIL import Image 
from io import BytesIO 
from bs4 import BeautifulSoup 
import dryscrape 
from urllib.parse import urljoin 


def url_to_image(url, filename): 
    # get HTTP response, open as bytes, save the image 
    # http://docs.python-requests.org/en/master/user/quickstart/#binary-response-content 
    req = requests.get(url) 
    i = Image.open(BytesIO(req.content)) 
    i.save(filename) 

# open page, get HTML request and parse with BeautifulSoup 
base = "http://www.nationalgeographic.com/photography/proof/2017/05/lake-chad-desertification/" 
session = dryscrape.Session() 
session.visit(base) 
response = session.body() 
soup = BeautifulSoup(response, "html.parser") 

# find all JPEGS in our soup and write their "src" attribute to array 
urls = [] 
for img in soup.find_all("img"): 
    if img["src"].endswith("jpg"): 
     print("endswith jpg") 
     urls.append(str(img["src"])) 
     print(str(img)) 

jpeg_no = 00 
for url in urls: 
    if url.startswith('http'): 
     absoute = url 
    else: 
     absoute = urljoin(base, url) 
    print (absoute) 
    url_to_image(absoute, filename="NatGeoPix/" + str(jpeg_no) + ".jpg") 
    jpeg_no += 1 
+0

또는 셀레늄 존재 또는 Google 크롬 헤드리스를 지원 (하지 않았다 그것을 시도해보십시오) –

+0

이미지가 JS로 렌더링되었다고 어떻게 말할 수 있습니까? –

+0

Firefox에서 웹 개발자 도구 모음을 사용하여 JavaScript를 끄면 이미지가 표시되지 않습니다. 또한 페이지 소스 (소스가 생성되지 않음)를 보면 HTML의 이미지 요소를 볼 수 없지만 JavaScript에서는 많은 참조를 볼 수 있습니다. 위의 방법을 사용하여 이미지를 긁어 낼 수있었습니다. –

관련 문제