zoukankan      html  css  js  c++  java
  • 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")
  • 相关阅读:
    7.21 高博教育 数组 内存
    【基础扎实】Python操作Excel三模块
    PAT 甲级 1012 The Best Rank
    PAT 甲级 1011  World Cup Betting
    PAT 甲级 1010 Radix
    链式线性表——实验及提升训练
    循环程序设计能力自测
    链表应用能力自测
    PAT 甲级 1009 Product of Polynomials
    1008 Elevator (20分)
  • 原文地址:https://www.cnblogs.com/xiaobai-2017/p/8431220.html
Copyright © 2011-2022 走看看