亚洲熟女综合色一区二区三区,亚洲精品中文字幕无码蜜桃,亚洲va欧美va日韩va成人网,亚洲av无码国产一区二区三区,亚洲精品无码久久久久久久

太好玩了,爬蟲、部署API、加小程序,一條龍玩轉(zhuǎn)知乎熱榜

一直想做一個(gè)從爬蟲到數(shù)據(jù)處理,到API部署,再到小程序展示的一條龍項(xiàng)目,最近抽了些時(shí)間,實(shí)現(xiàn)了一個(gè)關(guān)于知乎熱榜的,今天就來分享一下!

由于代碼還沒有完全整理好,今天只給出一個(gè)大致的思路和部分代碼,最終的詳細(xì)代碼可以關(guān)注后續(xù)的文章!

數(shù)據(jù)爬取

首先我們看下需要爬取的知乎熱榜

https://www.zhihu.com/billboard

這個(gè)熱榜可以返回50條熱榜數(shù)據(jù),而這些數(shù)據(jù)都是通過頁面的一個(gè) JavaScript 返回的

太好玩了,爬蟲、部署API、加小程序,一條龍玩轉(zhuǎn)知乎熱榜

于是我們就可以通過解析這段 JS 代碼來獲取對應(yīng)數(shù)據(jù)

url='https://www.zhihu.com/billboard'
headers={"User-Agent":"","Cookie":""}


defget_hot_zhihu():
res=requests.get(url,headers=headers)
content=BeautifulSoup(res.text,"html.parser")
hot_data=content.find('script',id='js-initialData').string
hot_json=json.loads(hot_data)
hot_list=hot_json['initialState']['topstory']['hotList']
returnhot_list

然后我們再點(diǎn)擊一個(gè)熱榜,查看下具體的熱榜頁面,我們一直向下下拉頁面,并打開瀏覽器的調(diào)試板,就可以看到如下的一個(gè)請求

太好玩了,爬蟲、部署API、加小程序,一條龍玩轉(zhuǎn)知乎熱榜

該接口返回了一個(gè)包含熱榜回答信息的 json 文件,可以通過解析該文件來獲取對應(yīng)的回答

defget_answer_zhihu(id):
url='https://www.zhihu.com/api/v4/questions/%s/answers?include='%id
headers={"User-Agent":"","Cookie":""}
res=requests.get(url+Config.ZHIHU_QUERY,headers=headers)
data_json=res.json()
answer_info=[]
foriindata_json['data']:
if'paid_info'ini:
continue
answer_info.append({'author':i['author']['name'],'voteup_count':i['voteup_count'],
'comment_count':i['comment_count'],'content':i['content'],
'reward_info':i['reward_info']['reward_member_count']})
returnanswer_info

數(shù)據(jù)存儲

獲取到數(shù)據(jù)之后,我們需要存儲到數(shù)據(jù)庫中,以便于后續(xù)使用。因?yàn)楹竺鏈?zhǔn)備使用 Flask 來搭建 API 服務(wù),所以這里存儲數(shù)據(jù)的過程也基于 Flask 來做,用插件 flask_sqlalchemy。

定義數(shù)據(jù)結(jié)構(gòu)

我們定義三張表,分別存儲知乎熱榜的詳細(xì)列表信息,熱榜的熱度信息和熱榜對應(yīng)的回答信息

classZhihuDetails(db.Model):
__tablename__='ZhihuDetails'
id=db.Column(db.Integer,primary_key=True)
hot_id=db.Column(db.String(32),unique=True,index=True)
hot_name=db.Column(db.Text)
hot_link=db.Column(db.String(64))
hot_cardid=db.Column(db.String(32))


classZhihuMetrics(db.Model):
__tablename__='ZhihuMetrics'
id=db.Column(db.Integer,primary_key=True)
hot_metrics=db.Column(db.String(64))
hot_cardid=db.Column(db.String(32),index=True)
update_time=db.Column(db.DateTime)


classZhihuContent(db.Model):
__tablename__='ZhihuContent'
id=db.Column(db.Integer,primary_key=True)
answer_id=db.Column(db.Integer,index=True)
author=db.Column(db.String(32),index=True)
voteup_count=db.Column(db.Integer)
comment_count=db.Column(db.Integer)
reward_info=db.Column(db.Integer)
content=db.Column(db.Text)

定時(shí)任務(wù)

由于我們需要定時(shí)查詢熱榜列表和熱榜的熱度值,所以這里需要定時(shí)運(yùn)行相關(guān)的任務(wù),使用插件 flask_apscheduler 來做定時(shí)任務(wù)

我們的定時(shí)任務(wù),涉及到了網(wǎng)絡(luò)請求和數(shù)據(jù)入庫的操作,把這部分定時(shí)任務(wù)代碼單獨(dú)拉出來,在 Flask 項(xiàng)目的根目錄下創(chuàng)建一個(gè)文件 apschedulerjob.py,由于在運(yùn)行該文件時(shí),是沒有 Flask app 變量的,所以我們需要手動調(diào)用 app_context() 方法來創(chuàng)建 app 上下文

defopera_db():
withscheduler.app.app_context():
...

當(dāng)然,這里的 scheduler 變量是在 create_app 中初始化過的

fromflask_apschedulerimportAPScheduler

scheduler=APScheduler()


defcreate_app(config_name):
app=Flask(__name__)
app.config.from_object(config[config_name])
config[config_name].init_app(app)
db.init_app(app)
scheduler.init_app(app)
...

接著,我們就可以根據(jù)前面的兩個(gè)爬蟲函數(shù),來分別入庫數(shù)據(jù)了

入庫熱榜熱度數(shù)據(jù)

update_metrics=ZhihuMetrics(hot_metrics=i['target']['metricsArea']['text'],
hot_cardid=i['cardId'],
update_time=datetime.datetime.now())

入庫熱榜列表數(shù)據(jù)

new_details=ZhihuDetails(hot_id=i['id'],hot_name=i['target']['titleArea']['text'],
hot_link=i['target']['link']['url'],hot_cardid=i['cardId'])

入庫熱榜回答數(shù)據(jù)

new_content=ZhihuContent(answer_id=answer_id,author=answer['author'],voteup_count=answer['voteup_count'],
comment_count=answer['comment_count'],reward_info=answer['reward_info'],
content=answer['content'])

最后我們就可以在 Flask 的入口程序中啟動定時(shí)任務(wù)了

importos
fromappimportcreate_app,scheduler


app=create_app(os.getenv('FLASK_CONFIG')or'default')


if__name__=='__main__':
scheduler.start()
app.run(debug=True)

編寫 API

熱榜列表 API

我們首先來做熱榜列表的接口,在數(shù)據(jù)庫表 ZhihuMetrics 中拿到當(dāng)天熱榜的最新熱度信息,然后再根據(jù)熱榜熱度信息來獲取對應(yīng)的列表信息,可以總結(jié)到如下的一個(gè)函數(shù)中

defzhihudata():
current_time='%s-%s-%s00:00:00'%(datetime.now().year,datetime.now().month,datetime.now().day,)
zhihumetrics_data=ZhihuMetrics.query.filter(ZhihuMetrics.update_time>current_time).group_by(ZhihuMetrics.hot_cardid).order_by(ZhihuMetrics.update_time).all()
metrics_list=db_opera.db_to_list(zhihumetrics_data)
details_list=[]
fordinmetrics_list:
zhihudetails_data=ZhihuDetails.query.filter_by(hot_cardid=d[1]).first()
details_list.append([zhihudetails_data.hot_name,zhihudetails_data.hot_link,d[0],d[1],d[2]])

returndetails_list

接著定義一個(gè)視圖函數(shù)返回 json 數(shù)據(jù)

@api.route('/api/zhihu/hot/')
defzhihu_api_data():
zhihu_data=zhihudata()
data_list=[]
fordatainzhihu_data:
data_dict={'title':data[0],'link':data[1],'metrics':data[2],'hot_id':data[3],'update_time':data[4]}
data_list.append(data_dict)

returnjsonify({'code':0,'content':data_list}),200

熱榜詳情 API

下面再來做熱榜詳情接口,該接口可以返回?zé)岚駸岫茸邉菪畔?,為前端畫圖提供數(shù)據(jù)。

defzhihudetail(hot_id):
zhihumetrics_details=ZhihuMetrics.query.filter_by(hot_cardid=hot_id).order_by(ZhihuMetrics.update_time).all()
Column={'categories':[],'series':[{'name':'熱度走勢','data':[]}]}

foriinzhihumetrics_details:
Column['categories'].append(datetime.strftime(i.update_time,"%Y-%m-%d%H:%M"))
Column['series'][0]['data'].append(int(i.hot_metrics.split()[0]))

returnColumn



@api.route('/api/zhihu/detail/<id>/')
defzhihu_api_detail(id):
zhihu_detail=zhihudetail(id)
returnjsonify({'code':0,'data':zhihu_detail}),200

接入小程序

對于小程序端,我們這里使用了 uni-app 框架,這是一個(gè)可以一份代碼多端運(yùn)行的框架,還是比較不錯(cuò)的。

創(chuàng)建項(xiàng)目

首先通過 IDE HBuilder 創(chuàng)建一個(gè) uni-app 模板

太好玩了,爬蟲、部署API、加小程序,一條龍玩轉(zhuǎn)知乎熱榜

改造項(xiàng)目

我們簡單改造下該模板,首先修改下 index.nvue 文件,把 tabList 修改如下

data(){
return{
tabList:[{
id:"tab01",
name:'知乎熱榜',
newsid:0
},{
id:"tab02",
name:'微博熱榜',
newsid:23
},

我們暫時(shí)只保留兩個(gè) tab 頁簽,沒錯(cuò)后面還要再做微博的熱榜!

接下來打開 news-page.nvue 文件,修改網(wǎng)絡(luò)請求地址

uni.request({

url:'http://127.0.0.1:5000/api/zhihu/hot/',
data:'',

把 URL 地址指向我們自己的 API 服務(wù)地址

然后再添加我們自己的新聞參數(shù)

hot_id:news.hot_id,
metrics:news.metrics,
news_url:news.link

再修改函數(shù) goDetail 如下

goDetail(detail){
if(this.navigateFlag){
return;
}
this.navigateFlag=true;
uni.navigateTo({
url:'/pages/detail/detail-new?query='+encodeURIComponent(JSON.stringify(detail))
});
setTimeout(()=>{
this.navigateFlag=false;
},200)
},

點(diǎn)擊每條熱榜時(shí),就會跳轉(zhuǎn)到 url 對應(yīng)的 /pages/detail/detail-new 頁面

引入 uCharts

下面編寫 detail-new.nvue 文件,這里主要用到了 uni-app 的插件 uCharts。這是一個(gè)高性能的跨端圖表插件,非常好用。

template 部分

<template>
<viewclass="qiun-columns">
<viewclass="qiun-bg-whiteqiun-title-barqiun-common-mt">
<viewclass="qiun-title-dot-light">柱狀熱力分布</view>
</view>
<viewclass="qiun-charts">
<canvascanvas-id="canvasColumn"id="canvasColumn"class="charts"@touchstart="touchColumn"></canvas>
</view>

<viewclass="qiun-bg-whiteqiun-title-barqiun-common-mt">
<viewclass="qiun-title-dot-light">線性走勢</view>
</view>
<viewclass="qiun-charts">
<canvascanvas-id="canvasLine"id="canvasLine"class="charts"@touchstart="touchColumn"></canvas>
</view>
</view>
</template>

創(chuàng)建兩個(gè) view,分別用于展示柱狀圖和折線圖

再編寫 script 部分

getServerData(){
uni.request({
url:'http://127.0.0.1:5000/api/zhihu/detail/'+this.details.hot_id,
data:{
},
success:function(res){
_self.serverData=res.data.data;
letColumn={categories:[],series:[]};
Column.categories=res.data.data.categories;
Column.series=res.data.data.series;
_self.showColumn("canvasColumn",Column);
_self.showLine("canvasLine",Column);
},
fail:()=>{
_self.tips="網(wǎng)絡(luò)錯(cuò)誤,小程序端請檢查合法域名";
},
});
}

再根據(jù) uCharts 的官方文檔編寫對應(yīng)的展示圖表函數(shù)

showColumn(canvasId,chartData){
canvaColumn=newuCharts({
$this:_self,
canvasId:canvasId,
type:'column',
legend:{show:true},
fontSize:11,
background:'#FFFFFF',
pixelRatio:_self.pixelRatio,
animation:true,
categories:chartData.categories,
series:chartData.series,
enableScroll:true,
xAxis:{
disableGrid:true,
scrollShow:true,
itemCount:4,
},
yAxis:{
//disabled:true
},
dataLabel:true,
width:_self.cWidth*_self.pixelRatio,
height:_self.cHeight*_self.pixelRatio,
extra:{
column:{
type:'group',
width:_self.cWidth*_self.pixelRatio*0.45/chartData.categories.length
}
}
});

}

這樣,我們就完成了基本的項(xiàng)目開發(fā)

我們可以到小程序的模擬器來查看效果啦

熱榜列表頁面

太好玩了,爬蟲、部署API、加小程序,一條龍玩轉(zhuǎn)知乎熱榜

熱榜詳情頁面

太好玩了,爬蟲、部署API、加小程序,一條龍玩轉(zhuǎn)知乎熱榜

基本的效果是有了,不過還有很多需要優(yōu)化的地方,下一次,我會分享出優(yōu)化后的代碼以及如何把 API 服務(wù)部署到云端,同時(shí)還是提供出供大家練習(xí)的 API,不要錯(cuò)過哦!

好啦!今天的分享到這里就結(jié)束了,希望大家持續(xù)關(guān)注馬哥教育官網(wǎng),每天都會有大量優(yōu)質(zhì)內(nèi)容與大家分享!聲明:文章轉(zhuǎn)載于網(wǎng)絡(luò),版權(quán)歸原作者所有,如有侵權(quán)請及時(shí)聯(lián)系!

相關(guān)新聞

歷經(jīng)多年發(fā)展,已成為國內(nèi)好評如潮的Linux云計(jì)算運(yùn)維、SRE、Devops、網(wǎng)絡(luò)安全、云原生、Go、Python開發(fā)專業(yè)人才培訓(xùn)機(jī)構(gòu)!