上一篇已经提到了实现单网页下载图片,本篇将继续讲解如何通过爬虫来实现全网站的下载。
任务分析:
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、明哥会陪着你陪你一起共同进步!
手打不易,有用的话,请记得关注转发。