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 何処へ行くの