python爬虫学习记录——爬取500px的图片

500px并没有什么防爬虫的措施,爬取上面的图片还是相对简单的,唯一的问题是500px已被视觉中国收购,由于版权问题请谨慎使用爬取的图片

打开一个作者的主页面

直接从源码里得到的图片链接仅仅是缩略图,并不是高清图片

而且此处用了ajax动态加载,下拉到底部才会继续加载50张图片,所以想要直接从作者主页的源码爬取是比较困难的

查看网络

Ajax的功能是依赖xhr(XMLHttpRequest)来实现的,查看网络中获取的xhr响应内容,发现了一些json数据包,点击后可以看到包含了一些有关图片的具体信息。

新标签页打开后发现确实包含了许多图片的相关信息

可以看到共有7页,310个项目(图片),当前为第3页

再观察一下url,尝试修改url进行请求

去除掉其他品质的图片,只留下尺寸最大的图片,修改每页显示的图片为100,请求成功。

每页的图片数量达到了100,且只剩下最高品质图片的url

尝试修改每页显示200项

仍然只显示100项

看来不能一步到位

通过requests工具获取数据,不用请求头即可成功

获取到的a是一个dict对象

观察下图片的url的位置

即可获取所有图片的url

这里可以将一些有用的相关信息导入自建数据库以便进行筛选或管理,这里我们只需要图片的url用以下载

大致的思路就是这样,是脚本代码放在最后,写的比较粗糙,没考虑下载超时等之类问题


全部的脚本代码

import requests

import urllib.request

from multiprocessing import Pool

import os

import re

def get_id(url):

a = requests.get(url)

id = re.findall('"id":(.*?),', a.text)[0]  #利用正则表达式解析响应获取作者的数字id

return id

def get_image(userid):

page="1"

images=[]

url="https://api.500px.com/v1/photos?feature=user&stream=photos&user_id="+userid+"&include_states=true&image_size[]=2048&page="+page+"&rpp=100"  #对请求的url进行编辑

ifm=requests.get(url)

x=ifm.json()

dir=x['photos'][0]['user']['fullname']  #获取作者的名字用以新建目录

if not os.path.exists(dir):

os.mkdir(dir)                      #若没有这个目录则新建目录

for i in range(1,x['total_pages']+1):  #获取页数并遍历

url="https://api.500px.com/v1/photos?feature=user&stream=photos&user_id="+userid+"&include_states=true&image_size[]=2048&page="+str(i)+"&rpp=100"

ifm = requests.get(url)

y = ifm.json()

for j in y['photos']:

image_m=(str(j['id']),j['name'],j['image_url'][0],dir)      #获取部分需要的信息放在一个元组中

images.append(image_m)          #将所有信息放在一个列表中

return images

def download_img(m):

try:

url=m[2]                                        #图片url

path=m[3]+'/'+m[0]+'.jpg'          #存放路径与图片名,为避免重名,用图片的id作为名字

if not os.path.exists(path):        #若文件不存在则进行下载

# print(m[0],m[2])

urllib.request.urlretrieve(url,path)

except:

fail.append(m[0])                  #对下载出错的图片id进行记录

if __name__=='__main__':

fail = []

userid=get_id("https://500px.com/vossiem") #输入作者的主页地址,获取作者数字id

a=get_image(userid)                    #输入作者数字id

print(len(a))                                  #照片总数

p=Pool(50)                                    #新建进程池

for i in a:

p.apply_async(download_img,(i,))

p.close()

p.join()

print('failed:',fail)

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容