• python3 BeautifulSoup爬取网页的图片


      爬取网页的标题或者图片,方法可以使用正则,这个并不推荐,因为很多情况下匹配有误。今天来总结一下BeautifulSoup方法爬取网页中的图片。

      参考原网址:http://www.testclass.net/crawler/get_images/

     前提条件:1.python3 环境  2.安装requests库 3.安装 beautifulsoup4  (2和3 以管理员方式运行cmd 用pip指令安装就ok,这里不详细介绍)

    我这里将原网址的代码搬了过来,加上了注释

    import requests
    from bs4 import BeautifulSoup
    
    url = 'http://jandan.net/drawings'
    header ={'user-agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0'}
    html = requests.get(url,headers=header).text
    # BeautifulSoup 对象是基于一个html字符串或者一个文件
    # 使用html.parser解析器 进行解析
    soup = BeautifulSoup(html, 'html.parser')
    
    
    # 筛选有效的jpg
    def valid_img(src):
        return src.endswith('jpg') and 'img.jandan.net' in src
    
    # 下载图片
    def download_file(url):
        # print('Downloading %s' %url)
        local_filename = url.split('/')[-1]
        # print('file_name:', local_filename)
        # filename like xxx.jpg
        r = requests.get(url, stream=True, headers=header)
        with open(local_filename, 'wb') as f:
            for chunk in r.iter_content(chunk_size=1024):
                if chunk:
                    f.write(chunk)
                    # 文件方法 将缓冲区文件立即写入文件
                    f.flush()
    
    
    for img in soup.find_all('img', src= valid_img):
        src = img['src']
        # print('src is',src)
        if not src.startswith('http'):
            src ='http:' + src
        download_file(src)
    
    

    '''我们来探讨r = requests.get(url, stream=True, headers=header)中的stream参数stream=True时,连接connection不会被返回放入到连接池中去除非你读取完requests中所有的数据或者直接调用Requests.close()方法。这必然导致连接的效率很低,当只需要响应的正文部分(或者什么都不需要读取)好消息 - 归功于urllib3,同一会话内的持久连接是完全自动处理的!同一会话内你发出的任何请求都会自动复用恰当的连接!只有所有的响应体数据被读取完毕连接才会被释放为连接池;所以确保将 stream设置为 False 或读取 Response 对象的 content 属性。'''

    可以看到 一般做这种爬虫的步骤:

    1.打开网页,读取网页的源码

    2.分析要爬取的图片的HTML,查找规律,一步步提取图片url

    3.根据图片的url将图片保存到指定的位置

    结果: 图片被保存到了当前目录中

    我们接下来介绍将图片保存到指定位置的另外一种写法

    urllib.request.urlretrive(img_url, file_path) 但是有的网站做了防爬,这个函数报403错误

    没办法,我们只能添加头部模仿浏览器去访问图片的url,然后获取图片

    import requests, os
    from bs4 import BeautifulSoup
    import urllib.request
    
    def jandan_img(path):
        url = 'http://jandan.net/drawings'
        header ={'user-agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0'}
        html = requests.get(url,headers=header).text
        soup = BeautifulSoup(html, 'html.parser')
        img_list = soup.find_all('img', src=valid_img)
        # 创建文件夹
        download_file(path)
        for img in img_list:
            src = img['src']
            # print(src)
            if not src.startswith('http'):
                src = 'http:' + src
            img_name = src.split('/')[-1]
            file_name = path + '\' + img_name
            # print(src)
            # urllib.request.urlretrieve(src, file_name)
            # 如果不用头部伪装 返回403
            html = requests.get(src, headers=header)
            # print(html)
            with open(file_name, 'wb') as f:
                f.write(html.content)
    
    # 筛选有效的jpg
    def valid_img(src):
        return src.endswith('jpg') and 'img.jandan.net' in src
    
    # 创建文件夹
    def download_file(path):
        try:
            if not os.path.exists(path):
                os.mkdir(path)
        except Exception as msg:
            print(msg)
    
    
    if __name__ == '__main__':
        jandan_img('E:\image')

    requests的用法 参考网址:https://www.cnblogs.com/guhao123/p/4054177.html

    beautifulsoup的解释器参考网址:http://blog.csdn.net/u013007900/article/details/54706336

    -------------------------------------------------------------------------------------------------------------------------------------------------------

    下面附一个略复杂的例子如下:

    # 程序说明:url ='http://bbs.zol.com.cn/dcbbs/d15_108727.html'
    # 程序说明:抓取该url下的所有图片,注意放到文件名称为:帖子标题下的目录中
    
    # coding = 'utf-8'
    import urllib
    import os, requests
    from urllib import request
    from bs4 import BeautifulSoup
    
    def get_allImage(url):
        # 打开网页
        res = requests.get(url)
        res.encoding = 'gb18030'
        # print(res)
        # 获取图片
        soup = BeautifulSoup(res.text, 'html.parser')
        # 获取标签之间的文字 用作分类的文件夹名字
        post_title = soup.title.string
        # 要获取的图片上层的div标签,这个网页有些特殊,它所有的放在一起
        post_div = soup.find(attrs={"id": "bookContent"})
        return post_div.find_all('img'), post_title
        # print(imgs)
        # for img in imgs:
        #     img_src = img.get('data-original')
        #     print(img_src)
        # # return img
    
    
    # 保存图片到指定的路径
    def save_img(url, file_path):
        images, folder_name = get_allImage(url)
        print(folder_name)
        file_path = file_path + "\" + folder_name
        # 文件序号
        file_seq = 1
        # 判断路径是否存在
        try:
            if not os.path.exists(file_path):
                print('文件夹不存在,重新建立')
                os.mkdir(file_path)
            for img in images:
                img_src = img.get('data-original')
                # 获取文件的后缀名
                # print(img_src)
                file_suffix = img_src.split('.')[6]
                # print(file_suffix)
                # 拼接图片名 目标路径+文件分隔符+图片名+文件后缀
                filename = '{}{}{}{}'.format(file_path, os.sep, file_seq, '.%s' % file_suffix)
                # print(filename)
                # 下载图片,并保存到文件夹中
                urllib.request.urlretrieve(img_src, filename)
                file_seq += 1
        except Exception as e:
            print("文件操作失败", e)
    
    
    if __name__ == "__main__":
        save_img("http://bbs.zol.com.cn/dcbbs/d15_108728.html", "E://image")
  • 相关阅读:
    SpringMVC 中整合之JSON、XML
    解决Django扩展用户表后新表内增加用户密码存储为明文
    python之路:始解(四)
    python作业:select版本FTP
    python作业:高级FTP程序
    python归档:笔记转化
    python之路:始解(三)
    python之路:始解(二)
    python作业:FTP程序
    python文件操作:pickle模块多次dump后出现的读取问题
  • 原文地址:https://www.cnblogs.com/xiaobai-2017/p/8431220.html
Copyright © 2020-2023  润新知