本帖最后由 20408912 于 2017-4-3 18:04 编辑
最近学了几个星期的python 一直在学习基础的变量 列表 循环之类的
前几天看了一节课程 我也参照了一下 做出了python多线程图片爬虫
在这里和大家一起学习探讨一下 求大神指教
第一步 我们先做一个单线程图片爬虫
[Python] 纯文本查看 复制代码 import time #添加模块
# 这里建立了两个常量
CC_LIST = ('CN IN US ID BR PK NG BD RU JP' # 这是图片的参数
'MX PH VN ET EG DE IR TR CD FR').split()
BASE_URL = 'http://flupy.org/data/flags' #这是抓取图片的网站参数
DEST_DIR = 'downloads/'
# 建立入口
def main():
start = time.time() # 爬虫开始时间
get_many(CC_LIST) # 过程
stop = time.time() # 爬虫结束时间
print(stop-start) # 结束时间减去开始时间 程序结束时会输出时间
# 入口的函数调用
main()
我们这是建立了入口 和抓取的网址和参数
下一步
[Python] 纯文本查看 复制代码 def get_one(cc):
image = download_flag(cc) # 下载图片 储存到内存
show_flag(cc)
save_flag(image,cc.lower()+'.gif') # 保存到文件里
def get_many(cc_list):
for cc in sorted(cc_list):
# 迭代 每次拿到图片
get_one(cc) #抓一个图片
我们这是下载图片到内存 在保存到本地
下一步
[Python] 纯文本查看 复制代码 def download_flag(cc):
url = '{}/{cc}/{cc}.gif'.format(BASE_URL, cc=cc.lower()) # lower 转换成小写
response = urlopen(url) # 响应 (Web)
image = response.read() # 图片是二进制
return image
def save_flag(image,filename):
path = os.path.join(DEST_DIR,filename)
with open(filename,'wb') as f: # w表示 write写 wb 二进制写
f.write(image)
这里是网址与参数结合 启动线程
然后再添加模块
[Python] 纯文本查看 复制代码 # 在顶部在添加模块
import os
from urllib.request import urlopen
还有两段最后的代码
[Python] 纯文本查看 复制代码 def show_flag(cc):
print(cc) # 启动爬虫 (单线程)
单线程完整代码:
[Python] 纯文本查看 复制代码 import time
import os
from urllib.request import urlopen
CC_LIST = ('CN IN US ID BR PK NG BD RU JP'
'MX PH VN ET EG DE IR TR CD FR').split()
BASE_URL = 'http://flupy.org/data/flags'
DEST_DIR = 'downloads/'
def download_flag(cc):
url = '{}/{cc}/{cc}.gif'.format(BASE_URL, cc=cc.lower())
response = urlopen(url)
image = response.read()
return image
def show_flag(cc):
print(cc)
def save_flag(image,filename):
path = os.path.join(DEST_DIR,filename)
with open(filename,'wb') as f:
f.write(image)
def get_one(cc):
image = download_flag(cc)
show_flag(cc)
save_flag(image,cc.lower()+'.gif')
def get_many(cc_list):
for cc in sorted(cc_list):
get_one(cc)
def main():
start = time.time()
get_many(CC_LIST)
stop = time.time()
print(stop-start)
main()
我们来运行一下:
单线程耗时10多秒 抓取了所有图片(代码或许有bug 有时可能崩溃)
我们来试试多线程
只需要修改:
[Python] 纯文本查看 复制代码 # 多线程修改
# 在顶部在添加参数
from concurrent import futures
#把 get_many 修改
def get_many(cc_list):
with futures.ThreadPoolExecutor(20) as executor: # 20 是20线程
res = executor.map(get_one,sorted(cc_list))
完整多线程代码:
[Python] 纯文本查看 复制代码 import time
import os
from urllib.request import urlopen
from concurrent import futures
CC_LIST = ('CN IN US ID BR PK NG BD RU JP'
'MX PH VN ET EG DE IR TR CD FR').split()
BASE_URL = 'http://flupy.org/data/flags'
DEST_DIR = 'downloads/'
def download_flag(cc):
url = '{}/{cc}/{cc}.gif'.format(BASE_URL, cc=cc.lower())
response = urlopen(url)
image = response.read()
return image
def show_flag(cc):
print(cc)
def save_flag(image,filename):
path = os.path.join(DEST_DIR,filename)
with open(filename,'wb') as f:
f.write(image)
def get_one(cc):
image = download_flag(cc)
show_flag(cc)
save_flag(image,cc.lower()+'.gif')
def get_many(cc_list):
with futures.ThreadPoolExecutor(20) as executor:
res = executor.map(get_one,sorted(cc_list))
def main():
start = time.time()
get_many(CC_LIST)
stop = time.time()
print(stop-start)
main()
多线程测试:
只耗时1到2秒左右
这就是多线程与双线程的区别
当然 多线程更消耗内存资源 你如你内存允许 就算1000线程都可以。
求各位大佬指点 |