[原創] 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 何処へ行くの
相關文章
相關標籤/搜索