想要更多爬虫示例吗,还等什么呢,关注微信公众号“木下学Python”获取把~
从 360图片网站 下载 1000 张图片,一下是没用多进程,多线程下载所使用的时间
使用多进程,多线程后,所使用的时间, 在加了多进程,多线程的代码后面都加了一个 # 标注
代码:
spiderMan.py 为主逻辑运行接口
spiderMan.py:
from urlManager import urlManager
from htmlDownload import htmlDownload
from parseHtml import parseHtml
from dataOutput import dataOutput
from multiprocessing import Pool #
import json
import time
class spipderMan():
"""
主逻辑
"""
def __init__(self):
"""
初始化各个模块
"""
self.manager = urlManager()
self.download = htmlDownload()
self.parse = parseHtml()
self.output = dataOutput()
def get_url(self):
"""
获取每一页的 url, 在这里添加多进程进行请求 url
:return:
"""
page_urls = self.manager.create_url()
p = Pool() # # 创建进程池
for page_url in page_urls:
p.apply_async(self.request_url,args=(page_url,)) # #添加进程任务,page_url 为传进去的进程任务的参数
p.close() # # 不再添加新进程
p.join() # # 等待所有子进程执行完毕,调用之前必须先调用 close(),针对 Pool 对象
def request_url(self,page_url):
"""
请求每一页的 url
:return:
"""
# 此处的循环放到上一个函数了
response = self.download.request_url(page_url)
# 判断是否请求成功
if response == None:
print('访问网页失败,可能被反爬或网络出问题了噢~')
# 判断是否是最后一页
html = json.loads(response.text)
if html['end'] != False:
print('没有更多图片了,下载完毕!')
else:
self.get_img_url(html)
def get_img_url(self,html):
"""
解析获取每一页所有图片的 url
:return:
"""
img_urls = self.parse.get_this_page_img_urls(html)
self.get_img(img_urls)
def get_img(self,img_urls):
"""
下载图片
:return:
"""
self.output.download_img(img_urls)
if __name__ == '__main__':
# 运行主接口
start_time = time.time()
spider = spipderMan()
spider.get_url()
end_time = time.time()
print(end_time - start_time)
urlManager.py:
class urlManager():
"""
管理 url
"""
def __init__(self):
"""
初始化需要拼接的 url
"""
self.base_url = 'http://image.so.com/zj?ch=beauty&sn={}&listtype=new&temp=1'
def create_url(self):
"""
构造每一页的 url
:return:
"""
urls = [self.base_url.format(str(i)) for i in range(0,1020,30)]
return urls
htmlDownload.py:
import requests
import random
class htmlDownload():
"""
网页下载
"""
def __init__(self):
"""
初始化请求头
"""
USER_AGENTS = [
"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:16.0) Gecko/20100101 Firefox/16.0",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11",
"Mozilla/5.0 (X11; U; Linux x86_64; zh-CN; rv:1.9.2.10) Gecko/20100922 Ubuntu/10.10 (maverick) Firefox/3.6.10"
]
self.headers = {'User-Agent' : random.choice(USER_AGENTS)}
def request_url(self,url):
"""
请求
:param url:
:return:
"""
response = requests.get(url,self.headers)
if response.status_code == 200:
return response
else:
return None
parseHtml.py:
class parseHtml():
"""
解析网页,提取数据
"""
def __init__(self):
self.img_urls = [] # 存储图片标题和 url 的列表
def get_this_page_img_urls(self,html):
"""
获取此页图片的 url
:param html:
:return: 存储图片 url 的列表
"""
# 打印当前下载了多少图片,先判断是否访问成功,成功就打印
if html['list']:
img_count = html['lastid'] - 30
print('当前已下载 {} 张,有误差,同名的会过滤~'.format(img_count))
for item in html['list']:
img_title = item['group_title']
img_url = item['qhimg_url']
self.img_urls.append((img_title,img_url))
return self.img_urls
dataOutput.py:
import os
import threading #
from htmlDownload import htmlDownload
class dataOutput():
"""
数据输出处理
"""
def __init__(self):
"""
创建图片保存路径
"""
self.root_path = r'C:\Users\13479\Desktop\python项目\我的爬虫\有无多进程,线程图片,视频下载对比\图片\多进程、线程爬取\images\\'
# 如果没有文件路径就创建
if not os.path.exists(self.root_path):
os.mkdir(self.root_path)
self.download = htmlDownload()
def download_img(self,img_urls):
"""
下载图片的函数, 运用多线程下载
:param img_urls: 图片名称,url 对应的列表
:return:
"""
# 设置 3 个线程,每个线程下载 10 张图片, 去掉了循环
t1 = threading.Thread(target=self.thread_run, name='Thread_1', args=(img_urls[0:15],)) #
t2 = threading.Thread(target=self.thread_run, name='Thread_2', args=(img_urls[15:],)) #
t1.start() # # 开启线程
t2.start()
t1.join() # # 等待其他线程
t2.join()
def thread_run(self,urls): #
"""
线程执行的下载任务
:param urls: 传进来的图片 url 列表
:return:
"""
for url in urls: #
# 构造图片的完整下载路线
download_path = '{}{}.jpg'.format(self.root_path,url[0])
if not os.path.exists(download_path):
response = self.download.request_url(url[1])
try:
with open(download_path, 'wb') as f:
f.write(response.content)
except:
pass
else:
pass