2022(秋)实验三:爬虫图片

计211高璇 2022-12-08 22:54:37

1 实验目的

  1. 理解抓取网页的含义和URL基本构成;
  2. 掌握类和函数及模块的设计与实现;
  3. 掌握网络爬虫原理。

2 实验内容

本实验将利用python程序抓取网络图片,完成可以批量下载一个网站的照片。所谓网页抓取,就是把URL地址中指定的网络资源从网络流中读取出来,保存到本地。

3 实验知识点

  1. Python基本语法;
  2. 网络爬虫基本原理;
  3. 解析HTML页面及URL;
  4. 爬取Web页面;
  5. 使用正则表达式提取关键信息对内容进行过滤。

4 实验时长

    8学时。

5 实验环境

  1. python3;
  2. Spyder。

6 实验过程

6.1 原理探究

1、网络爬虫

    即Web Spider,网络蜘蛛是通过网页的链接地址来寻找网页的。从网站某一个页面(通常是首页)开始,读取网页的内容,找到在网页中的其它链接地址,然后通过这些链接地址寻找下一个网页,这样一直循环下去,直到把这个网站所有的网页都抓取完为止。

网络爬虫的基本操作是抓取网页。

2、浏览网页过程

    抓取网页的过程其实和读者平时使用浏览器浏览网页的道理是一样的。打开网页的过程其实就是浏览器作为一个浏览的“客户端”,向服务器端发送了 一次请求,把服务器端的文件“抓”到本地,再进行解释、展现。浏览器的功能是将获取到的HTML代码进行解析,然后将原始的代码转变成我们直接看到的网站页面。

    URL的格式由三部分组成: 

  • 第一部分是协议(或称为服务方式)。
  • 第二部分是存有该资源的主机IP地址(有时也包括端口号)。
  • 第三部分是主机资源的具体地址,如目录和文件名等。

    第一部分和第二部分用“://”符号隔开,

    第二部分和第三部分用“/”符号隔开。

    第一部分和第二部分是不可缺少的,第三部分有时可以省略。

    爬虫最主要的处理对象就是URL,它根据URL地址取得所需要的文件内容,然后对它 进行进一步的处理。

    因此,准确地理解URL对理解网络爬虫至关重要。

 

3、利用urllib2通过指定的URL抓取网页内容

    在Python中,我们使用urllib2这个组件来抓取网页。
    urllib2是Python的一个获取URLs(Uniform Resource Locators)的组件。

    它以urlopen函数的形式提供了一个非常简单的接口。

 

4、HTTP的异常处理问题

    当urlopen不能够处理一个response时,产生urlError。
    不过通常的Python APIs异常如ValueError,TypeError等也会同时产生。
    HTTPError是urlError的子类,通常在特定HTTP URLs中产生。

 

5、Timeout 设置(超时设置)

    在Python2.6前,urllib2 的 API 并没有暴露 Timeout 的设置,要设置 Timeout 值,只能更改 Socket 的全局 Timeout 值。在 Python 2.6 以后,超时可以通过 urllib2.urlopen() 的 timeout 参数直接设置。

6.2 项目结构

    项目包含两个文件,pet_spider.py和main_file.py。其中pet_spider.py文件定义了类PetSpider,包含3个方法分别是get_html_content下载网页源代码、get_urls获得网页图片urls、 download_images下载图片。main_file.py文件定义了主函数main,用于调用PetSpider类。

6.3 根据给定的网址来获取网页源代码

    根据给定的网址来获取网页详细信息,得到的html就是网页的源代码。

    get_html_content函数主要功能是递归下载网页源代码。注意将byte类型转换成string类型,其中re.findall的含义是返回string中所有与pattern(正则表达式)相匹配的全部字串,返回形式为数组。

    新建pet_spider.py。

    首先实现获取网页源代码的函数:

# import libraries
import requests
import re
import os
 
# define class
class PetSpider():
    
    def __init__(self, image_path, html_path, url_path):
        self.image_path = image_path
        self.html_path = html_path
        self.url_path = url_path
    
    # get webpages
    def get_html_content(self, url, url_prefix):
        r = requests.get(url, timeout=60)
        page_content = r.content.decode('utf-8')
        page_div=re.compile(r'<div class="page">(.*?)</div>',re.I|re.S|re.M).findall(page_content)
        if page_div:
            current_page = re.compile(r'<a class ="current" href="javascript:void\(0\);">(.*?)</a>',re.I|re.S|re.M).findall(page_div[0])
            if current_page:
                html_file_name = '%s/web_page_%s.txt' %(self.html_path, current_page[0])
                print('downloading %s' %(html_file_name))
                f = open(html_file_name, "wb")
                f.write(r.content)
                f.close()
            else:
                print('current_page not found')
            next_url = re.compile(r'<a class="next" href="(.*?)">&raquo;</a>',re.I|re.S|re.M).findall(page_div[0])
            if next_url:
                next_url = url_prefix +next_url[0]
                self.get_html_content(next_url, url_prefix)
            else:
                if current_page:
                    print('download over')
                else:
                    print('next_url not found')
        else:
            print('page_div not found')

6.4 从网页源代码中过滤所有图片urls

    获取网页源代码后,从网页源代码中匹配过滤图片的urls,制作进度条,从文件中读出网页图片内容,最后将所有urls写入文件。

    继续向pet_spider.py文件中添加如下代码:

# get urls from webpages
    def get_urls(self):
        url_content = ''
        
        for _, _, file_list in os.walk(self.html_path):
            pass
        
        file_count = len(file_list)
        counter = 1
        
        for i in file_list:
            file_name = '%s/%s' %(self.html_path, i)
            print('extracting urls from %s. %d/%d' %(file_name, counter, file_count))
            
            f = open(file_name, "rb")
            page_content = f.read().decode('utf-8')
            f.close()
            
            urls = re.compile(r'<img src="(.*?)" />',re.I|re.S|re.M).findall(page_content)
            if urls:
                for i in urls:
                    if i.find('alt') >=0:
                        continue
                    url_content += i
                    url_content += '\n'
            else:
                print('url not found')
            
            counter += 1
        
        # write urls into file
        f = open('%s/urls.txt' %(self.url_path), "wb")
        f.write(bytes(url_content, encoding='utf8'))
        f.close()

6.5 将图片下载保存在本地

    将图片下载到本地,首先将urls字符串保存到列表中,遍历列表中的urls,将下载的图片保存在文件中。

    继续向pet_spider.py文件中添加如下代码:

# download images
    def download_images(self):
        rows = open('%s/urls.txt' %(self.url_path)).read().split("\n")
        current_image_number = 1
        urls_count = len(rows)
 
        for url in rows:
            try:
                # try to download the image
                r = requests.get(url, timeout=60)
                # save the image to disk
                image_file = '%s/img_%d.jpg' %(self.image_path, current_image_number)
                f = open(image_file, "wb")
                f.write(r.content)
                f.close()
                
                print('download %s. %d/%d' %(image_file, current_image_number, urls_count))
                
                current_image_number += 1
            except:
                print('%s has an exception. skip.' %(url))

6.6 主函数

    新建main_file.py文件。代码如下:

import os
from pet_spider import PetSpider
 
if __name__ == '__main__':  
    url = 'http://pet.lelezone.com/mao/'
    url_prefix = 'http://pet.lelezone.com'
    image_path = 'cats'
    html_path = 'html'
    url_path = 'url'
    
    if not os.path.isdir(image_path):
        os.makedirs(image_path)
    if not os.path.isdir(html_path):
        os.makedirs(html_path)
    if not os.path.isdir(url_path):
        os.makedirs(url_path)
    
    pet_spider = PetSpider(image_path, html_path, url_path)
    print('Download webpages.')
    pet_spider.get_html_content(url, url_prefix)
    print('Extract urls.')
    pet_spider.get_urls()
    print('Download images')
    pet_spider.download_images()

最后运行主函数实现图片爬虫。

7.总结

        本次实验中,我们主要学习了爬虫的相关知识,学习如何利用爬虫技术获取网页中的图片,但是最终由于所给的网址无法打开,所以最终没有运行成功。但我们通过实验,了解了一些通过爬虫获取网页中的图片的相关方法,例如我们可以运用 get_html_content函数递归下载网页源代码以及通过从网页源代码中过滤所有图片urls等内容,同时通过学习和深入了解爬虫技术,我们确实体会到了爬虫技术的功能之强大和便捷,不仅在学习上,在生活和工作的许多方面我们都可以利用使用爬虫技术解决问题。虽然此次试验中最终没有运行成功,但通过实验练习,我们掌握了爬虫的方法,在之后的学习和生活中,也可以利用此项技术为我们提供许多便捷。

...全文
42 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
C3333_C343223 2023-01-03
  • 打赏
  • 举报
回复

很不错的内容,干货满满,已支持师傅,期望师傅能输出更多干货,并强烈给师傅文章点赞

另外,如果可以的话,期待师傅能给正在参加年度博客之星评选的我一个五星好评,您的五星好评都是对我的支持与鼓励:https://bbs.csdn.net/topics/611387568

点赞五星好评回馈小福利:抽奖赠书 | 总价值200元,书由君自行挑选(从此页面参与抽奖的同学,只需五星好评后,参与抽奖)

163

社区成员

发帖
与我相关
我的任务
社区描述
软件工程老师
python 高校 江苏省·南通市
社区管理员
  • juking@ntu
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧