【问题标题】:Scrape a jpg file on webpage, then saving it using python在网页上抓取一个 jpg 文件,然后使用 python 保存它
【发布时间】:2015-07-18 06:17:45
【问题描述】:

好的,我正在尝试从 Gucci 网站上抓取 jpg 图片。以此为例。

http://www.gucci.com/images/ecommerce/styles_new/201501/web_full/277520_F4CYG_4080_001_web_full_new_theme.jpg

我尝试了 urllib.urlretrieve,它不起作用,因为 Gucci 阻止了该功能。所以我想使用请求来抓取图像的源代码,然后将其写入 .jpg 文件。

image = requests.get("http://www.gucci.com/images/ecommerce/styles_new/201501/web_full/277520_F4CYG_4080_001_web_full_new_theme.jpg").text.encode('utf-8')

我对它进行了编码,因为如果我不这样做,它会一直告诉我 gbk 无法对字符串进行编码。

然后:

with open('1.jpg', 'wb') as f:
    f.write(image)

看起来不错吧?但结果是——无法打开jpg文件。没有图! Windows 告诉我 jpg 文件已损坏。

可能是什么问题?

  1. 我在想,也许我在抓取图像时丢失了一些信息,或者某些字符被错误地抓取了。但是我怎样才能知道是哪一个呢?

  2. 我在想可能是某些信息通过编码丢失了。但是如果我不编码,我什至不能打印它,更不用说将它写入文件了。

会出什么问题?

【问题讨论】:

  • 我发现wget 更适合这样的任务
  • wget 还在使用 urllib.urlretrieve,被 Gucci.com 屏蔽了
  • 文件已损坏,因为您没有写入任何内容。你期望f.write() 做什么?如果要保存image响应对象的内容,需要明确说明。

标签: python image python-3.x jpeg python-requests


【解决方案1】:

我不确定您使用encode 的目的。您不是在处理文本,而是在处理图像。您需要以二进制数据而不是文本的形式访问响应,并使用图像处理函数而不是文本函数。试试这个:

from PIL import Image
from io import BytesIO
import requests

response = requests.get("http://www.gucci.com/images/ecommerce/styles_new/201501/web_full/277520_F4CYG_4080_001_web_full_new_theme.jpg")
bytes = BytesIO(response.content)
image = Image.open(bytes)
image.save("1.jpg")

注意使用response.content 而不是response.text。您需要安装 PIL 或 Pillow 才能使用 Image 模块。 BytesIO 包含在 Python 3 中。

或者您可以直接将数据保存到磁盘而不查看里面的内容:

import requests
response = requests.get("http://www.gucci.com/images/ecommerce/styles_new/201501/web_full/277520_F4CYG_4080_001_web_full_new_theme.jpg")
with open('1.jpg','wb') as f:
    f.write(response.content)

【讨论】:

    【解决方案2】:

    JPEG 文件不是文本,而是二进制数据。所以你需要使用request.content属性来访问它。

    下面的代码还包括一个get_headers() 函数,当您浏览一个网站时会很方便。

    import requests
    
    def get_headers(url):
        resp = requests.head(url)
        print("Status: %d" % resp.status_code)
        resp.raise_for_status()
        for t in resp.headers.items():
            print('%-16s : %s' % t)
    
    def download(url, fname):
        ''' Download url to fname '''
        print("Downloading '%s' to '%s'" % (url, fname))
        resp = requests.get(url)
        resp.raise_for_status()
        with open(fname, 'wb') as f:
            f.write(resp.content)
    
    def main():
        site = 'http://www.gucci.com/images/ecommerce/styles_new/201501/web_full/'
        basename = '277520_F4CYG_4080_001_web_full_new_theme.jpg'
        url = site + basename
        fname = 'qtest.jpg'
    
        try:
            #get_headers(url)
            download(url, fname)
        except requests.exceptions.HTTPError as e:
            print("%s '%s'" % (e, url))
    
    if __name__ == '__main__':
        main()
    

    我们调用.raise_for_status() 方法,以便get_headers()download() 在出现问题时引发异常;我们在main() 中捕获异常并打印相关信息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-23
      • 1970-01-01
      • 1970-01-01
      • 2021-12-17
      相关资源
      最近更新 更多