美文网首页
使用ThreadPoolExecutor线程池高效爬取Bing每

使用ThreadPoolExecutor线程池高效爬取Bing每

作者: 越大大雨天 | 来源:发表于2019-06-26 00:46 被阅读0次

    本文没有写太多代码逻辑分析,使用的爬虫是最基本的爬虫知识,只是想试试使用线程池的效果,线程池的知识点参考上文:https://www.jianshu.com/p/82f1a574ad8c

    就直接上代码了,实践结果证明,多线程在有延迟的网络请求及文件写入等IO操作上是能极大提高效率的,且使用futures下的线程池模块实现非常容易。

    以下代码可直接使用,爬取的图片用来自动更换壁纸很棒。注意更改下代码中的路径或者在当前目录新建“Bing每日一图”目录即可。

    import re
    import requests
    from concurrent import futures
    import time
    
    
    class BingImageDownload(object):
        """
            下载bing每日一图,实例化时需传入pagelist参数,为下载页的可迭代对象
        """
        def __init__(self, pagelist):
            self.url = "http://bing.plmeizi.com/show/{}"
            self.headers = {
                "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36"
            }
            self.pagelist =pagelist
    
        # 获取每个页面的标题和大图链接字典
        def get_image(self,page):
            this_url = self.url.format(page)
            # 获取快照页,通过快照页获取图片名及高清图链接
            response = requests.get(this_url,headers=self.headers)
            if response.status_code == 200:
                content = response.text
                message = re.findall(r'<span id="title">(.*?)>>查看大图</a>', content, re.S)[0]
                title = re.findall(r'(.*?) ', message, re.S)[0]
                image_url = re.findall(r'<a href="(.*?)" target="_blank" id="picurl">', message, re.S)[0]
                image_info_dict = {"title":title,"image_url":image_url}
                return  self.download_HDimage(image_info_dict,page)
            else:
                print('页面信息获取失败:第{}页'.format(page))
            # 稍微设置延迟,减轻对服务器压力
            time.sleep(0.2)
        # 写入文件
        def to_file(self, content, filename,page):
            filename = filename.strip('"')
            with open('./Bing每日一图/%s.jpg' % filename, 'wb') as f:
                f.write(content)
                print("第%s页:【%s】-->下载完成" % (page, filename))
    
        #下载大图
        def download_HDimage(self,image_info_dict,page):
            title = image_info_dict.get("title")
            image_url = image_info_dict.get("image_url")
            response = requests.get(image_url,headers=self.headers)
            if response.status_code == 200:
                content = response.content
                self.to_file(content,title,page)
            else:
                print("HD大图下载失败 -->title:{},url:{}".format(title,image_url))
    
        # 使用线程池并发管理并发下载,设定下载页
        def main(self):
            start = time.time()
            DOWNLOAD_PAGE_LIST = self.pagelist
            # 线程池开启,设置最大线程量20
            workers = 20
            with futures.ThreadPoolExecutor(workers) as excutor:
                result = excutor.map(self.get_image, DOWNLOAD_PAGE_LIST)
            end = time.time()
            total_time = end-start
            print("---下载完成,总计下载数量:{},总耗时:{}---".format(len(list(result)),total_time))
            return len(list(result))
    
    
    if __name__ == '__main__':
        PAGE_LIST = range(1,1000)
        downloader = BingImageDownload(PAGE_LIST)
        downloader.main()
    
    

    相关文章

      网友评论

          本文标题:使用ThreadPoolExecutor线程池高效爬取Bing每

          本文链接:https://www.haomeiwen.com/subject/bgnfcctx.html