在网页上抓取一个 jpg 文件,然后使用 python 保存它
Scrape a jpg file on webpage, then saving it using python
好的,我正在尝试从 Gucci 网站上抓取 jpg 图片。以此为例。
我试过urllib.urlretrieve,但没用,因为 Gucci 屏蔽了这个功能。所以我想用requests来抓取图片的源代码,然后写入一个.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 文件已损坏。
可能是什么问题?
我在想,可能是我在抓图的时候漏掉了一些信息,或者抓错了一些字符。但是我怎样才能找出是哪一个呢?
我在想,也许一些信息通过编码丢失了。但是如果我不编码,我连打印都无法打印,更不用说写入文件了。
可能会出什么问题?
我不确定您使用 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)
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()
中捕获异常并打印相关信息。
好的,我正在尝试从 Gucci 网站上抓取 jpg 图片。以此为例。
我试过urllib.urlretrieve,但没用,因为 Gucci 屏蔽了这个功能。所以我想用requests来抓取图片的源代码,然后写入一个.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 文件已损坏。
可能是什么问题?
我在想,可能是我在抓图的时候漏掉了一些信息,或者抓错了一些字符。但是我怎样才能找出是哪一个呢?
我在想,也许一些信息通过编码丢失了。但是如果我不编码,我连打印都无法打印,更不用说写入文件了。
可能会出什么问题?
我不确定您使用 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)
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()
中捕获异常并打印相关信息。