zoukankan      html  css  js  c++  java
  • 爬虫学习笔记:微信公众号文章图片下载

    一、背景知识

    最近看微信公众号,发现很多有趣的图片,又不想一一保存,遂产生通过 python 爬虫的方式直接一次性解析保存。

    在此过程中,使用到rerequestsosbs4.BeautifulSouptimePIL 等多个库,算是综合使用了一下。

    有所收获。

    二、整体思路

    • 分析网页源代码
    • 获取图片的 URL
    • 根据 URL 保存下载
    • 根据图片分辨率进行二次过滤

    三、具体分析

    1.标题

    标题存放在 <h1 class> 标签之下,使用 bs.select 即可获取。

    2.图片

    图片存放在 img 标签之下,对应的 URL 存放在 data-src 字段。

    图片路径通过 os.path.exists() 判断是否存在。

    图片内容通过 requests.get(url).content 进行下载保存。

    四、实操

    1.准备工作

    import re
    import requests
    import os
    from bs4 import BeautifulSoup
    import urllib
    import time
    from PIL import Image
    
    # 头部文件
    headers = {
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36', 'Connection': 'close'
    }
    

    2.请求网站

    # 待爬取网站
    url = r'https://mp.weixin.qq.com/s/zyxFlgm_th1KGWwsEylCVQ' # 我今天非得跟你玩
    url = r'https://mp.weixin.qq.com/s/xgwt2ujb1AD_d3_iWhLP2Q' # 这些年,我们看过的那些媛们!
    
    # 请求
    response = requests.get(url, headers=headers)
    print(response.status_code) # 200 代表正常返回
    response.raise_for_status() # 如果异常抛出错误
    

    3.bs4解析标题

    # bs4解析
    bs = BeautifulSoup(response.text, 'html.parser')
    title = bs.select('h1')[0].text.strip()
    # title = bs.find_all('h1')[0].text.strip()
    
    # 过滤标题中的中文
    title = re.findall('[\u4e00-\u9fa5a-zA-Z0-9]+', title, re.S)
    title = '-'.join(title)
    

    4.图片解析

    # 第1种解析方式
    imglist = []
    for img in bs.select('img'):
        if 'data-src' in img.attrs:
            imglist.append(img['data-src'])
    
    # 第2种解析方式
    imglist2 = []
    imgs = bs.find_all('img', attrs={'data-type':'gif'})
    if imgs is not None:
        for img in imgs:
            print(img['data-src'])
            imglist2.append(img['data-src'])
    

    5.路径生成

    # 判断路径是否存在
    path = r'C:\Users\Hider\Desktop\图片'
    if not os.path.exists(path):
        os.mkdir(path)
    
    if not os.path.exists(os.path.join(path, title)):
        os.mkdir(os.path.join(path, title))
    

    6.图片下载

    # 第1种方式下载图片
    num = 0
    for jpg_url in imglist:
        result = requests.get(jpg_url, headers=headers).content
        f = open(os.path.join(path, title, str(num+1) + '.gif'), 'wb')
        f.write(result)
        f.close()
        num += 1
        print(f'正在下载第{num}张...')
        time.sleep(1)
    
    # 第2种方式下载图片
    path = r'C:\Users\Hider\Desktop\图片'
    for jpg_url in imglist:
        try:
            picture_name = jpg_url.split('/')[-2]
            fmt = jpg_url.split('=')[-1]
            result = requests.get(jpg_url, headers=headers).content
            with open(path + '\\' + title + '\\' + picture_name + '.' + fmt, 'wb+') as f:
                f.write(result)
        except Exception as reason:
            print(str(reason))
            
    # 第3种方式下载图片 -- 好像快很多!!!
    path = r'C:\Users\Hider\Desktop\图片'
    for jpg_url in imglist:
        try:
            picture_name = jpg_url.split('/')[-2]
            fmt = jpg_url.split('=')[-1]
            # urllib.request.urlretrieve(jpg_url, '{0}{1}.gif'.format(path, picture_name))
            urllib.request.urlretrieve(jpg_url, path + '\\' + title + '\\' + picture_name + '.' + fmt)
        except Exception as reason:
            print(str(reason))
    

    7.图片过滤

    # 过滤图片
    file_list = os.listdir(os.path.join(path, title))
    for file in file_list:
        if file.split('.')[-1] == 'gif':
            filename = os.path.join(path, title, file)
            img = Image.open(filename)
            imgSize = img.size
            img.close()
            # print(imgSize)
            if imgSize[0] > 700 and imgSize[1] > 700:
                pass
                # print(imgSize)
            else:
                os.remove(filename) # 删除文件
                print(file)
    

    五、封装函数

    import re
    import requests
    import os
    from bs4 import BeautifulSoup
    import urllib
    import time
    from PIL import Image
    
    def wechat_picture_download(url, path):
        # 头部文件
        headers = {
            'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36', 'Connection': 'close'
        }    
        # 请求
        response = requests.get(url, headers=headers)
        print(response.status_code) # 200 代表正常返回
        response.raise_for_status() # 如果异常抛出错误
        # bs4解析
        bs = BeautifulSoup(response.text, 'html.parser')
        title = bs.select('h1')[0].text.strip()
        # title = bs.find_all('h1')[0].text.strip()    
        # 过滤标题中的中文
        title = re.findall('[\u4e00-\u9fa5a-zA-Z0-9]+', title, re.S)
        title = '-'.join(title)
        # 解析
        imglist = []
        for img in bs.select('img'):
            if 'data-src' in img.attrs:
                imglist.append(img['data-src'])
        # 判断路径是否存在
        if not os.path.exists(path):
            os.mkdir(path)
        if not os.path.exists(os.path.join(path, title)):
            os.mkdir(os.path.join(path, title))
        num = 0
        for jpg_url in imglist:
            try:
                # urllib.request.urlretrieve(jpg_url, '{0}{1}.gif'.format(path, picture_name))
                print('正在下载:', str(num+1) + '.gif')
                urllib.request.urlretrieve(jpg_url, os.path.join(path, title, str(num+1) + '.gif'))
                time.sleep(1)
                num += 1
            except Exception as reason:
                print(str(reason))
        print('-'*10,'全部下载完成!!','-'*10)
        # 过滤图片
        file_list = os.listdir(os.path.join(path, title))
        for file in file_list:
            if file.split('.')[-1] == 'gif':
                filename = os.path.join(path, title, file)
                img = Image.open(filename)
                imgSize = img.size
                img.close()
                # print(imgSize)
                if imgSize[0] > 100 and imgSize[1] > 100:
                    pass
                    # print(imgSize)
                else:
                    os.remove(filename) # 删除文件
                    print('正在删除:', file)
        print('-'*10,'过滤完成!!','-'*10)
        return True
                
              
    # 待爬取网站
    # url = r'https://mp.weixin.qq.com/s/zyxFlgm_th1KGWwsEylCVQ' # 我今天非得跟你玩
    url = r'https://mp.weixin.qq.com/s/xgwt2ujb1AD_d3_iWhLP2Q' # 这些年,我们看过的那些媛们!
    path = r'C:\Users\Hider\Desktop\图片'
    
    wechat_picture_download(url, path)  
    

    参考链接:Python 判断文件夹是否存在(OS)

    参考链接:抓取微信公众号文章中的图片

    参考链接:python爬虫之爬取微信公众号文章中的图片

  • 相关阅读:
    maven管理jar,pom.xml导入spring依赖
    三分钟明白 Activiti工作流 -- java运用
    Java框架之spring—jdbcTemplate
    Activiti BPMN 2.0 designer eclipse插件安装
    eclipse离线安装Activiti Designer插件
    eclipse oxygen离线安装activiti
    使用spring注解——定义bean和自动注入
    web.config中配置数据库连接的两种方式
    Java的三种代理模式
    03 Spring框架 bean的属性以及bean前处理和bean后处理
  • 原文地址:https://www.cnblogs.com/hider/p/15761004.html
Copyright © 2011-2022 走看看