後臺經驗總結

這篇文章想在面試季之前對做過的所有與後端相關的項目做一個相應的彙總,包括以下幾個部分:

-1、爬蟲
-2、Django框架
-3、Springboot框架

爬蟲

需要注意以下幾點:

  • 1、關於python的語言特性:
    由於python存在全局鎖機制(GIL),導致其在進行多線程的操作時並不是真正的多線程,對於一些CPU密集型的操作而言甚至會比單線程操作還慢。但是對於爬蟲這種異步I/O操作,多線程模式下速度就顯得很可觀了。
  • 2、關於get/post區別以及常用的header頭部信息:
    在爬蟲的請求頭部信息之中,只需要把握住兩個信息USER-AGENT來辨別你究竟是否是機器,以及COOKIE信息以防止在讀取過多頁面時請求失效。
    如果你對網絡信息進行抓包的話,最常用的請求信息由三種GET、POST、CONNECT。CONNECT往往用於受限的網絡環境之中,常常客戶端訪問服務器需要代理,且採用HTTPS進行訪問時會出現CONNECT包。而GET方法於POST方法作爲前後端交互最常用的兩種方法, 最直觀的就是語義上的區別,1、get用於獲取數據,post用於提交數據。2. get參數有長度限制(受限於url長度,具體的數值取決於瀏覽器和服務器的限制),而post無限制。
  • 3、改進措施:
    開啓多進程或都線程的方式,我們是無法無限制地開啓多進程或多線程的:在遇到要同時響應成百上千路的連接請求,則無論多線程還是多進程都會嚴重佔據系統資源,降低系統對外界響應效率,而且線程與進程本身也更容易進入假死狀態。考慮使用“線程池”或“連接池”。“線程池”旨在減少創建和銷燬線程的頻率,其維持一定合理數量的線程,並讓空閒的線程重新承擔新的執行任務。“連接池”維持連接的緩存池,儘量重用已有的連接、減少創建和關閉連接的頻率。這兩種技術都可以很好的降低系統開銷,都被廣泛應用很多大型系統,如websphere、tomcat和各種數據庫等。
import urllib
import urllib.request
from bs4 import BeautifulSoup
import re
from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor

#這裏定義兩個變量,一個存儲電影信息,一個存儲頁面信息
atl={}
page_set=set()

def search_info(value):
    url_values=urllib.parse.urlencode(value)
    url="https://movie.douban.com/subject_search?"+url_values+"&cat=1002"
    headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36 Edge/15.15063',
        'Cookie':'bid=AcGP1hAxgzc; __yadk_uid=sk9vChSfDhNf8KsrXzfQ2rEZpYub6Ad1; ue="[email protected]"; gr_user_id=269c198e-b35e-4a2d-823e-57d96c0b1e3d; viewed="1651032_10429536_26295140_3083546_25727531_3879823_11519143"; _ga=GA1.2.1723306564.1494480349; ps=y; ll="108296"; push_noty_num=0; push_doumail_num=0; ct=y; _pk_ref.100001.4cf6=%5B%22%22%2C%22%22%2C1512662283%2C%22https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DWf9fcbu190F5xJk92yTLzdSq0LkpoPqBKqsoNOPsYL1xcmfQUbLGDFe2ErHc3OT5t1VMy_Xx74s5zkgiKvpjxK%26wd%3D%26eqid%3Da62d351b00057c500000000359e35f27%22%5D; ap=1; __utmt=1; _vwo_uuid_v2=AD65B84526727D1C768A09C0A79AD4DB|e0fec646c1a6e058bf05eeda289ecf31; _pk_id.100001.4cf6=80aa6c4a3dfb6148.1494480349.19.1512666501.1508073270.; _pk_ses.100001.4cf6=*; __utma=30149280.1723306564.1494480349.1511200103.1512662284.37; __utmb=30149280.11.10.1512662284; __utmc=30149280; __utmz=30149280.1511200103.36.25.utmcsr=baidu|utmccn=(organic)|utmcmd=organic; __utmv=30149280.5471; __utma=223695111.1215516402.1494480349.1512662291.1512664108.19; __utmb=223695111.0.10.1512664108; __utmc=223695111; __utmz=223695111.1508073230.17.11.utmcsr=baidu|utmccn=(organic)|utmcmd=organic'}
    req = urllib.request.Request(url,headers=headers)
    response = urllib.request.urlopen(req)
    html = response.read().decode('utf-8')
    html_data=BeautifulSoup(html,'lxml')
    return html_data

#將網頁的鏈接讀取爲url模塊:
def html_read(url):
    html_data=BeautifulSoup(urllib.request.urlopen(url).read().decode('UTF-8'),'lxml')
    return html_data

#查找網頁信息
def page_info(html_data):
    a=page_set
    find_pages=re.compile(r'(.*)movie(.*)subject_search(.*)cat')#生成匹配模式
    try:
        for i in html_data:
            if find_pages.search(i['href']):#使用search模塊,如果能匹配到,則滿足要求
                a.add(i['href'])
        return page_set
    except:
        pass
#這一段代碼找出其中含有attribute:onclick的電影,這裏將value_info信息添加到電影信息中來,以便評價。
def movie_info(html_data):
    for i in html_data:
        if i.has_attr('onclick') and i.has_attr('title'):
            atl[i['title']]={'url':i['href']}
            try:
                data=str(html_read(i['href']).find_all('strong'))
                value_rate=re.compile(r'\d.\d')
                value=value_rate.findall(data)
                atl[i['title']]['value']=value[0]
            except:
                atl[i['title']]['value']="該電影還未上映"
    return atl
if __name__ == '__main__':
    input_value={}
    input_value['search_text']=input('請輸入你想查找的電影')
    pages=search_info(input_value).find_all(name='a')
    if page_info(pages):
         for url in page_info(pages):
                page=html_read(url).find_all(name='a')
                movie_info(page)
    else:
        movie_info(pages)
    print(atl)

#文件讀取默認是隻讀以文本對象rt形式,可以講文件直接轉化爲列表讀取。f.tell()尋找文件指針,f.seek()重新設置文件指針。要寫入文件,必須要有w/a
##輸入第一個評論界面,輸出爲下一頁評論界面:
def next_comment_page(url):
    movie_ID=subject
    html_data=BeautifulSoup(urllib.request.urlopen(url).read().decode('UTF-8'),'lxml')
    try:
        next_info=data.find_all(name='a',attrs={'class':'next'})
        new_url='https://movie.douban.com/subject/'+movie_ID+'/comments'+next_info[0].get('href')
        return new_url
    except:
        return False
#該段代碼提取出其中的評論信息,保存爲列表形式(代碼中包含測試信息):
def page_comment_info(url,filepath):
    global comment_url
    html_data=html_read(url)
    comment_info=html_data.find_all(name='p',attrs={'class':""},text=True)
    content_data=re.compile(r'<p class="">(.*)')#提取內容的正則表達式
    filepath=open('D:/coment.txt','wt')
    lock.acquire()
    for cmt in comment_info:
        comts=content_data.findall(str(cmt))
        try:
            filepath.write(str(comts))
        except:
            pass
    #這裏除了寫入要加鎖,對於next_comment_page的設置也要加鎖
    comment_url=next_comment_page(comment_url)
    lock.release()                     #在此處加入同步原語:鎖機制
    f.close()

f=open('D:/coment.txt','wt')
movie_id=re.compile('\d+')
subject=movie_id.findall(atl['美國隊長3']['url'])[0]
coment_url='https://movie.douban.com/subject/'+subject+'/comments?status=P'
page_comment_info(coment_url)
#手動創建一個線程池
thread1=Thread(target=page_comment_info(comment_url))
thread2=Thread(target=page_comment_info(comment_url))
thread3=Thread(target=page_comment_info(comment_url))
threads=[thread1,thread2,thread3]
try:
    while next_comment_page(comment_url):
        comment_url=next_comment_page(comment_url)
        page_comment_info(comment_url)
        print('正在提取>>>>>>>'+comment_url+'頁面的評論信息')
     for i in threads:
         i.start()
except:
    print('信息提取完畢')
    f.close()

關於Django框架:

在之前的博客之中已經做了許多的介紹,包括MTV的模式以及搭建的各種細節(坑),我嘗試在樹莓派上搭建了Django服務器並復現了官網上博客的相關功能。需要注意的是Django之中的C(controller部分)已經被模板自動實現,所以其更關注MTV模式(鬆耦合特性)
在配置文件中,通常需要注意以下幾點
URL匹配規則:1、首先精確匹配。 2、最長路徑匹配。 3、最後根據後綴進行匹配。
基本流程:1、模塊在主程序中進行註冊。 2、通過setting之中的urls將不同的urls導入到不同模塊之中的url之中去。
3、不同模塊之間的url最終根據此url匹配規則,匹配到對應的視圖(view模塊之中)。4、視圖層(view)處理對應的HTTP GET/POST方法,往往是對於Models之中ORM對應的數據庫對象進行操作。最終返html模板。
本質上:MYV的三大模塊是這樣一個意思:M代表數據本身的特點。V代表後臺數據的處理模塊。T代表前端數據的呈現模塊即最終的HTML文件。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章