爬虫实战:一键爬取指定网站所有图片(二)

前言:

​ 上一篇已经提到了实现单网页下载图片,本篇将继续讲解如何通过爬虫来实现全网站的下载。

任务分析:

​ 1、已实现指定某一网页的图片下载

​ 2、通过获取页面的url,进行href元素值的读取,并写入到下一个Job当中,并执行读出。

直接进入题:

这次的功能其实比较简单,只用通过xml的值,采用xpath的方式进入读取就行了。

上一篇我们定义了一个DownloadImage类,这次我们新建一个download_image.py文件,当然,这次文件不用在其它文件中调用,所以直接放到了执行脚本当中,我们定义一个类,这个类当中包含几个属性:

1、待下载的url,我们定义为ready_list,已处理完的url,定义为finish_list,类型都为set()。即然是url,那么我们的头信息必不可少,好了,直接上代码:

class ImageList(object):
    finish_list = set()
    ready_list= set()

    headers = {
        # 用户代理
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'
    }
    def __init__(self):
    		pass
}

思路:

1、每次访问一个Url,我们将列表从待处理列表中移出,写入到已处理的列表。

2、继续读取页面中的内链,判断内链在待处理的和已处理的列表中是否存在,如果不在,那么加入到待处理当中。如果已存在,则不处理,

3、将这个页面推送给DownloadImage类进行图片采集。

先上代码:

import argparse
from DownloadImage import DownloadImage
from lxml import etree as et
from urllib.parse import *
import requests
import os
class ImageList(object):
    finish_list = set()
    ready_list= set()

    headers = {
        # 用户代理
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'
    }
    def __init__(self,url,runCount=20):
        self.runCount=int(runCount)
        self.start=0
        self.url = url
        self.urlParse=urlparse(self.url)
        self.ready_list.add(url)
    def run(self):
        while len(self.ready_list)>0:
            url = self.ready_list.pop()
            self.ready_list.discard(url)
            self.getUrls(url)
            self.downloadImage(url)
        #
    def getUrls(self,url):
        response = requests.get(url, headers=self.headers)
        if(response.status_code==200):
            html = et.HTML(response.text)
            urls = html.xpath('//a/@href')
            for newUrl in urls:
                if not self.isRootUrls(urljoin(self.url,newUrl)):
                    continue
                if newUrl not in self.ready_list and newUrl not in self.finish_list:
                    self.ready_list.add(urljoin(self.url,newUrl))
    def downloadImage(self,url):
        #执行download_page
        obj = DownloadImage(url, None)
        # 过滤格式
        obj.run()
        self.start =self.start+1
        #判断是否为同一域名下
    def isRootUrls(self,url):
        newUrl=urljoin(self.url,url)
        urlp=urlparse(newUrl)
        if urlp.netloc == self.urlParse.netloc:
            return True
        else:
            return False

直接解读代码:

Self.runCount,控制页面的处理次数,因为如果页面较多,将进入死循环。这里只是简单控制了一下,代码还待优化。

self.getUrls 读取页面中所有的url列表,按逻辑判断是否加入到reday_list列表当中

self.isRootUrls 判断是否内链,如果不加此行,会成外链爬虫,程序会无限读取。

self.downloadImage ,启动单页图片下载脚本

self.run 循环器,判断ready_list是否存在,如果存在,继续执行,直到网站中无新链接进来。

相信有爬虫基础的一眼能看明白。

但是,这里面存在几个问题,因为时间的关系,和我自己本身的诉求,我未进行修复。

1.采集的URL未进行持久化保存,在结束进程后,下一次会重新采集

2.对与图片采集记录也没有进行持久化保存

3.循环一开始,会出现线程锁死,如果并发太多,无法直接结束进程

4.未实现多线程的控制

以上几点我后面有时间会再进行优化处理。只是对爬虫的处理方案进行了说明,希望对大家有所帮助,如果有什么问题可以留言咨询。

代码地址:https://gitee.com/python_play/download_image

本文是“明哥陪你学Python”系列章节之一,如果你对Python有更多兴趣,或有问题,可以私信与明哥联系,我会陪你一起解决,其它相关章节可以从首页中的“明哥陪你学Python”列表进行查看。

本系列教程及源码地址:点击访问

最后:如果你正在学习Python的路上,或者准备打算学习Python、明哥会陪着你陪你一起共同进步!

手打不易,有用的话,请记得关注转发。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章