2014-02-07 37 views
1

为了学习的目的,我试图下载Buzzfeed文章的所有帖子图像。下载的图像是空白图像,而不是实际图像

这里是我的代码:

import lxml.html 
import string 
import random 
import requests 

url ='http://www.buzzfeed.com/mjs538/messages-from-creationists-to-people-who-believe-in-evolutio?bftw' 
headers = headers = { 
     'User-Agent': 'Mozilla/5.0', 
     'From': '[email protected]' 
} 

page= requests.get(url) 

tree = lxml.html.fromstring(page.content) 

#print(soup.prettify()).encode('ascii', 'ignore') 

images = tree.cssselect("div.sub_buzz_content img") 

def id_generator(size=6, chars=string.ascii_uppercase + string.digits): 
    return ''.join(random.choice(chars) for x in range(size)) 

for image in images: 
    with open(id_generator() + '.jpg', 'wb') as handle: 
     request = requests.get(image.attrib['src'], headers=headers, stream=True) 

     for block in request.iter_content(1024): 
      if not block: 
       break 
      handle.write(block) 

什么被检索的图像的所有110个字节大小,并查看他们只是一个空的图像。我在我的代码中做错了什么,导致了这个问题?如果有更简单的方法来执行此操作,我不必使用请求。

+0

尝试添加一个用户代理到您的请求。许多网络服务器拒绝没有用户代理的请求。通常在抓取时在用户代理中留下一个电子邮件地址,以便让服务器所有者在您不批准抓取时与您联系。 –

+0

@SteinarLima仍然没有添加用户代理的运气。我用新代码更新了OP。我相信我正确实施了用户代理? – ComputerLocus

+0

另一个说明:您不应该将这些图像保存在您的计算机上。他们会让你看起来很愚蠢。 –

回答

1

如果你试图抓取网页的源代码,仔细观察,你会发现图像的URL要在img标签的src属性都没有规定,但在rel:bf_image_src属性。

image.attrib['src']更改为image.attrib['rel:bf_image_src']应该可以解决您的问题。

我没能复制你的代码(它声称cssselect未安装),但是这个代码顺利在我的电脑上BeautifulSoupurllib2运行,并下载所有22幅图片。

from itertools import count 
from bs4 import BeautifulSoup 
import urllib2 
from time import sleep 


url ='http://www.buzzfeed.com/mjs538/messages-from-creationists-to-people-who-believe-in-evolutio?bftw' 
headers = { 
    'User-Agent': 'Non-commercical crawler, Steinar Lima. Contact: https://stackoverflow.com/questions/21616904/images-downloaded-are-blank-images-instead-of-actual-images' 
} 

r = urllib2.Request(url, headers=headers) 
soup = BeautifulSoup(urllib2.urlopen(r)) 
c = count() 

for div in soup.find_all('div', id='buzz_sub_buzz'): 
    for img in div.find_all('img'): 
     print img['rel:bf_image_src'] 
     with open('images/{}.jpg'.format(next(c)), 'wb') as img_out: 
      req = urllib2.Request(img['rel:bf_image_src'], headers=headers) 
      img_out.write(urllib2.urlopen(req).read()) 
      sleep(5) 
+0

我想知道这个表示法是什么意思:'图像/ {}。jpg' – ComputerLocus

+0

@Fogest这是用[str.format](http://docs.python。组织/ 2 /库/ stdtypes.html#str.format)。我使用'c'作为['itertools.count'](http://docs.python.org/2/library/itertools.html#itertools.count),并使用''images/{}。jpg' .format(next(c))',文件名将从'0.jpg'开始并向上计数。 –

+0

啊好吧,这是有道理的。 count()基本上等价于将整数设置为0,然后每次循环运行时递增?如果是这样,使用'count()'是否有优势?使用递增数字可能比使用像我这样的随机字符串更好。 – ComputerLocus