zoukankan      html  css  js  c++  java
  • 爬取今日头条街拍美图

    爬取今日头条街拍美图

    一、项目需求

    1. 抓取今日头条街拍图片,并将每组图片储存到本地。

    2. 图片格式存储为jpg

    3. 每组图片用一个独立的文件夹储存

    二、项目分析

    目标URL为:https://www.toutiao.com/search/?keyword=街拍,如下截图:

    (注:如果图片看不清楚请右键点击图片通过新的标签打开)

     这里可以发现,目标URL是由ajax加载,然后用JavaScript渲染出来的。请求的参数有offset、format、keyword、autoload、count、cur_tab 和 from ,除了offset参数以外,其余的都是固定的参数(可以自行推理,拖动鼠标滚轮让下走则会继续发送ajax请求,再打开新的请求发现参数offset的值为20,第三个请求的offset值为40,也就是说,每次请求20组数据,其余的参数均不变)。再通过Preview选项卡观察data字段,会发现我们需要的数据就在这里面,以其中的一个为例:

    我们需要的图片url就在image_list中,而这组图片的标题则在title字段中:

    三、项目源码

    import requests
    from urllib.parse import urlencode
    import os
    from hashlib import md5
    from multiprocessing.pool import Pool
    
    
    def get_page(offset):
        """加载一个ajax请求的结果"""
        params = {
            'offset':offset,
            'format':'json',
            'keyword':'街拍',
            'autoload':'true',
            'count':'20',
            'cur_tab':'3',
            'from': 'gallery'
        }
        url = 'http://www.toutiao.com/search_content/?' + urlencode(params)
        try:
            response = requests.get(url)
            if response.status_code == 200:
                return response.json()
        except requests.ConnectionError:
            return None
    
    
    def get_images(json):
        """解析方法,提取每条数据的image_list字段中的图片链接,将图片链接和所属标题一同返回"""
        if json.get('data'):
            for item in json.get('data'):
                title = item.get('title')
                images = item.get('image_list')
                if images:
                    for image in images:
                        yield {
                            'image':image.get('url'),
                            'title':title
                        }
    
    
    def save_image(item):
        """保存图片方法,根据item中的title来创建文件夹,然后请求图片链接,获取图片的二进制数据,并写入文件。图片命名使用了md5"""
        if not os.path.exists(item.get('title')):
            os.mkdir(item.get('title'))
        try:
            local_image_url = item.get('image')
            new_image_url = local_image_url.replace('list','large')
            response = requests.get('http:' + new_image_url)
            if response.status_code == 200:
                file_path = '{0}/{1}.{2}'.format(item.get('title'),md5(response.content).hexdigest(),'jpg')
                if not os.path.exists(file_path):
                    with open(file_path,'wb') as f:
                        f.write(response.content)
                else:
                    print('Already Download',file_path)
        except requests.ConnectionError:
            print('Failed to Save Image')
    
    
    def main(offset):
        """主函数"""
        json = get_page(offset)
        for item in get_images(json):
            print(item)
            save_image(item)
    
    
    GROUP_START = 1
    GROUP_END = 5
    
    if __name__ == '__main__':
        pool = Pool()
        groups = ([x * 20 for x in range(GROUP_START,GROUP_END + 1)])
        pool.map(main,groups)
        pool.close()
        pool.join()
  • 相关阅读:
    MyBatisPlus乐观锁
    MyBatisPlus查询
    IDEA创建Java类时自动配置注释(作者,创建时间,版本等)
    MyBatisPlus自动填充处理
    Cannot read property '$createElement' of undefined
    IDEA中gradle的配置和使用
    android7.0以上https抓包
    转发unbuntu jdk 安装
    Unity 连接WebSocket
    Tween 使用
  • 原文地址:https://www.cnblogs.com/jonas-von/p/9198500.html
Copyright © 2011-2022 走看看