上一节的爬虫实战我们讲到了使用单线程的方法爬取王者的高清壁纸,并且做了一个案例就是爬取美女图片的小案例,但是我们主要讲解的是使用多线程完成爬虫任务,于是我们这一节课,讲述如何使用threading多线程爬取王者高清壁纸。
前面操作请看我们之前使用单线程爬取壁纸的案例,这一节我们就不做过多介绍。
首先我们理清爬取思路,首先我们要定义两个类,一个是生产者producter,一个是消费者consumer。然后使用生产者队列来存储从网页上获取下来的照片的url,并且完成规范化。并且把含有文件名的文件进行创建。然后我们使用消费者进行下载并且保存到所属文件当中,mian函数进行翻页,并且给出消费者和生产者的队列范围。
有了这个思路我们直接进入代码:
import queue
import requests#请求网站
from urllib import parse#解析库
import os#文件操作库
from urllib import request#用来下载
headers={
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36",
"Referer": "https://pvp.qq.com/web201605/wallpaper.shtml"}#其中referer是指上一个页面是哪个,这里我们为了避免被反爬虫,所以我们进行了这个的添加。
class producter(threading.Thread):
def __init__(self,page_queue,image_queue,*args,**kwargs):
super(Producer, self).__init__(*args,**kwargs)
self.page_queue=page_queue
self.image_queue=image_queue
def run(self) -> None:
while not self.page_queue.empyt():#当页面列表不空的时候
page_url=self.page_quequ.get()#取出网址,对应下方主函数的url,从主函数中取出来
resp=requests.get(page_url,headers=headers)
result=resp.json()#进行json解析
datas=result['List']#这里不懂请看之前的单线程,就是从解析的代码中,找到这个list类
for data in datas:
image_urls=explanin_data(data)#将网址进行提取,看下方相应函数。
name=parse.unquote(data['sProdName']).replace("1:1", "").strip()#将1:1替换成空,并且消除空格。
dir_path=os.path.join("images",name)
if not os.path.exists(dir_path):#如果文件名不存在 则创建
os.mkdir(dir_path)
for index,image_url in enumerate(image_urls):
self.image_queue.put({
"image_url":image_url,"image_path":os.path.join(dir_path,'%d.jpg'%(index+1))})
#这里将每一张图的网址放到了image_queue中,并且对照片进行了命名
class Consumer(threading.Thread):
def __init__(self,image_quene,*args,**kwargs):
super(Consumer, self).__init__(*args,**kwargs)
self.image_quene=image_quene
def run(self) -> None:
while True:
try:
image_obj=self.image_quene.get(timeout=10)#会报错 超过10秒
image_url=image_obj.get("image_url")
image_path=image_obj.get("image_path")
try:
request.urlretrieve(image_url,image_path)
print(image_path+"下载完成!")
except:
print(image_path+"下载失败!")
except:
break
#消费者行为主要完成了下载部分代码的书写,使用try和except来定义异常
def explanin_data(data):
image_urls=[]
for x in range(1,9):
image_url= parse.unquote(data['sProdImgNo_%d'%x]).replace('200','0')
image_urls.append(image_url)
return image_urls
def main():
page_quene=queue.Queue(18)
image_quene=queue.Queue(1000)
for page in range(0,18):
page_url=f'https://apps.game.qq.com/cgi-bin/ams/module/ishow/V1.0/query/workList_inc.cgi?activityId=2735&sVerifyCode=ABCD&sDataType=JSON&iListNum=20&totalpage=0&page={
page}&iOrder=0&iSortNumClose=1&iAMSActivityId=51991&_everyRead=true&iTypeId=2&iFlowId=267733&iActId=2735&iModuleId=2735&_=1649850019827'
page_quene.put(page_url)
for i in range(3):
th=Producer(page_quene,image_quene,name='生产者%d号'%i)
th.start()
for x in range(5):
th=Consumer(image_quene,name='消费者%d号'%x)
th.start()
if __name__ == '__main__':
main()
这就完成了我们对于王者高清壁纸多线程下载的全部过程。
最后我们来看一下最后下载之后的样子:
谢谢各位大佬的观看,给弟弟点个赞再走吧!!!如果关注我就更好啦,会有跟多的精彩内容呈现哒