user999 发表于 2022-6-11 20:23

python小虫子,爬取天空之城的图片信息和作者信息

本帖最后由 user999 于 2022-6-11 20:30 编辑

首先说下,我不是计算机专业,我之前就会点VBA。2022年的疫情,从3月份开始,一直在家里闷到了5月15号。为了避免自己变成废物,硬着头皮学的PYTHON。当下主攻爬虫,下一步准备学习pandas的相关内容。
今天带来的作品,是爬取天空之城这个网站的内容。网站地址:全球航拍爱好者和专业摄影师的作品社区 | 天空之城 (skypixel.com)
这个是大疆旗下的视频分享社区,里面的图片视频质量非常非常高。
我这里放上的代码,入口是图片区。
功能如下:
在图片区,以热度为排序标准,依次爬取专区内图片,并且统计相关作者的主页,并对作者的一些信息进行收集整理。毕竟大家口味不同,统计这个信息,有助于迅速的找到让自己心水的那位大神。
在正式放上代码之前,
说句话:我觉得大家不用害羞,能跑就可以。要么你能跑,要么你代码能跑。{:301_977:}你不发出来,你咋知道自己哪里不OK?学习路上,最怕的就是自闭。
首先感谢以下论坛的小伙伴,排名不分先后:
@gzq830510 @surepj @叫我小王叔叔 @cdsgg
感谢你们在这几个月,耐心的回答我在编程区提出的那些傻缺问题,学习之路上,遇到你们这些热心人,我很感激,谢谢~

https://static.52pojie.cn/static/image/hrline/1.gif
先上一张统计图:直接输出的不是这样的,是一个CSV文件,我还没学会pandas。所以。这个表的美化是手动做的。实际上,是在PY文件同级文件夹生成一个CSV文件。其实也没什么,就是按照作者名字,去重。然后简单做个表头。最后面的链接,是用的EXCEL的HYPERLINK函数。

然后,放上一张,在天空之城,很随便就可以看到这种质量的图片:


https://static.52pojie.cn/static/image/hrline/1.gif
进入正题:因为我还没搞定路径问题,所以建议代码和文件夹这样放:
xxxxx←----你喜欢的名字当文件夹名
|---→img #-------img文件夹,用来放图片
|-----xxxx.py #----代码文件
然后说一下,代码里面我觉得比较诡异的那几个段落:
title = re.sub('[\[/:*?"<>|.\n\\\!,\]]', '_', img.get('title'))# 作品名称
如此鬼畜实属无奈,因为我最终要上传到百度云盘,事实上,即便我这样设置了,依然还有很多图片上传失败。因为大神的个性的图片名称,让我有点处理不了,我也不知道咋屏蔽颜文字。
slugUser = img.get('user', {}).get('slug','保密')# 单独的作者编号
这个网站我走的是JSON数据,都是用的字典匹配。但是这个网站比较有意思的地方是,如果说有人选择了隐蔽性别,那么这个键就没有,而不是性别=‘保密’这种。
然后下面就是代码了,请各位大佬斧正吧:
import requests
import time
import csv
import re

with open('tkuser.csv', mode='a', newline='', encoding='utf-8') as f:
    csv_Header = ('作者名称', '作者性别', '作者国籍', '注册时间', '作者身份', '作者声望', '粉丝数', '关注的人', '作品获赞数', '作品数量', '作者主页')
    csv.writer(f).writerow(csv_Header)

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
                  'Chrome/102.0.5005.63 Safari/537.36 Edg/102.0.1245.30 '
}

paramsUser = {
    'lang': 'zh-Hans',
    'platform': 'web',
    'device': 'desktop'
}

webPage = 0
imgNum = 0

while True:

    try:

      url = 'https://www.skypixel.com/api/v2/tags/a2a2dfa4-ac36-43b9-9d65-edbfc5dbbe09/photos?'

      params = {
            'lang': 'zh-Hans',
            'platform': 'web',
            'device': 'desktop',
            'sort': 'popular',
            'cycle': 'all',
            'limit': '15',
            'offset': webPage
      }

      imgAll = requests.get(url=url, headers=headers, params=params).json()
      img_Dict = imgAll.get('data', {}).get('items')

      for img in img_Dict:
            time.sleep(2)
            imgNum += 1
            title = re.sub('[\[/:*?"<>|.\n\\\!,\]]', '_', img.get('title'))# 作品名称
            comment_count = img.get('comment_count')# 作品评论
            view_count = img.get('view_count')# 作品浏览数
            like_count = img.get('like_count')# 作品点赞
            imgType = img.get('type')# 作品类型
            large = img.get('image', {}).get('large')# 作品链接
            name = img.get('user', {}).get('name')# 作者名字
            slug = 'https://www.skypixel.com/users/' + img.get('user', {}).get('slug')# 作者页面--下面是作者页面信息
            slugUser = img.get('user', {}).get('slug')# 单独的作者编号
            urlUser = f'https://www.skypixel.com/api/v2/users/{slugUser}?'
            linkUser = requests.get(url=urlUser, headers=headers, params=paramsUser).json()
            userDict = linkUser.get('data', {}).get('item')
            # country_code = userDict['country_code']# 国籍
            country_name = userDict.get('country_name')# 国籍
            created_at = userDict.get('created_at')# 注册时间
            userType = userDict.get('type')# 作者身份
            credit_score = userDict.get('credit_score')# 声望
            followee_count = userDict.get('followee_count')# 关注的人
            follower_count = userDict.get('follower_count')# 粉丝
            gender = userDict.get('gender')# 性别
            work_count = userDict.get('work_count')# 作品数量
            work_liked_count = userDict.get('work_liked_count')# 作者被赞次数
            imgDown = requests.get(url=large, headers=headers).content# 下载图片
            print(f'正在保存 {title} ,作者为 {name} 这是第 {imgNum} 张图片-当前页码 {webPage}')

            with open('img\\' + f'{name}_{title}.jpg', mode='wb') as f:
                f.write(imgDown)

            with open('tkuser.csv', mode='a', newline='', encoding='utf-8') as f:
                csv_Header = (
                  name, gender, country_name, created_at, userType, credit_score, follower_count, followee_count,
                  work_liked_count, work_count, slug)
                csv.writer(f).writerow(csv_Header)

      webPage += 15

    except IOError as e:
      print('捕获到异常', e)
      break
因为我也不知道到底有多少图片,至少前500张肯定是没问题的。在运行区,会有这样的提示:

下面的信息如此啰嗦有如下考虑:
1,如果程序中途跑了,或者我跑了。你可以知道你大概下载到哪一段了。记下后面的页数,把webPage数字改成对应的,变相解决“断点续传”问题。

CSV如果采用UTF-8格式,一定几率EXCEL打开是乱码的。需要使用数据,导入,然后编码那块,选择上面的,然后,分隔符号,选择“,”。百度说这个是EXCEL的BUG。

最后再次感谢论坛所有帮助过我的人,祝大家工作顺利,生活愉快~{:301_978:}

iceleali 发表于 2022-6-12 00:16

果然,那啥才是动力

user999 发表于 2022-6-12 07:48

萌新与小白 发表于 2022-6-11 23:24
excel打开csv乱码,可以看看https://gitee.com/uid_random/python_exercise/blob/master/spider/4/2.bs4%E7 ...

excel在中文系统中打开文件时以gbk编码,所以若csv文件是以utf-8编码写入的内容,则用excel打开时中文会乱码(解决方式是用记事本另存为ANSI),但用文本编辑器或pycharm打开utf-8编码的csv文件不会乱码。文档原话:由于使用open()来读取CSV文件,因此默认情况下,将使用系统默认编码来解码文件并转换为unicode(请参阅locale.getpreferredencoding())。要使用其他编码来解码文件,请使用open的encoding参数。
-----------------
编码这一块一直在折磨我,非相关专业,底子薄。谢谢提供的解决方案。学习了。

prince_cool 发表于 2022-6-11 21:15

学习了!!!!!!

lichenrong 发表于 2022-6-11 21:40

学习了,这个代码写的不错

pglsh210 发表于 2022-6-11 22:04

学习了,,,,,

萌新与小白 发表于 2022-6-11 23:24

excel打开csv乱码,可以看看https://gitee.com/uid_random/python_exercise/blob/master/spider/4/2.bs4%E7%88%AC%E5%8F%96%E6%8B%9B%E8%81%98.py#L221,save_data()的注释

韬韬同学 发表于 2022-6-12 08:01

太难啦,小白看的眼花

yjn866y 发表于 2022-6-12 08:37

学习一下,,自己复个盘

西红柿叶子 发表于 2022-6-12 10:02

学习一下
页: [1] 2 3
查看完整版本: python小虫子,爬取天空之城的图片信息和作者信息