一. requests.Session()
上一篇總結爬蟲的文章裡,有說道一個cookie的問題。當時我都是手動解析,手動新增的。後來才知道requests模組居然有一個Session功能,可以保持cookie。這裡記錄一下:
import requests
base_url = 'https://www.zhihu.com'
# 未登入裝態
r_session = requests.Session()
r_session.headers['User-Agent'] = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'
zhihu = r_session.get(base_url)
print(zhihu.request.headers)
# 登入
data = {'username': 'username', 'password': 'password'}
zhihu_sign_in = r_session.post('https://www.zhihu.com/api/v3/oauth/sign_in', data=data)
print(zhihu_sign_in.request.headers)
複製程式碼
結果:
用了Session就會自動帶上cookie了。
二. 如何下載一個圖片
-
urlretrieve
在Python自帶的模組urllib中提供了一個方法urlretrieve,可以用這個方法下載一個圖片:
from urllib.request import urlretrieve import os img_url = 'https://wx4.sinaimg.cn/mw690/70396e5agy1fxlqvsv93sj20ku0yu42u.jpg' urlretrieve(img_url, './image.jpg') 複製程式碼
傳入圖片地址和圖片要存放的地址即可。
-
requests模組
import requests img_url = 'https://wx4.sinaimg.cn/mw690/70396e5agy1fxlqvsv93sj20ku0yu42u.jpg' img = requests.get(img_url) with open('./image2.jpg', 'wb') as f: f.write(img.content) 複製程式碼
使用requests模組也可以下載圖片,通過open方法將下載下來的圖片通過二進位制方式寫入檔案中
如果下載的圖片(除了圖片其他資源也一樣,比如視訊)特別大,那麼還可以用
import requests img_url = 'https://wx4.sinaimg.cn/mw690/70396e5agy1fxlqvsv93sj20ku0yu42u.jpg' img = requests.get(img_url, stream=True) with open('./image3.jpg', 'wb') as f: for chunk in img.iter_content(chunk_size=10): f.write(chunk) 複製程式碼
這種方式,加上steam=True引數,可以讓requests下載一點儲存一點,而不是等全部下載完成再進行儲存,然後通過chunk_size控制chunk的大小
-
實現一個下載桌布的爬蟲
import requests
import time
import random
from bs4 import BeautifulSoup
import os
from functools import reduce
base_url = 'https://alpha.wallhaven.cc/' # 桌布網址
req_session = requests.Session()
req_session.headers['user-agent'] = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'
def get_store_path(dir_name):
'''
建立存放桌布檔案目錄
'''
current_path = os.path.abspath('.')
target_path = os.path.join(current_path, 'wallpaper/%s' % dir_name)
folder = os.path.exists(target_path)
if not folder:
os.makedirs(target_path)
return target_path
def get_img_html(page_size):
'''
獲取桌布的html資源
'''
htmls = []
for i in range(1, page_size):
params = {
'q': keyword,
}
# 由於該網站page是從2開始的,如果帶了小於2的值就會找不到桌布
if i >= 2:
params['page'] = i
html = req_session.get('%s/search' % base_url, params=params)
htmls.append(html)
time.sleep(random.random())
return htmls
def parse_html(html):
'''
從html中將桌布地址解析出來
'''
imgs_src = []
bs_html = BeautifulSoup(html.text, 'lxml')
img_tags = bs_html.find_all('img', {'class': 'lazyload'})
if len(img_tags):
for img in img_tags:
imgs_src.append(img['data-src'])
return imgs_src
def download_imgs(imgs_src):
'''
下載桌布
'''
if len(imgs_src):
for index, src in enumerate(imgs_src):
img = req_session.get(src, stream=True)
img_name = src.split('/')[-1]
store_path = '%s/%s' % (get_store_path(keyword), img_name)
with open(store_path, 'wb') as f:
for chunk in img.iter_content(chunk_size=128):
f.write(chunk)
print('下載進度:%d/%d' % (index + 1, len(imgs_src)))
print('下載完成,圖片已存放在:%s' % store_path)
else:
print('沒有找到相關主題的桌布')
keyword = input('請輸入你想要下載的桌布主題:')
page_size = int(input('請輸入下載桌布的頁數,每頁24張:'))
print('開始查詢桌布....')
html_list = get_img_html(page_size)
img_src_list = []
if len(html_list):
print('查詢完成')
print('開始爬取桌布地址...')
for html in html_list:
img_src_list.append(parse_html(html))
img_src_list = reduce(lambda x, y: x+y, img_src_list)
print('爬取完成')
print('開始下載桌布...')
download_imgs(img_src_list)
else:
print('沒有找到相關主題的桌布')
複製程式碼
結果: