2015-11-04 75 views
0

我使用urlretrieve从网站上刮取图像。除了一个以外,这很有效,而不是非常小的细节。这些文件不可读。我尝试了几个网站,但结果是一样的。我想知道我是否应该指出它是一个二进制下载,但在文档中找不到任何提示。搜索了网页,发现了与请求库的一些替代方法,但结果相同。 Windows照片查看器,Paint和Gimp都报告该文件已损坏或无法读取。我很确定我正在犯一些愚蠢的错误。任何帮助将不胜感激!urlretrieve似乎损坏图像文件

def get_images(url, soup): 
    #this makes a list of bs4 element tags 
    print 'URL: ', url 
    n = 0 
    images = [img for img in soup.findAll('img')] 

    #compile our unicode list of image links 
    image_links = [each.get('src') for each in images] 
    for each in image_links: 
     n = n + 1 
     path = urlparse.urlparse(each).path 
     fn = (os.path.split(path)[1]).strip() 
     ext = (os.path.splitext(fn)[1]).strip().lower() 
     if (fn == '' or ext == ''): 
      continue 

     fn = os.path.join ("images", fn) 

#  print 'From: ', url 
     print 'Each> ', each 
#  print 'File< ', fn 
#  avatar = open(fn, 'wb') 
#  avatar.write(requests.get(url).content) 
#  avatar.close() 
     result = urllib.urlretrieve(url, fn) 
     print result 

    return n 

更新

Jephron向我指出了正确的方向,我没有正确与图像路径组合的URL。他的解决方案的工作原理是使用urlparse.urljoin(url, each),正如我最初所做的那样使用os.path.join,可能会导致突然在Windows系统中的url中出现反斜杠。非常烦人。我添加了相对和绝对url路径的测试,最终代码如下所示。

def get_images(url, soup): 
    #this makes a list of bs4 element tags 
    print ' ' 
    print 'URL: ', url 
    n = 0 
    images = [img for img in soup.findAll('img')] 

    #compile our unicode list of image links 
    image_links = [each.get('src') for each in images] 

    for each in image_links: 
     path = urlparse.urlparse(each).path 
     fn = (os.path.split(path)[1]).strip() 
     ext = (os.path.splitext(fn)[1]).strip().lower() 
     if (fn == '' or ext == ''): 
      continue 

     fn = os.path.join ("images", fn) 
     if (not (each.startswith ('http:') or each.startswith('https:'))): 
      image_link = urlparse.urljoin(url, each) 
     else: 
      image_link = each 

     print 'Found: ', fn 

     try: 
      urllib.urlretrieve(image_link, fn) 
      n = n + 1 
     except: 
      continue 

    return n 

但请注意,3/4的.png仍然不可读。我必须找出原因,但仍可能存在隐藏的障碍。

回答

2

我运行了你的代码,看看它下载的“图像”。事实证明,您保存的文件内容实际上是网站的整个HTML。尝试在文本编辑器中打开它并亲自查看。

要解决这个问题,请注意,您传递给urlretrieve的参数实际上是您所刮取的网页的网址。如果您将图片网址加入网页网址,您将获得正确的网址:

def get_images(url, soup): 
    #this makes a list of bs4 element tags 
    print 'URL: ', url 
    n = 0 
    images = [img for img in soup.findAll('img')] 

    #compile our unicode list of image links 
    image_links = [each.get('src') for each in images] 
    for each in image_links: 
     print "maybe an image" 
     print each 
     n = n + 1 
     path = urlparse.urlparse(each).path 
     fn = (os.path.split(path)[1]).strip() 
     ext = (os.path.splitext(fn)[1]).strip().lower() 
     if (fn == '' or ext == ''): 
      continue 

     fn = os.path.join ("images", fn) 

     print 'Each> ', each 

     result = urllib.urlretrieve(os.path.join(url, each), fn) 
     print result 

    return n 
+0

感谢您运行和测试我的代码的麻烦!它指出我在正确的方向。我用正确的解决方案编辑了我的问题。非常感谢! – Arnold