Python中如何抓取知乎某个问题下的所有图片?

初学 python,想到用这个练手,但是知乎的答案是动态加载的,每次网页滚动一定距离就会发送一个 POST 请求,当滚动到末尾的时候就会发送 GET 请求,加载新的内容,求思路,谢谢 TIM 截图 20180110103000.png


Python中如何抓取知乎某个问题下的所有图片?

10 回复

就是那个 GET 请求,一定有 offset, page 等参数。JSON 的多好处理


import requests
import json
import os
from urllib.parse import urljoin
import re

def fetch_zhihu_images(question_id, save_dir='zhihu_images'):
    """
    抓取知乎问题下的所有图片
    
    Args:
        question_id: 知乎问题ID(URL中的数字部分)
        save_dir: 图片保存目录
    """
    
    # 创建保存目录
    if not os.path.exists(save_dir):
        os.makedirs(save_dir)
    
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
        'Referer': f'https://www.zhihu.com/question/{question_id}'
    }
    
    # 知乎API端点
    base_url = f'https://www.zhihu.com/api/v4/questions/{question_id}/answers'
    
    offset = 0
    limit = 20
    total_images = 0
    
    while True:
        params = {
            'include': 'data[*].is_normal,content',
            'limit': limit,
            'offset': offset,
            'sort_by': 'default'
        }
        
        try:
            response = requests.get(base_url, headers=headers, params=params, timeout=10)
            response.raise_for_status()
            data = response.json()
            
            # 提取所有回答
            answers = data.get('data', [])
            if not answers:
                break
            
            for answer in answers:
                content = answer.get('content', '')
                
                # 使用正则表达式匹配图片URL
                # 匹配知乎的图片格式,包括原始图片和缩略图
                img_patterns = [
                    r'data-original="(https://pic\d\.zhimg\.com/[^"]+)"',  # 原始图片
                    r'data-actualsrc="(https://pic\d\.zhimg\.com/[^"]+)"',  # 实际图片
                    r'src="(https://pic\d\.zhimg\.com/[^"]+)"',  # 普通图片
                    r'https://www\.zhihu\.com/equation\?tex=([^"]+)'  # 公式图片(可选)
                ]
                
                for pattern in img_patterns:
                    img_urls = re.findall(pattern, content)
                    
                    for img_url in img_urls:
                        # 清理URL,去除查询参数获取原始图片
                        clean_url = img_url.split('?')[0]
                        
                        # 下载图片
                        try:
                            img_response = requests.get(clean_url, headers=headers, timeout=10)
                            img_response.raise_for_status()
                            
                            # 生成文件名
                            filename = os.path.join(save_dir, f'img_{total_images:04d}.jpg')
                            
                            # 保存图片
                            with open(filename, 'wb') as f:
                                f.write(img_response.content)
                            
                            print(f'已保存: {filename}')
                            total_images += 1
                            
                        except Exception as e:
                            print(f'下载失败 {clean_url}: {e}')
                            continue
            
            # 检查是否还有更多数据
            if data.get('paging', {}).get('is_end', True):
                break
                
            offset += limit
            
        except requests.exceptions.RequestException as e:
            print(f'请求失败: {e}')
            break
        except json.JSONDecodeError as e:
            print(f'JSON解析失败: {e}')
            break
    
    print(f'\n总共下载了 {total_images} 张图片')
    return total_images


# 使用示例
if __name__ == '__main__':
    # 从知乎问题URL中提取ID
    # 例如:https://www.zhihu.com/question/123456789
    question_id = '123456789'  # 替换为实际的问题ID
    
    # 调用函数下载图片
    fetch_zhihu_images(question_id)

这个脚本的工作原理:

  1. 获取问题ID:从知乎问题URL中提取数字ID
  2. 调用API:使用知乎的官方API获取问题下的所有回答
  3. 解析内容:从回答内容中提取图片URL
  4. 下载图片:下载并保存所有找到的图片

使用步骤:

  1. 安装依赖:pip install requests
  2. 替换question_id为你要抓取的问题ID
  3. 运行脚本,图片会保存在zhihu_images文件夹

注意事项:

  • 需要遵守知乎的robots.txt和使用条款
  • 建议添加适当的延迟避免请求过快
  • 知乎可能有反爬机制,可能需要处理验证码

核心要点: 通过官方API获取数据,用正则匹配图片链接。

python<br><a target="_blank" href="https://www.zhihu.com/api/v4/questions/265062021/answers?sort_by=default&amp;include=data" rel="nofollow noopener">https://www.zhihu.com/api/v4/questions/265062021/answers?sort_by=default&amp;include=data</a>[*].is_normal,admin_closed_comment,reward_info,is_collapsed,annotation_action,annotation_detail,collapse_reason,is_sticky,collapsed_by,suggest_edit,comment_count,can_comment,content,editable_content,voteup_count,reshipment_settings,comment_permission,created_time,updated_time,review_info,relevant_info,question,excerpt,relationship.is_authorized,is_author,voting,is_thanked,is_nothelp,upvoted_followees;data[*].mark_infos[*].url;data[*].author.follower_count,badge[?(type=best_answerer)].topics&amp;limit=20&amp;offset=23<br><br><a target="_blank" href="https://www.zhihu.com/api/v4/questions/265062021/answers?sort_by=default&amp;include=data" rel="nofollow noopener">https://www.zhihu.com/api/v4/questions/265062021/answers?sort_by=default&amp;include=data</a>[*].is_normal,admin_closed_comment,reward_info,is_collapsed,annotation_action,annotation_detail,collapse_reason,is_sticky,collapsed_by,suggest_edit,comment_count,can_comment,content,editable_content,voteup_count,reshipment_settings,comment_permission,created_time,updated_time,review_info,relevant_info,question,excerpt,relationship.is_authorized,is_author,voting,is_thanked,is_nothelp,upvoted_followees;data[*].mark_infos[*].url;data[*].author.follower_count,badge[?(type=best_answerer)].topics&amp;limit=20&amp;offset=63<br><br><br><a target="_blank" href="https://www.zhihu.com/api/v4/questions/265062021/answers?include=data" rel="nofollow noopener">https://www.zhihu.com/api/v4/questions/265062021/answers?include=data</a>[*].is_normal,admin_closed_comment,reward_info,is_collapsed,annotation_action,annotation_detail,collapse_reason,is_sticky,collapsed_by,suggest_edit,comment_count,can_comment,content,editable_content,voteup_count,reshipment_settings,comment_permission,created_time,updated_time,review_info,relevant_info,question,excerpt,relationship.is_authorized,is_author,voting,is_thanked,is_nothelp,upvoted_followees;data[*].mark_infos[*].url;data[*].author.follower_count,badge[?(type=best_answerer)].topics&amp;limit=20&amp;offset=83&amp;sort_by=default<br>
加载更多和 GET 请求末尾的 offset 有关,但是请求 URL 似乎不是固定的

不是固定 url 么 只是参数顺序变了而已吧 又没关系

最近刚好做了一个应用,不过我用的是 nodejs,爬取范围比楼主的稍微大点,一个话题下所有图片。

基于爬虫的应用,关键点其实不在于能爬到内容并解析,而是建立一个爬取体系,能够分步骤可靠并可控的爬取所需内容。具体到楼主这个需求,可以分几步:

1、找一款合适的知乎爬虫 sdk,研究下 api 参数,我用的是: https://github.com/shanelau/zhihu。
2、对于一个问题,第一次先爬取所有回答,后续用定时任务爬取更新的回答。
3、另起一个定时任务,解析每个回答中的文本信息,提取图片并保存。
4、另起一个定时任务,对图片进行后续处理。比如识别下是不是妹子什么的。

学习了,我之前都是全部自己写,没想到已经有轮子了这个前提

想法如出一辙 爬虫思路也是一样的 遇到的坑也是 哈哈

我发现有的图片加载不出来 这个是什么问题?比如这个 https://pic3.zhimg.com/0bea957c8c4c92cfd1713a62e55bbb28_r.jpg 直接访问也是只能加载部分,我看了下我扒下来的所有图片,不好图片都是这样的

回到顶部