[原创] Python3.6+request+beautiful 半次元Top100 爬虫实战,将小姐姐的cos美图得到

1 技术栈

Python3.6 Python的版本css

request 获得网页html、jpg等资源的libhtml

beautifulsoup 解析html的利器html5

html5lib 指定beautifulsoup按什么方式解析python

os 建立文件夹须要用到系统操做libgit

2 IDE

Anaconda Spidergithub

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 网络处理的类型web

Accept-Encoding 编码方式chrome

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 何処へ行くの
相关文章
相关标签/搜索