最近学习了一下python的多进程和多线程,于是就想到使用进程去现实一个爬虫。通过比较实用多进程比使用普通函数的效率更高,节省了大量的时间。话不多说,看下面的代码,希望对各位有所帮助。

import os, sys, io, urllib, requests, re, chardet, time
import multiprocessing
'''
遇到不懂的问题?Python学习交流群:1136201545
满足你的需求,资料都已经上传群文件,可以自行下载!
'''
#设置系统输出流的编码为utf-8
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf8')

headers = {
    'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Mobile Safari/537.36'
}

url = 'http://www.ivsky.com/tupian/ziranfengguang/'

def Schedule(blocknum, blocksize, totalsize):
    """
        blocknum:已经下载的数据块
        blocksize:数据块的大小
        totalsize:远程文件的大小
    """
    per = blocknum * blocksize / totalsize * 100.0
    if per > 100:
        per = 100
    print('当前下载进度: %.2f%%'%per)

def download_page():
    try:
        res = requests.get(url, headers=headers)
        if res.status_code == 200:
            res.encoding = chardet.detect(res.content).get('encoding')#通过chardet库的detect方法获取页面的编码
            return res.text
    except requests.HTTPError as e:
        return None

def parser_html(html):
    if not html:
        return
    patt = re.compile(r'<img src="(.*?)" alt="(.*?)" />', re.S)#获取图片的链接和名字
    content = re.findall(patt, html)
    return content #返回图片链接和名字列表

def download_pic(url, name):
    if not os.path.exists(r'./pic'):
        os.mkdir(r'./pic')
    filename = './pic/{}.jpg'.format(name)
    print('开始下载:{}'.format(name))
    urllib.request.urlretrieve(url, filename, Schedule)#使用urllib.request.urlretrieve方法下载图片并返回当前下载进度
    time.sleep(1)

if __name__ == '__main__':
    html = download_page()
    contents = parser_html(html)
    for content in contents:
        p = multiprocessing.Process(target=download_pic, args=(content[0],content[1]))
        #启动进程和连接进程
        p.start()
        p.join()

下面是使用多进程和普通函数分别爬取图片的结果

多进程

image

普通函数

image


本文转载:CSDN博客