一個微博熱搜引發的故事
- 一、故事從這里開始
- 二、搞事情第一步:搜集圖片
- 三、搞事情第二步:展示圖片
- 四、搞事情第三步:推廣鏈接
- 五、搞事情第四步:統計分析
- 1.資料處理2.資料篩選3.統計各天的頻率4.統計星座的頻率5.統計月份的頻率6.資料可視化(3個條形圖)
- 寫在最后
很多人學習python,不知道從何學起,
很多人學習python,掌握了基本語法過后,不知道在哪里尋找案例上手,
很多已經做案例的人,卻不知道如何去學習更加高深的知識,
那么針對這三類人,我給大家提供一個好的學習平臺,免費領取視頻教程,電子書籍,以及課程的源代碼!
QQ群:961562169
一、故事從這里開始
3月29日那晚,我正在廁所蹲坑來著,大概就是邊蹲邊刷手機的那種…突然發現一條微博熱搜#你出生那天的宇宙#
在評論區,發現大家都有一個同樣的疑惑:無法訪問NASA官網(可能是因為訪問量過大,導致網路極高延時),作為一個社會主義正直青年,我怎么能放著不管呢?
于是,我決定搞事情!!
二、搞事情第一步:搜集圖片
一個簡單的想法油然而生:既然大家沒法從官網上下載圖片,那我就幫大家集齊圖片,然后發給大家就好啦,(搜集資料嘛,寫個爬蟲不就好了?)
于是,我直接沖進NASA官網準備分析一波請求,結果…好叭,我也是大家中的一員,我也加載不出圖片,
這點困難我怎么能退縮呢,再于是,我就去微博評論下面苦苦尋找,果然功夫不負有心人,發現豆瓣上有個大佬已經為找齊了所有圖片:
秉承“拿來主義”的作風,我決定這里就是我的資料源(某豆瓣相冊)
簡單分析了一下,發現可以通過一個m_start的引數進行翻頁,每頁20張圖片(如m_start=0為第一頁,m_start=20為第二頁),那么寫一個回圈便可:
import re
import queue
import requests
import threading
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
headers = {
'Host': 'www.douban.com',
'Connection': 'keep-alive',
'Cache-Control': 'max-age=0',
'Upgrade-Insecure-Requests': '1',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36',
'Sec-Fetch-Dest': 'document',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'Sec-Fetch-Site': 'none',
'Sec-Fetch-Mode': 'navigate',
'Sec-Fetch-User': '?1',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'zh-CN,zh;q=0.9',
'Cookie': 'bid=rb_kUqiDS6k; douban-fav-remind=1; _pk_ses.100001.8cb4=*; ap_v=0,6.0; __utma=30149280.1787149566.1585488263.1585488263.1585488263.1; __utmc=30149280; __utmz=30149280.1585488263.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __yadk_uid=HNoH1YVIvD2c8HrQDWHRzyLciFJl1AVD; __gads=ID=a1f73d5d4aa31261:T=1585488663:S=ALNI_MafqKPZWHx0TGWTpKEm8TTvdC-eyQ; ct=y; _pk_id.100001.8cb4=722e0554d0127ce7.1585488261.1.1585488766.1585488261.; __utmb=30149280.10.6.1585488263'
}
# driver初始化
chrome_options = Options()
chrome_options.add_argument('--headless')
driver = webdriver.Chrome(options=chrome_options)
# 下載圖片
def downimg():
while not img_queue.empty():
img = img_queue.get()
img_name = img[0]
url = img[1]
res = requests.get(url)
data =https://www.cnblogs.com/41280a/p/res.content
with open('./img/%s.webp'%img_name,'wb') as f:
f.write(data)
print(img_name)
# 網站引數
url_o = 'https://www.douban.com/photos/album/1872547715/?m_start=%d'
# 爬取連接
img_queue = queue.Queue()
for i in range(0,21):
url = url_o%(18*i)
driver.get(url)
es = driver.find_elements_by_class_name('photo_wrap')
for e in es:
img_e = e.find_element_by_tag_name('img')
img_url = img_e.get_attribute('src')
img_url = img_url.replace('photo/m/public','photo/l/public') # 替換為大圖
text_e = e.find_element_by_class_name('pl')
img_date = text_e.text
img_queue.put((img_date,img_url))
print('%d頁爬取完成'%(i+1))
driver.close()
# 下載圖片
thread_list = []
N_thread = 5
for i in range(N_thread):
thread_list.append(threading.Thread(target=downimg))
for t in thread_list:
t.start()
for t in thread_list:
t.join()
代碼簡單來說就是:webdriver訪問頁面并獲取圖片地址,然后通過多執行緒利用requests下載并保存圖片,
至此,圖片搜集的作業基本完成!
三、搞事情第二步:展示圖片
有了圖片,接下來就是如何讓大家獲得圖片呢?去給每個人私發?機智的我當然不會這么干,我決定寫一個小網頁來讓大家訪問,作為很不專業的我,東平西湊,效果大概就是這樣(你生日那天的宇宙):
四、搞事情第三步:推廣鏈接
關于推廣,咱也不懂,咱也不敢說, 傻傻的我決定自己發一條微博(心里大概是想:這么方便的工具,肯定會受大家歡迎的,肯定是這樣沒有錯,對,沒錯…):
現實嘛,總是殘酷的,吃瓜群眾都猜到了:無人問津,石沉海底~
幾經周折,最后呢在一位相關話題的熱門博主的鼎力幫助下,最終迎來了一些流量:
五、搞事情第四步:統計分析
雖然這個流量跟我想象的還是相差甚遠,畢竟這個話題也是有上億的閱讀量的,但是我還是決定對昨天訪問的情況做一個簡單的統計:
1.資料處理
在某度統計里拿到網頁訪問資料的原始csv表格后,進行了簡單資料處理,調整為更方便讀取的格式,
2.資料篩選
由于表格中并不僅僅包括NASA頁面的資料,還有一些其他頁面的資料,于是必須進行資料的篩選:
# 讀取資料
data = https://www.cnblogs.com/41280a/p/pd.read_csv('./analyze/20200330-20200330.csv',encoding='utf-8')
# 篩選資料(和NASA相關且有有效日期的資料)
data_NASA = []
for i in range(len(data)):
url = urllib.parse.unquote(data['URL'][i])
pv = data['PV'][i] # 瀏覽量
uv = data['UV'][i] # 訪客量
#if url[-1] == '日' and 'NaN' not in url: # 為NASA訪問頁面
if 'date=' in url and 'NaN' not in url:
try:
data_NASA.append((re.findall('date=(\d*?月\d*?日)',url)[0],pv,uv))
except:
pass
3.統計各天的頻率
# 統計各個天數的頻率
PV_map= {}
UV_map = {}
PV_total = 0
UV_total = 0
for d in data_NASA:
if d[0] not in PV_map.keys():
PV_map[d[0]] = 0
UV_map[d[0]] = 0
PV_map[d[0]] += d[1] # PV
UV_map[d[0]] += d[2] # UV
PV_total += d[1]
UV_total += d[2]
for k in PV_map.keys(): # 計算頻率
PV_map[k] = PV_map[k]/PV_total*100
UV_map[k] = UV_map[k]/UV_total*100
PVs= sorted(PV_map.items(),key=lambda x:x[1],reverse=True) # 排序
UVs= sorted(UV_map.items(),key=lambda x:x[1],reverse=True) # 排序
4.統計星座的頻率
# 判斷星座
def get_xingzuo(month, date):
dates = (21, 20, 21, 21, 22, 22, 23, 24, 24, 24, 23, 22)
constellations = ("摩羯座", "水瓶座", "雙魚座", "白羊座", "金牛座", "雙子座", "巨蟹座", "獅子座", "處女座", "天秤座", "天蝎座", "射手座", "摩羯座")
if date < dates[month-1]:
return constellations[month-1]
else:
return constellations[month]
# 統計各星座的頻率
xingzuo = ("摩羯座", "水瓶座", "雙魚座", "白羊座", "金牛座", "雙子座", "巨蟹座", "獅子座", "處女座", "天秤座", "天蝎座", "射手座", "摩羯座")
xingzuo_map = {}
for x in xingzuo:
xingzuo_map[x] = 0
xingzuo_total = 0
for d in data_NASA:
month = int(re.findall('(\d*?)月(\d*?)日',d[0])[0][0])
day = int(re.findall('(\d*?)月(\d*?)日',d[0])[0][1])
x = get_xingzuo(month,day)
#xingzuo_map[x] += d[1] # PV
xingzuo_map[x] += d[2] # UV
xingzuo_total += d[2]
for k in xingzuo_map.keys():
xingzuo_map[k] = xingzuo_map[k]/xingzuo_total*100
xingzuos= sorted(xingzuo_map.items(),key=lambda x:x[1],reverse=True) # 排序
5.統計月份的頻率
# 統計各月份的頻率
month = [str(i)+'月' for i in range(1,13)]
month_map = {}
for m in month:
month_map[m] = 0
month_total = 0
for d in data_NASA:
m = d[0].split('月')[0]+'月'
#month_map[m] += d[1] # PV
month_map[m] += d[2] # UV
month_total += d[2]
for k in month_map.keys():
month_map[k] = month_map[k]/month_total*100
months= sorted(month_map.items(),key=lambda x:x[1],reverse=True) # 排序
6.資料可視化(3個條形圖)
## 生日查詢TOP10-按訪客量UV
date = []
uv = []
for i in UVs:
date.append(i[0])
uv.append(i[1])
top10_date = date[:10]
top10_date.reverse()
top10_uv = uv[:10]
top10_uv.reverse()
fig, ax = plt.subplots() # 畫圖
b = plt.barh(top10_date,top10_uv,color='#6699CC') # 金色#FFFACD 銀色#C0C0C0 橙色#FFA500 藍色#6699CC
i = len(b)
for rect in b: # 畫數值
if i==3: # 第三名
rect.set_facecolor('#FFA500') # 橙色
if i==2: # 第二名
rect.set_facecolor('#C0C0C0') # 銀色
if i==1: # 第一名
rect.set_facecolor('#FFFACD') # 金色
w = rect.get_width()
ax.text(w, rect.get_y()+rect.get_height()/2, ' %.2f%%'%w,ha='left', va='center')
i -= 1
plt.xticks([]) # 關掉橫坐標
## 星座查詢排名
name = []
v = []
for i in xingzuos:
name.append(i[0])
v.append(i[1])
name.reverse()
v.reverse()
fig, ax = plt.subplots() # 畫圖
b = plt.barh(name,v,color='#6699CC') # 金色#FFFACD 銀色#C0C0C0 橙色#FFA500 藍色#6699CC
i = len(b)
for rect in b: # 畫數值
if i==3: # 第三名
rect.set_facecolor('#FFA500') # 橙色
if i==2: # 第二名
rect.set_facecolor('#C0C0C0') # 銀色
if i==1: # 第一名
rect.set_facecolor('#FFFACD') # 金色
w = rect.get_width()
ax.text(w, rect.get_y()+rect.get_height()/2, ' %.2f%%'%w,ha='left', va='center')
i -= 1
plt.xticks([]) # 關掉橫坐標
## 月份查詢排名
name = []
v = []
for i in months:
name.append(i[0])
v.append(i[1])
name.reverse()
v.reverse()
fig, ax = plt.subplots() # 畫圖
b = plt.barh(name,v,color='#6699CC') # 金色#FFFACD 銀色#C0C0C0 橙色#FFA500 藍色#6699CC
i = len(b)
for rect in b: # 畫數值
if i==3: # 第三名
rect.set_facecolor('#FFA500') # 橙色
if i==2: # 第二名
rect.set_facecolor('#C0C0C0') # 銀色
if i==1: # 第一名
rect.set_facecolor('#FFFACD') # 金色
w = rect.get_width()
ax.text(w, rect.get_y()+rect.get_height()/2, ' %.2f%%'%w,ha='left', va='center')
i -= 1
plt.xticks([]) # 關掉橫坐標
最后的結果就長這個樣子:
寫在最后
如果可以,我亦希望在無數次鍵盤的敲擊聲中創造出所謂的“極致浪漫”~
最后,附上本次NASA活動中個人覺得比較好看的一些圖片:
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/139144.html
標籤:Python
