后台经验总结

这篇文章想在面试季之前对做过的所有与后端相关的项目做一个相应的汇总,包括以下几个部分:

-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'

(.*)')#提取内容的正则表达式 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文件。

你可能感兴趣的:(python,java)