美文网首页
旧版500px.com获取图片,新版还能用

旧版500px.com获取图片,新版还能用

作者: 喷射的熔浆 | 来源:发表于2017-08-30 05:03 被阅读0次

相信看这篇文章的都知道500px.com这个网站把,提供了好多优质的图片可以使用,但是网站的JS很强,只用右键是不能下载的,但是也可以Dev Tools看一下html代码就可以找出来,不过也很麻烦,如果要一张一张的下载的。
考虑:

  1. 网站这么多图片,不可能一次性加载完,必定有接口
    查看了“Network”tab发现确实有一个加载完页面之后,动态加载图片调用的API
  2. 图片点击才会放大,之前是小的图片,说明图片提供了多种尺寸的
    看API对用的GET参数发现,用一个数组形式的来定义的
  3. 使用PHP太简单,还是用Python弄一个吧

代码

现在网站更新了,就得API/v1(第一个版本)更新为了API/v2,网站所有的图片格式都是用Google的webp,不在是之前的jpeg格式了。
但是幸运的是现在还可以用是v1的接口,不知道以后等v2稳定了,v1是不是就down了。先不管那些,现在v1还可以用。

#!/usr/bin/python3
# file-name : byId2.py

# get picture by id from 500px.com
# by Ray Lee
# raylee.bio#qq.com

###############################
# 20170825
# 还可以用,但是网站吧所有图片格式都换成了webp
# 怪不得打不开
###############################
import sys, requests, json, shutil, os
import re
from urllib import parse # added 2017.03.04

# determine the destination folder
if sys.platform == 'linux':
    destFolder = "/mnt/c/Users/xxx/Pictures/500px/"
    logFolder = destFolder+".cache/"
else:
    destFolder = "C:\\Users\\xxx\\Pictures\\500px\\"
    logFolder = destFolder+".cache\\"

def log(cur, ib):
    '''log to file and stderr'''
    log_file = logFolder + "{}.log".format(ib)
    if not os.path.exists(log_file):
        print("", file=open(log_file, 'w+'), end='')
    print(cur+"\n", file=open(log_file,"a"))

def id_existed_or_not(id):
    '''check if the image id has existed in the dest folder
    if yes, skip
    '''
    existedFiles = os.listdir(destFolder)
    for f in existedFiles:
        if f.startswith(ib+"_"):
            return True
    return False

def id_valid_or_not(id):
    ''' is the image id is valid'''
    if len(id) < 8:
        return False
    else:
        return True
def get_photo_urls(ib, headers):
    ''' get urls of given image ids [array]'''
    try:
        r = requests.get("https://api.500px.com/v1/photos", params={"expanded_user_info": True, "ids": ib, "image_size[]": 2048, "include_licensing": True, "include_releases": True, "include_tags": True},headers=headers2)
        cont = json.loads(r.text)
    except ConnectionError as e:
        raise e
    else:
        if 'error' in cont: # added 2017.4.30
            print("\n"+ str(cont['status']) +" "+ cont['error'])
            sys.exit(1)
        return cont["photos"]

def save_photo(dat):
    '''save image data to file'''
    img_file_name = re.sub(r'[:<>"/|?*\\]',"-",dat[0])
    img_file_name = parse.unquote(img_file_name)
    url = dat[1]
    if url.startswith("/photo"):
        url = 'https://drscdn.500px.org'+url
    res = requests.get(url, headers=headers3, stream=True)
    if res.status_code == 200:
        res.raw.decode_content = True
        with open(destFolder+img_file_name, mode="wb") as img_file:
            shutil.copyfileobj(res.raw, img_file)
        print("# \033[01;32m>>{}\033[00m".format(img_file_name), file=sys.stderr, flush=True)
    else:
        print("x \033[01;31m<<Error to download\033[00m", file=sys.stderr)

# ids 支持使用,分割的多个id同时请求
# 1. check id's validity
valid_ids = []
if __name__ == '__main__':
    inputs = sys.argv[1:]
    # 必须提供参数,至少一个
    if len(inputs) < 1:
        print("at least one augument required", file=sys.stderr)
        sys.exit(0)
    for ib in inputs:
        if id_existed_or_not(ib) == True:
            print(ib+" existed, skipped", file=sys.stderr, flush=True)
            continue
        if id_valid_or_not(ib) == False:
            print(ib+" invalid, skipped", file=sys.stderr, flush=True)
            continue
        valid_ids.append(ib)
    
    if len(valid_ids) < 1:
        print("no valid id")
        sys.exit(1)

    # 1.1 check if the url has been cached under .cache folder
    cached_ids = []
    cachedFiles = os.listdir(logFolder)
    for f in cachedFiles:
        if f.startswith(ib+"."):
            cached_ids.append(ib);
            valid_ids.remove(ib);

    # 2, fetch url of each id
    urlhub = get_photo_urls(','.join(valid_ids), headers)

    # 3, save images
    # 3.1 add cached urls
    if cached_ids:
        for x in cached_ids:
            y = open(logFolder+x+".log")
            z = json.loads(y.read())
            urlhub[x] = z
    # 3.2 iterate the url hub and save image stream
    for i in urlhub:
        cur   = urlhub[i]
        name  = cur["name"]
        ext   = 'webp' if True else cur["image_format"]
        url   = cur["image_url"][-1]
        suri  = cur["url"].split('/')[-1]
        fname = "{}_{}.{}".format(i, suri, ext)
        log(json.dumps(cur), i)
        save_photo([fname, url])

运行

  1. 配置要放置图片的位置
  2. id_valid_or_not表示id至少需要8位数,但是之前的一些图片可能id会很小,只是我下载的是否防止自己复制错加的,你可以不用弄
  3. 现在是用的webp格式,默认浏览器可以打开,浏览器之不包括IE和Edge在内的其他网页浏览软件。
  4. headers headers2 headers3 包含个人信息,没有包括在内,需要的话可以发邮件给我,但不公开。
python3 byId2.py 225733431 225576949

相关文章

网友评论

      本文标题:旧版500px.com获取图片,新版还能用

      本文链接:https://www.haomeiwen.com/subject/yjkzdxtx.html