社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

Python 抓取知乎几千张小姐姐图片是什么体验?

Python绿色通道 • 3 年前 • 184 次点击  

↑ 关注 + 星标 ,每天学Python新技能

后台回复【大礼包 】送你Python自学大礼包

文 | 某某白米饭

来源:Python 技术「ID: pythonall」

知乎上有许多关于颜值、身材的话题,有些话题的回复数甚至高达几百上千,拥有成千上万的关注者与被浏览数。如果我们在摸鱼的时候欣赏这些话题将花费大量的时间,可以用 Python 制作一个下载知乎回答图片的小脚本,将图片下载到本地。

请求 URL 分析

首先打开 F12 控制台面板,看到照片的 URL 都是 http://img2.jintiankansha.me/get2?src=http://pic4.zhimg.com/80/xxxx.jpg?source=xxx 这种格式的。

滚动知乎页面向下翻页,找到一个带 limit,offset 参数的 URL 请求。

检查 Response 面板中的内容是否包含了图片的 URL 地址,其中图片地址 URL 存在 data-original 属性中。

提取图片的 URL

从上图可以看出图片的地址存放在 content  属性下的 data-original 属性中。

下面代码将获取图片的地址,并写入文件。

import re
import requests
import os
import urllib.request
import ssl

from urllib.parse import urlsplit
from os.path import basename
import json

ssl._create_default_https_context = ssl._create_unverified_context

headers = {
    'User-Agent'"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36",
    'Accept-Encoding''gzip, deflate'
}

def get_image_url(qid, title):
    answers_url = 'https://www.zhihu.com/api/v4/questions/'+str(qid)+'/answers?include=data%5B*%5D.is_normal%2Cadmin_closed_comment%2Creward_info%2Cis_collapsed%2Cannotation_action%2Cannotation_detail%2Ccollapse_reason%2Cis_sticky%2Ccollapsed_by%2Csuggest_edit%2Ccomment_count%2Ccan_comment%2Ccontent%2Ceditable_content%2Cattachment%2Cvoteup_count%2Creshipment_settings%2Ccomment_permission%2Ccreated_time%2Cupdated_time%2Creview_info%2Crelevant_info%2Cquestion%2Cexcerpt%2Cis_labeled%2Cpaid_info%2Cpaid_info_content%2Crelationship.is_authorized%2Cis_author%2Cvoting%2Cis_thanked%2Cis_nothelp%2Cis_recognized%3Bdata%5B*%5D.mark_infos%5B*%5D.url%3Bdata%5B*%5D.author.follower_count%2Cbadge%5B*%5D.topics%3Bdata%5B*%5D.settings.table_of_content.enabled&offset={}&limit=10&sort_by=default&platform=desktop'
    offset = 0
    session = requests.Session()

    while True:
        page = session.get(answers_url.format(offset), headers = headers)
        json_text = json.loads(page.text)
        answers = json_text['data']

        offset += 10

        if not answers:
            print('获取图片地址完成')
            return

        pic_re = re.compile('data-original="(.*?)"', re.S)

        for answer in answers:
            tmp_list = []
            pic_urls = re.findall(pic_re, answer['content'])

            for item in pic_urls:  
                # 去掉转移字符 \
                pic_url = item.replace("\\""")
                pic_url = pic_url.split('?')[0]

                # 去重复
                if pic_url not in tmp_list:
                    tmp_list.append(pic_url)

            
            for pic_url in tmp_list:
                if pic_url.endswith('r.jpg'):
                    print(pic_url)
                    write_file(title, pic_url)

def write_file(title, pic_url):
    file_name = title + '.txt'

    f = open(file_name, 'a')
    f.write(pic_url + '\n')
    f.close()

示例结果:

下载图片

下面代码将读取文件中的图片地址并下载。


def read_file(title):
    file_name = title + '.txt'

    pic_urls = []

    # 判断文件是否存在
    if not os.path.exists(file_name):
        return pic_urls

    with open(file_name, 'r'as f:
        for line in f:
            url = line.replace("\n""")
            if url not in pic_urls:
                pic_urls.append(url)

    print("文件中共有{}个不重复的 URL".format(len(pic_urls)))
    return pic_urls

def download_pic(pic_urls, title):

    # 创建文件夹
    if not os.path.exists(title):
        os.makedirs(title)

    error_pic_urls = []
    success_pic_num = 0
    repeat_pic_num = 0

    index = 1

    for url in pic_urls:
        file_name = os.sep.join((title,basename(urlsplit(url)[2])))

        if os.path.exists(file_name):
            print("图片{}已存在".format(file_name))
            index += 1
            repeat_pic_num += 1
            continue

        try:
            urllib.request.urlretrieve(url, file_name)
            success_pic_num += 1
            index += 1
            print("下载{}完成!({}/{})".format(file_name, index, len(pic_urls)))
        except:
            print("下载{}失败!({}/{})".format(file_name, index, len(pic_urls)))
            error_pic_urls.append(url)
            index += 1
            continue
        
    print("图片全部下载完毕!(成功:{}/重复:{}/失败:{})".format(success_pic_num, repeat_pic_num, len(error_pic_urls)))

    if len(error_pic_urls) > 0:
        print('下面打印失败的图片地址')
        for error_url in error_pic_urls:
            print(error_url)

结语

今天的文章用 Python 爬虫制作了一个小脚本,如果小伙伴们觉得文章有趣且有用,点个 在看 支持一下吧!

——END——


Python自学超级硬核资料


Ps:这里都是视频学习资料,基础不好或者零基础的同学比较适合

最后送大家一份Python学习大礼包,从Python基础,爬虫,数据分析Web开发等全套资料,吃透资料,你可以扔掉其他资料,这些资料都是视频,学起来非常友好。



扫码加微信后备注「Python新手」方便我给你发送资料, 另外「Python绿色通道」专属学习群已正式成立,想进群也可扫上方二维码。





    
推荐阅读

  1. Windows有救了!这款免费工具终于来了

  2. 315曝光人脸识别?程序员可以这样避免信息泄露

  3. 漫画:为什么程序猿 996 会猝死,而企业家 007 却不会?

  4. 腾讯商业数据分析师培养计划!

  5. 知乎高赞:拼多多和国家电网,选哪个?

  6. 最新!字节跳动再次扩招1000人,招聘要求令人窒息


看完记得关注@Python绿色通道
及时收看更多好文
↓↓↓



点个在看你最好看



Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/110508
 
184 次点击