zoukankan      html  css  js  c++  java
  • [原创] Python3.6+request+beautiful 半次元Top100 爬虫实战,将小姐姐的cos美图获得

    1 技术栈

    Python3.6 Python的版本

    request 得到网页html、jpg等资源的lib

    beautifulsoup 解析html的利器

    html5lib 指定beautifulsoup按什么方式解析

    os 创建文件夹需要用到系统操作lib

    2 IDE

    Anaconda Spider

    3 如何正确的获取半次元网页内容

    3.1 https请求的user head参数的设置

    agent='Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36 OPR/46.0.2597.57'
    user_head={     
    	'Accept': "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", 
    	'Accept-Encoding': "gzip, deflate, sdch, br",
    	'Accept-Language': "zh-CN,zh;q=0.8,en;q=0.6,zh-TW;q=0.4,ja;q=0.2",
    	'Cache-Control':'max-age=0',
    	"Connection": "keep-alive",
    	'Referer': 'https://bcy.net/start',
    	'User-Agent': agent    
    }
    

    Accept 网络处理的类型

    Accept-Encoding 编码方式

    Accept-Language 编码语言

    Cache-Control 控制缓存的生命周期

    Connection 连接方式,选择keep-alive长期连接

    Referer 从哪个页面发来的请求

    User-Agent 浏览器标志,防止半次元服务器识别http请求为浏览器发起

    3.2 cookie文件的读取

    cookie_file = "bcy_cookie.txt"  
        if os.path.exists(cookie_file):
            #如果cookies文件存在则直接读取cookie
            bcy_cookies = {}
            with open(cookie_file,'r',buffering = 4*1024) as fp:
                for line in fp.read().split(';'):
                    name,value = line.strip().split('=',1)
                    bcy_cookies[name] = value
                fp.flush()  
            print('load cookies is Success')
        else: 
            print('you have no cookie')
        print ("bcy cookies:" + str(bcy_cookies))
    

    bcy_cookie是一个对象

    bcy_cookie.txt中的内容为:

    acw_tc=AQAAACHqkjHLZQcAtVPt3f8ifalDKgni; 
    PHPSESSID=vgeda76lj7339cov0n76390rl0; 
    lang_set=zh; 
    mobile_set=no
    

    3.3 request 读取html内容并转为soup对象

       GALLERY_START_URL = 'https://bcy.net/coser/toppost100'
       #浏览器打开首页
       gallery_content = requests.get(GALLERY_START_URL,cookies=bcy_cookies,headers=user_head,timeout=9).text.encode('utf-8')    
       #得到首页的soup的对象
       gallery_soup = BeautifulSoup(gallery_content,'html5lib')
    

    requests.get 获取一个html对象,timeout是设置允许的最大时间延迟
    BeautifulSoup 将html对象转为可以被解析的soup对象,采用html5lib解析

    3.4 soup对象查找源代码中的连接


    注意应该查找source(源代码)中作品连接入口,
    elements是经过浏览器chrome加载js渲染后的dom,所以对应的css class可能不一样

    	# 得到所有的作品入口
        all_work = gallery_soup.findAll('li',class_ = 'l-work-thumbnail')
    

    3.5 遍历每一个all_work对象获取标题和作品进入的连接

    	# 得到所有的作品入口
        for work in all_work:
    		work_a = work.find('div',class_ = 'work-thumbnail__topBd').find('a')
            title = work_a['title']  
            #去掉保存到本地图片文件名中非法字符
            unvalid_str = '<>,/|,:,"",*,?'
            for ch in unvalid_str:
                title = title.replace(ch,'') 
            title = title.strip()                
            work_url = 'https://bcy.net' + work_a['href']
    

    因为Windows系统不允许文件夹出现<>,/|,:,"",*,?等字符,所以需要做delete处理

    3.6 新建作品文件夹

    专门写一个函数用于作品文件夹创建,并做是否创建的处理

    # @创建gallery文件夹
    # @input:GALLERY_NAME gallery保存的文件夹
    # @output:
    def mkdir(GALLERY_NAME):
        GALLERY_NAME = GALLERY_NAME.strip()
        GALLERY_NAME = GALLERY_NAME.rstrip("\")
    
        if not os.path.exists(GALLERY_NAME):  # 如果不存在则创建目录
            print(GALLERY_NAME + ' Success')   # 创建目录操作函数
            os.makedirs(GALLERY_NAME)
            return True
        else:  # 如果目录存在则不创建,并提示目录已存在
            print(GALLERY_NAME + ' existence')
            return False
    

    主函数中的步骤

    	#新建作品
        WORK_FOLD_NAME = GALLERY_NAME + '\' +str(top_index).zfill(3) + '_' + title
        mkdir(WORK_FOLD_NAME)
    

    3.7 点击进入作品连接,遍历读取所有的图片

    	#得到作品html对象
    	image_content = requests.get(work_url,cookies=bcy_cookies,headers=user_head,timeout=20).text.encode('utf-8') 
    	
    	#得到作品soup对象
    	image_group_soup = BeautifulSoup(image_content,'html5lib')
    
    	#每一个图片的soup对象
    	image_group_div = image_group_soup.findAll('img',class_ = 'detail_std')
    	
    	#记录爬去图片的标号 
    	image_index = 0
    	
    	#遍历每一个有图片的image div
    	for image in image_group_div:
    		image_url = image['src'] #图片的URL
    		image_url = image_url[:-5] #图片URL去掉后缀得到真正的RAW图片
    		
    		#获取图片图像,注意图片是资源所用 stream设置为True
    		pic = requests.get(image_url, stream=True,cookies=bcy_cookies, headers=user_head,timeout=12)
    		
    		#图片保存在本地的路径
    		file_local_url = WORK_FOLD_NAME + '\' +str(image_index).zfill(2) +'.jpg'
    		
    		#图片已存在则直接continue
    		if os.path.exists(file_local_url):
    			print('pic has been downloaded!')
    			continue
    		else:
    			print('pic is downloaded, start to writing to local ')    
    			# 推荐使用witho open,避免忘记进行fp.close()操作,buffering设置是为了IO加速
    			with open(file_local_url, 'wb',buffering = 4*1024) as fp:
    				fp.write(pic.content) #写入file_local_url内容到图片
    				fp.flush()  
    			print(image_url +' download Successful')
    			
    		image_index = image_index +1
    

    上面的buffering参数值得一说,如果不加则直接从pic读取持续写入磁盘中

    如果图片很大,这种行为很伤磁盘

    所以需要设置一个缓冲区,每从网络读取4K大小才从内存写入磁盘

    完整代码,见我的Github

    https://github.com/Kalafinaian/BcyTopSpider

    如果你喜欢这个Python小程序,欢迎各位Start我这个repository

    Author by : Kalafianian
    本当は空を飞べると知っていたから
    羽ばたくときが怖くて风を忘れた
    Oblivious 何処へ行くの
    
  • 相关阅读:
    Python之路Day12--mysql介绍及操作
    Python之路第一课Day11--随堂笔记(异步IO数据库队列缓存之二)
    Python之路第一课Day10--随堂笔记(异步IO数据库队列缓存)
    Python之路第一课Day9--随堂笔记之二(进程、线程、协程篇)
    Python之路第一课Day9--随堂笔记之一(堡垒机实例以及数据库操作)未完待续....
    Python之路第一课Day8--随堂笔记(socket 承接上节---网络编程)
    Python之路第一课Day7--随堂笔记(面向对象编程进阶...未完待续 )
    Python之路第一课Day6--随堂笔记(面向对象 )
    Python之路第一课Day5--随堂笔记(模块)
    Python之路第一课Day4--随堂笔记(迭代生成装饰器)
  • 原文地址:https://www.cnblogs.com/Kalafinaian/p/7354063.html
Copyright © 2011-2022 走看看