上一篇<學(xué)習(xí)MVC之租房網(wǎng)站(十一)-定時任務(wù)和云存儲>學(xué)習(xí)了Quartz的使用、發(fā)郵件,并將通過UEditor上傳的圖片保存到云存儲。在項目的最后,再學(xué)習(xí)優(yōu)化網(wǎng)站性能的一些技術(shù):緩存和頁面靜態(tài)化。
使用緩存可以降低數(shù)據(jù)庫的壓力,而使用頁面靜態(tài)化則可以降低Web服務(wù)器的壓力。
一 緩存
ASP.NET下可用的緩存為System.Web.Caching.Cache,保存在服務(wù)器內(nèi)存中,不適用于服務(wù)器集群,雖然也用沒用過集群,但現(xiàn)在的主流都使用NoSQL數(shù)據(jù)庫來做緩存,典型的有Redis和Memcached,這類緩存技術(shù)支持集群部署,而且如果使用獨立的服務(wù)器,便可不受主服務(wù)器宕機的影響,Redis更是支持把數(shù)據(jù)持久化到硬盤。Redis和Memcached的應(yīng)用需要專門學(xué)習(xí)實踐,這兒只是代替普通Cache來掌握基本的使用。
a) Memcached基礎(chǔ)
Memcached最適合的操作系統(tǒng)是Linux,在VS中可以從Nuget安裝EnyimMemcached來使用。首先要讓Memcached運行起來,在生產(chǎn)環(huán)境會作為服務(wù)運行,在學(xué)習(xí)階段只是每次使用前啟動控制臺就行了。
需要緩存的對象要被標(biāo)記為Serializable,而且與該對象關(guān)聯(lián)的對象也需要標(biāo)記可序列化。存取方法為:
b) Redis基礎(chǔ)
Redis使用Json格式的序列化方式,所以不需要像Memcached那樣標(biāo)記Serializable,而且Memcached只能在內(nèi)存保存數(shù)據(jù),Redis還可以將數(shù)據(jù)持久化到硬盤。在學(xué)習(xí)應(yīng)用時,也是在使用前啟動其控制臺:
使用方式和Memcached類似,首先安裝ServiceStack.Redis,存取代碼為:
二 頁面靜態(tài)化
緩存可以降低數(shù)據(jù)庫讀取的壓力,但在網(wǎng)站收到訪問請求后,仍然每次都要跑一遍取得Model、渲染View的過程,而通過將頁面靜態(tài)化可以規(guī)避這個過程造成的壓力。比如用戶訪問ID為249的房源頁面時,原本是要通過House/Detail/249實時渲染,但現(xiàn)在就可以直接訪問對應(yīng)的249.html文件,這實際上是將渲染頁面的動作提前到了新增249房源的時刻,在249房源保存到系統(tǒng)時隨即生成其html頁面,以后服務(wù)器只需要直接返回這個頁面,運算量大大減少,而且相比以前的實時渲染,靜態(tài)頁面只需要渲染一次(不包括修改數(shù)據(jù)后的重新靜態(tài)化)。
新增房源后,渲染靜態(tài)化頁面的代碼為:
調(diào)用方法:string html=MVCHelper.RenderViewToString(this.ControllerContext, @"~/Views/House/StaticIndex.cshtml", model);
除了新增,每次修改房源信息,也要重新生成靜態(tài)頁面,以保證信息的同步。
注:
課程內(nèi)容來自如鵬網(wǎng)(www.rupeng.com),專注于大學(xué)生就業(yè)的在線教育平臺;
ASP.NET MVC課程 http://www.rupeng.com/News/9/640.shtml
在這里我就不再一一介紹每個步驟的具體操作了,因為在爬取老版數(shù)據(jù)的時候都已經(jīng)講得非常清楚了,所以在這里我只會在重點上講述這個是這么實現(xiàn)的,如果想要看具體步驟請先去看我的文章內(nèi)容,里面有非常詳細(xì)的介紹以及是怎么找到加密js代碼和api接口。
私信小編01即可獲取大量Python學(xué)習(xí)資料
58同城的數(shù)據(jù)爬取非常簡單,唯一有點難的就是字體的加密,除此之外其他的數(shù)據(jù)用xpath即可獲取。
想爬取不同地方的直接訪問鏈接即可:
數(shù)據(jù)在鏈接中,直接請求獲取即可。
既然是字體加密那么就先把字體尋找出來,尋找簡單,在開發(fā)者工具中的分類找到Font,然后搜索這個鏈接進行查找。
已經(jīng)找到這個字體了,他是在請求頁面的時候返回的,然后他還是個base64的,只需要轉(zhuǎn)換一下再保存就可以了。
import requests
from lxml import etree
def get_data():
url="https://bj.58.com/chuzu/?PGTID=0d200001-0000-11e9-58e6-a658f219b27c&ClickID=1"
headers={
'authority': 'bj.58.com',
'method': 'GET',
'path': '/chuzu/?PGTID=0d200001-0000-11e9-58e6-a658f219b27c&ClickID=1',
'scheme': 'https',
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'accept-encoding': 'gzip, deflate, br',
'accept-language': 'zh-CN,zh;q=0.9',
'cache-control': 'max-age=0',
'cookie': 'f=n; commontopbar_new_city_info=1%7C%E5%8C%97%E4%BA%AC%7Cbj; commontopbar_ipcity=bj%7C%E5%8C%97%E4%BA%AC%7C0; userid360_xml=C0E9739B2022549506AFBC01231A1DAA; time_create=1606640420140; xxzl_cid=f4a781439d9247f393d0a1629bec00df; xzuid=e0e5ea78-ac5a-491b-819d-a869ab37a7a7; xxzl_deviceid=2G3xFS3qwOviMHxtC%2FVEituhpmiI%2FJ%2BAmJ08cPBulZSe7LcSgT98WgFcyNDbzMXJ; id58=c5/nfF+bz1xVS0tAA7tjAg==; 58tj_uuid=116f1ed0-7c25-477e-8887-be3602fa2389; new_uv=1; utm_source=; spm=; init_refer=https%253A%252F%252Fbj.58.com%252Fchuzu%252Fsub%252Fpn70%252F%253Fpagetype%253Dditie%2526PGTID%253D0d3090a7-0000-1b87-3e2e-c6efe8d19973%2526ClickID%253D2; wmda_uuid=13712f08f0e555f110b1b2684ce9d709; wmda_new_uuid=1; wmda_session_id_11187958619315=1604046685879-d3ad7e5f-77f6-29d7; wmda_visited_projects=%3B11187958619315; als=0; f=n; new_session=0',
'sec-fetch-dest': 'document',
'sec-fetch-mode': 'navigate',
'sec-fetch-site': 'none',
'sec-fetch-user': '?1',
'upgrade-insecure-requests': '1',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36'
}
response=requests.get(url=url, headers=headers)
return response.text
def get_font(data):
html=etree.HTML(data)
script=html.xpath('//script[2]/text()')[0]
ttf=re.findall(".*?src:url\(\'data:application/font-ttf;charset=utf-8;base64,(.*?)\'\).*?",script,re.S)[0]
with open('fangchan-secret.ttf','wb') as f:
f.write(base64.b64decode(ttf))
if __name__=='__main__':
data=get_data()
get_font(data)
import base64
from fontTools.ttLib import TTFont
import re
import requests
from lxml import etree
def get_data():
url="https://bj.58.com/chuzu/?PGTID=0d200001-0000-11e9-58e6-a658f219b27c&ClickID=1"
headers={
'authority': 'bj.58.com',
'method': 'GET',
'path': '/chuzu/?PGTID=0d200001-0000-11e9-58e6-a658f219b27c&ClickID=1',
'scheme': 'https',
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'accept-encoding': 'gzip, deflate, br',
'accept-language': 'zh-CN,zh;q=0.9',
'cache-control': 'max-age=0',
'cookie': 'f=n; commontopbar_new_city_info=1%7C%E5%8C%97%E4%BA%AC%7Cbj; commontopbar_ipcity=bj%7C%E5%8C%97%E4%BA%AC%7C0; userid360_xml=C0E9739B2022549506AFBC01231A1DAA; time_create=1606640420140; xxzl_cid=f4a781439d9247f393d0a1629bec00df; xzuid=e0e5ea78-ac5a-491b-819d-a869ab37a7a7; xxzl_deviceid=2G3xFS3qwOviMHxtC%2FVEituhpmiI%2FJ%2BAmJ08cPBulZSe7LcSgT98WgFcyNDbzMXJ; id58=c5/nfF+bz1xVS0tAA7tjAg==; 58tj_uuid=116f1ed0-7c25-477e-8887-be3602fa2389; new_uv=1; utm_source=; spm=; init_refer=https%253A%252F%252Fbj.58.com%252Fchuzu%252Fsub%252Fpn70%252F%253Fpagetype%253Dditie%2526PGTID%253D0d3090a7-0000-1b87-3e2e-c6efe8d19973%2526ClickID%253D2; wmda_uuid=13712f08f0e555f110b1b2684ce9d709; wmda_new_uuid=1; wmda_session_id_11187958619315=1604046685879-d3ad7e5f-77f6-29d7; wmda_visited_projects=%3B11187958619315; als=0; f=n; new_session=0',
'sec-fetch-dest': 'document',
'sec-fetch-mode': 'navigate',
'sec-fetch-site': 'none',
'sec-fetch-user': '?1',
'upgrade-insecure-requests': '1',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36'
}
response=requests.get(url=url, headers=headers)
return response.text
def get_font(data):
html=etree.HTML(data)
script=html.xpath('//script[2]/text()')[0]
ttf=re.findall(".*?src:url\(\'data:application/font-ttf;charset=utf-8;base64,(.*?)\'\).*?",script,re.S)[0]
with open('fangchan-secret.ttf','wb') as f:
f.write(base64.b64decode(ttf))
def parse_font():
font=TTFont('fangchan-secret.ttf')
bestcmap=font['cmap'].getBestCmap()
newmap=dict()
for key in bestcmap.keys():
value=int(re.search(r'(\d+)', bestcmap[key]).group(1)) - 1
key=hex(key)
newmap[key]=value
print(newmap)
if __name__=='__main__':
data=get_data()
get_font(data)
parse_font()
我們發(fā)現(xiàn)字體編號和之前的不符合,比如:0x9476=7,而這里的是2,這是什么原因呢?是因為他的字體是動態(tài)生成的,每次返回的數(shù)字編號對應(yīng)的值都是不同的,但是不影響我們代碼的正常運行與結(jié)果。
import base64
from fontTools.ttLib import TTFont
import re
import requests
from lxml import etree
def get_data():
url="https://bj.58.com/chuzu/?PGTID=0d200001-0000-11e9-58e6-a658f219b27c&ClickID=1"
headers={
'authority': 'bj.58.com',
'method': 'GET',
'path': '/chuzu/?PGTID=0d200001-0000-11e9-58e6-a658f219b27c&ClickID=1',
'scheme': 'https',
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'accept-encoding': 'gzip, deflate, br',
'accept-language': 'zh-CN,zh;q=0.9',
'cache-control': 'max-age=0',
'cookie': 'f=n; commontopbar_new_city_info=1%7C%E5%8C%97%E4%BA%AC%7Cbj; commontopbar_ipcity=bj%7C%E5%8C%97%E4%BA%AC%7C0; userid360_xml=C0E9739B2022549506AFBC01231A1DAA; time_create=1606640420140; xxzl_cid=f4a781439d9247f393d0a1629bec00df; xzuid=e0e5ea78-ac5a-491b-819d-a869ab37a7a7; xxzl_deviceid=2G3xFS3qwOviMHxtC%2FVEituhpmiI%2FJ%2BAmJ08cPBulZSe7LcSgT98WgFcyNDbzMXJ; id58=c5/nfF+bz1xVS0tAA7tjAg==; 58tj_uuid=116f1ed0-7c25-477e-8887-be3602fa2389; new_uv=1; utm_source=; spm=; init_refer=https%253A%252F%252Fbj.58.com%252Fchuzu%252Fsub%252Fpn70%252F%253Fpagetype%253Dditie%2526PGTID%253D0d3090a7-0000-1b87-3e2e-c6efe8d19973%2526ClickID%253D2; wmda_uuid=13712f08f0e555f110b1b2684ce9d709; wmda_new_uuid=1; wmda_session_id_11187958619315=1604046685879-d3ad7e5f-77f6-29d7; wmda_visited_projects=%3B11187958619315; als=0; f=n; new_session=0',
'sec-fetch-dest': 'document',
'sec-fetch-mode': 'navigate',
'sec-fetch-site': 'none',
'sec-fetch-user': '?1',
'upgrade-insecure-requests': '1',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36'
}
response=requests.get(url=url, headers=headers)
return response.text
def get_font(data):
html=etree.HTML(data)
script=html.xpath('//script[2]/text()')[0]
ttf=re.findall(".*?src:url\(\'data:application/font-ttf;charset=utf-8;base64,(.*?)\'\).*?",script,re.S)[0]
with open('fangchan-secret.ttf','wb') as f:
f.write(base64.b64decode(ttf))
def parse_font():
font=TTFont('fangchan-secret.ttf')
bestcmap=font['cmap'].getBestCmap()
newmap=dict()
for key in bestcmap.keys():
value=int(re.search(r'(\d+)', bestcmap[key]).group(1)) - 1
key=hex(key)
newmap[key]=value
return newmap
def parse_data(data,newmap):
for key,value in newmap.items():
key_=key.replace('0x','') + ';'
if key_ in data:
data=data.replace(key_,str(value))
html=etree.HTML(data)
house_list=html.xpath('//ul[@class="house-list"]/li')[:-1]
for house in house_list:
room=house.xpath('.//p[@class="room"]/text()')[0]
money=house.xpath('.//b[@class="strongbox"]/text()')[0]
print(room,money)
if __name__=='__main__':
data=get_data()
get_font(data)
newmap=parse_font()
parse_data(data,newmap)
源字節(jié)的租房小程序一個關(guān)于房屋租賃類的APP,用的uni-app實現(xiàn) ,這種app少不了的就是經(jīng)紀(jì)人,位置信息。我們的代碼開源免費,歡迎交流使用。
map地圖組件使用時直接在template中使用<map></map>標(biāo)簽,標(biāo)簽中可嵌套map屬性
map最常用到的屬性:
longitude 中心經(jīng)度
latitude 中心緯度
scale 縮放級別(取值范圍為5-18,默認(rèn)的是16 ,值數(shù)越大,放大程度越大,看的越細(xì))
markers 標(biāo)記點 (類型為Array數(shù)組,在地圖上標(biāo)記出來的點)
polyline(類型為Array數(shù)組,沒有默認(rèn)值,表示路線,數(shù)組上的所有點連成線)
circles(類型Array數(shù)組,表示圓)
controls(類型Array數(shù)組,表示控件)
include-points(類型Array數(shù)組,表示縮放視野已包含所有給定的坐標(biāo)點)
show-compass(類型為Boolean,默認(rèn)值為false,表示為是否顯示指南針)
enable-overlooking(類型為Boolean,默認(rèn)值為false,表示為是否開啟俯視)
enable-satellite(類型為Boolean,默認(rèn)值為false,表示為是否開啟衛(wèi)星圖)
enable-traffic(類型為Boolean,默認(rèn)值為false,表示為是否開啟實時路況)
show-location(類型為Boolean,表示顯示帶有方向的當(dāng)前定位點)
polygons(類型Array,表示為多邊形)
markers的屬性有(表示標(biāo)記點用于在地圖上顯示標(biāo)記的位置)
id:標(biāo)記點id(marker點擊事件回調(diào)會返回此id)
latitude:緯度(范圍 -90 ~ 90 )
longitude:經(jīng)度(范圍 -180 ~ 180 )
title:標(biāo)注點名
iconPath:顯示的圖標(biāo)
rotate:旋轉(zhuǎn)角度(順時針旋轉(zhuǎn)的角度,范圍 0 ~ 360,默認(rèn)為 0 )
alpha:標(biāo)注的透明度( 默認(rèn)1,無透明,范圍 0 ~ 1)
width:標(biāo)注圖標(biāo)寬度(默認(rèn)為圖片實際寬度 )
height:標(biāo)注圖標(biāo)高度(默認(rèn)為圖片實際高度 )
callout:自定義標(biāo)記點上方的氣泡窗口
label:為標(biāo)記點旁邊增加標(biāo)簽
anchor:經(jīng)緯度在標(biāo)注圖標(biāo)的錨點
callout的屬性有
content:文本
color:文本顏色
fontSize:文字大小
borderRadius:callout邊框圓角
bgColor:背景色
padding:文本邊緣留白
display:BYCLICK':點擊顯示;'ALWAYS':常顯
textAlign:文本對齊方式
label的屬性有
content:文本
color:文本顏色
fontSize:文字大小
x:label的坐標(biāo),原點是 marker 對應(yīng)的經(jīng)緯度
y:label的坐標(biāo),原點是 marker 對應(yīng)的經(jīng)緯度
borderWidth:邊框?qū)挾?/span>
borderColor:邊框顏色
borderRadius:callout邊框圓角
bgColor:背景色
padding:文本邊緣留白
textAlign:文本對齊方式
polyline的屬性有(表示指定一系列坐標(biāo)點,從數(shù)組第一項連線至最后一項)
points,經(jīng)緯度數(shù)組,類型為Array,必填,如:[{latitude: 0, longitude: 0}]
color,線的顏色,類型為String,不必填,如:#0000AA
width,線的寬度,類型為Number,不必填
dottedLine,是否虛線,類型為Boolean,不必填,默認(rèn)值false
arrowLine,帶箭頭的線,類型為Boolean,不必填,默認(rèn)值為false
arrowIconPath,更換箭頭圖標(biāo),類型為String,不必填,在arrowLine為true時,默認(rèn)帶箭頭的線時生效
borderColor,線的邊框顏色,類型為String,不必填
borderWidth,線的厚度,類型為Number,不必填
circles 的屬性有(在地圖上顯示圓)
latitude,緯度,Number,必填,浮點數(shù),范圍 -90 ~ 90
longitude,經(jīng)度,Number,必填,浮點數(shù),范圍-180 ~ 180
color,描邊的顏色,String,不必填,如:#0000AA
fillColor,填充顏色,String,不必填,如:#0000AA
radius,半徑,Number,必填
strokeWidth,描邊的寬度,Number,不必填
controls 控件 (在地圖上顯示一個控件,但是這個控件并不隨著地圖移動)
id:控件id(在控件點擊事件回調(diào)會返回此id)
position:控件在地圖的位置(控件相對地圖位置)
iconPath:顯示的圖標(biāo)(項目目錄下的圖片路徑)
clickable:是否可點擊(默認(rèn)不可點擊)
附上代碼
<template>
<view>
<view>
<map :latitude="latitude" :longitude="longitude"
:markers="covers"
@click="clickMap">
</map>
</view>
</view>
</template>
<script>
export default {
data() {
return {
title: 'map',
name: '杭州市',
address: '杭州市拱墅區(qū)萬達(dá)廣場',
latitude: 30.31968,
longitude: 120.14209,
covers: [{
latitude: 30.31968,
longitude: 120.14209,
iconPath: '../../../static/location.png',
}]
}
},
methods:{
clickMap(e){
console.log(e);
uni.openLocation({
longitude: Number(this.longitude),
latitude: Number(this.latitude),
name: this.name,
address: this.address
})
},
}
}
</script>
<style>
map {
width: 100%;
height: 450rpx;
}
</style>
如若轉(zhuǎn)載,請注明出處:開源字節(jié) https://sourcebyte.cn/article/247.html
*請認(rèn)真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。