Nginx + uWSGI + Python + Django构建必应高清壁纸站

写在前面

作这个网站的初衷是由于,每次打开必应搜索搜东西的时候都会被上面的背景图片吸引,我想必应的壁纸应该是通过专业人员精选出来的,我甚至会翻看之前的历史图片,惟一美中不足的是必应的首页只能查看最多7天的壁纸。因此我萌生出本身建一个网站,天天定时搜集必应的壁纸,将壁纸信息保存在数据库中,这样就能够看到好久以前的壁纸图片了。网站使用的是python的django框架,前端接入使用了nginx+uwsgi。没什么特别的考虑,其实网站自己没什么技术含量,使用python的django入手仍是很快的,固然用nodejs+express也是不错的(其实个人node比python熟,想折腾点新东西哈哈)。我在这里写出步骤来,给刚刚上手的朋友们一个参考。服务器是直接购买的阿里云的,第一年很便宜才100不到好像,1核2G的基础配置带宽也低,不过够用了。域名直接在万网购买,其实也是阿里旗下,备案也很方便,按照提示步骤操做,差很少2周之内就下来了。最终的成果能够到这里先睹为快:必应高清壁纸,必应每日一图javascript

安装python环境

咱们使用的是最新的django框架,须要比较新版本的python环境,阿里云的服务器我购买的时候选择的是centos 6.9,不过我以为操做系统版本对后面的操做影响不大,服务器内置都已经安装有python环境,只不过是python2.6.6比较老的版本了。因此为了使用最新的django 3.0.1,我干脆安装最新的python 3.8.1。这里我本身下载python源码进行编译,安装。 html

wget https://www.python.org/ftp/python/3.8.1/Python-3.8.1.tgz
tar zxvf Python-3.8.1.tgz 
cd Python-3.8.1
./configure 
make
make install

安装好以后,python2.6与python3.8是共存的,咱们可使用python3命令来使用3.8.1版本的python,经过下面的命令能够看到咱们安装的python3.8被安装到的目录:前端

$ which python3
/usr/local/bin/python3
$ ll /usr/local/bin/python3
/usr/local/bin/python3 -> python3.8

跟随python3一块儿安装的还有pip3,是python的包管理工具,python2.x用的是pip,python3.x用的是pip3。接下来咱们安装django框架java

安装django框架

pip3 install django

结果报告下面的错误:node

pip3 install django ssl error

看提示是ssl的版本太低,而python须要更高的版本,使用命令 openssl version 查看获得当前系统安装的openssl的版本是1.0.1e,而python3.8须要openssl版本为1.0.2或者以上的版本。这里咱们安装openssl 1.1.1的版本:python

# 下载源码编译安装
wget https://www.openssl.org/source/openssl-1.1.1a.tar.gz
tar -zxvf openssl-1.1.1a.tar.gz
cd openssl-1.1.1a
./config --prefix=/usr/local/openssl no-zlib 
make
make install

# 替换系统目录中低版本的库
mv /usr/bin/openssl /usr/bin/openssl.bak
mv /usr/include/openssl/ /usr/include/openssl.bak
ln -s /usr/local/openssl/include/openssl /usr/include/openssl
ln -s /usr/local/openssl/lib/libssl.so.1.1 /usr/local/lib64/libssl.so
ln -s /usr/local/openssl/bin/openssl /usr/bin/openssl
ln -s /usr/local/openssl/lib/libssl.so.1.1 /usr/lib64/libssl.so

# 加入库搜索路径并使之生效
echo "/usr/local/openssl/lib" >> /etc/ld.so.conf
ldconfig -v

# 查看openssl版本输出:OpenSSL 1.1.1a  20 Nov 2018
openssl version

这样新版openssl就安装好了,咱们再从新编译并安装Python3,以下:linux

cd Python-3.8.1
./configure --with-openssl=/usr/local/openssl
make
make install

这里的3.8.1编译的时候是添加 --with-openssl=/usr/local/openssl 这个选项,而不是网上的资料说的 --with-ssl 网上说的这个选项是错的,会报错 unrecognized options 。除此之外还有一个问题让我费了点时间值得注意一下,就是在openssl进行make install以后,从新编译python3.8的时候,编译结束老是有下面的错误提示:nginx

Could not build the ssl module!
Python requires an OpenSSL 1.0.2 or 1.1 compatible libssl with X509_VERIFY_PARAM_set1_host().

就是提示找不到ssl,该错误提示仍是由于编译python的时候 -ssl  选项没有找到正确的 libssl.so 的动态库。咱们能够经过下面的命令来肯定当前系统中的ssl动态库的状况:程序员

ldconfig -v | grep ssl 

# 在其输出中咱们要肯定是否还有老的ssl库在里面,实际上在编译提示找不到ssl的时候
# 我经过命令查看的结果发现 /usr/lib64/libssl.so 软链的仍是 1.0.1 的老版本
# 因而我改为链接到新编译的 1.1.1 版本以后,最后看到的是下面的结果

libssl.so.1.1 -> libssl.so.1.1
libssl3.so -> libssl3.so
libssl.so.10 -> libssl.so.1.0.1e

以后再从新编译python就没有报ssl not found的错误了,说明新版ssl已经编译到python3.8.1中,此时咱们再用上面的命令安装django,最后获得下面的提示,表示安装成功完成:web

Installing collected packages: sqlparse, pytz, asgiref, Django
Successfully installed Django-3.0.5 asgiref-3.2.7 pytz-2019.3 sqlparse-0.3.1

这里要注意的是,网络很慢的状况下会常常超时,我以后是经过wget手工下载以后再进行安装的:

wget https://files.pythonhosted.org/packages/a9/4f/8a247eee2958529a6a805d38fbacd9764fd566462fa0016aa2a2947ab2a6/Django-3.0.5-py3-none-any.whl
pip3 install ./Django-3.0.5-py3-none-any.whl

安装成功以后,咱们经过下面的方法验证是否正常:

python3
Python 3.8.1 (default, Apr 18 2020, 00:10:11) 
[GCC 4.4.6 20120305 (Red Hat 4.4.6-4)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import django
>>> print(django.get_version())
3.0.5

就是直接运行python3,打开python3的交互输入,引用django模块,打印出其版本,正确打印出了咱们安装的3.0.5版本,说明安装正常了

配置django

django框架安装正常以后,咱们创建一个简单的django工程testdj以下:

django-admin.py startproject testdj

建立完成以后,会在当前目录下建立一个目录与工程名同名 testdj,咱们看下该目录的结构:

django tree

这样咱们的django项目就建立好了,咱们经过其提供的管理脚本 manage.py 来启动他:

# 注意这里要用python3来运行
python3 manage.py runserver 0.0.0.0:8000

运行以后报错了:

django sqlite3 error

因为django3.0.5版本默认引用了sqlite3的数据库,咱们并无安装sqlite3,因此报错,咱们先在 settings.py 中把这个配置去掉:

settings sqlite3

再次运行以后正常,可是此时咱们还不能在浏览器中访问他,咱们须要编写对应的页面,由于此时项目中什么都没有,连主页都没有,运行成功以下图:

django run ok 

编写视图以及设置url路由

下面咱们为主页的请求编写一个view并配置一下路由规则,让主页请求路由到咱们编写的view上,在上面的目录结构里面,与 settings.py 同一目录下添加文件 view.py 内容以下:

# view.py
from django.http import HttpResponse

def hello(request):
    return HttpResponse("Hello world ! ")

修改urls.py的内容以下:

# urls.py
from django.contrib import admin
from django.urls import path
from django.conf.urls import url
from . import view

urlpatterns = [
    url(r'^$', view.hello),
]

将 settings.py 中的 ALLOWED_HOSTS 配置修改成以下:

# 若是不修改会报相似的错误
# Invalid HTTP_HOST header: 'ip:8000'. You may need to add 'ip' to ALLOWED_HOSTS.
ALLOWED_HOSTS = ['*']

再次启动项目以后,在浏览器经过地址访问获得正确输出:

django view ok

此时咱们的diango顺利启动,下面咱们在django中使用数据库,django中默认配置sqlite3,咱们这里为演示方便,也使用sqlite3做为例子,相信换成其余的数据库不难

在django中使用sqlite3

咱们使用sqlite3这个小巧简单的单文件数据库来作演示,sqlite3虽然结构简单,可是功能可一点不简单,支持大多数常见的sql语法,首先咱们须要安装sqlite3:

wget https://www.sqlite.org/2018/sqlite-autoconf-3240000.tar.gz
tar -xvzf sqlite-autoconf-3240000.tar.gz
cd sqlite-autoconf-3240000/
./configure --prefix=/usr/local/sqlite
make
make install

编译完成以后,咱们须要从新编译与安装python3.8.1,按照上面编译python3的流程从新跑一遍(包括  ./configure --with-openssl=/usr/local/openssl ) ,从新编译python3以后,咱们能够打开python3的输入交互环境,直接在里面 import sqlite3 没有报错,即sqlite3能够在python3中正常使用了,若是有报错的话,按照咱们上面解决 openssl 的思路去定位相似的问题,相信应该很好解决。在调用configure配置python3的时候,会生成 config.log 里面也能够查看到一些出错信息。接下来咱们首先生成一个sqlite3的数据库文件,并建立一个表,插入测试数据,过程以下:

# 咱们的数据库文件的名字取 db.sqlite3
sqlite3 db.sqlite3

create table "tb_message"
(
   "message_id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
   "message_user" varchar(255) NOT NULL, 
   "message_content" text default ''   
);

insert into tb_message(message_user,message_content)values('张三','这是张三发送的消息');
insert into tb_message(message_user,message_content)values('李四','这是李四发送的消息');

将生成的数据库文件的名字放在想要放置的目录下,为了测试方便,咱们将其放在django工程的根目录,咱们将在django项目中读出表的数据并展现到网页上,为了使用django的model,咱们须要先建立一个app,在django工程的根目录下使用下面的命令建立一个名字为djapp的app:

django-admin startapp djapp 

咱们看到建立了一个djapp的文件夹,咱们看看djapp的目录结构:

djapp tree

咱们前面为了顺利运行django项目,将settings.py中关于sqlite的配置注释了,如今咱们须要将这些配置正常化,同时咱们刚才建立的djapp咱们要在 settings.py 配置中添加进来:

# settings.py
# 这里配置了数据库文件所在的路径

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}
...
# Application definition
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'djapp',
]

生成model定义,也就是 djapp/models.py 的内容,在django中,咱们能够本身编写models.py的内容,而后使用相关的命令生成数据库的表结构,反过来咱们能够本身定义好表结构,使用相关命令由表结构去生成model的类定义。我通常习惯于本身定义好数据库的表结构,而后使用命令生成model的类定义,下面咱们生成model类定义到文件 djapp/models.py 中:

# 咱们在manage.py所在的目录运行下面的命令

python3 manage.py inspectdb > djapp/models.py

咱们能够在 djapp/models.py 文件中看到生成的model定义的内容,一个数据库表对应一个class,咱们只建立了一个表,因此文件中只有一个模型类,要注意的是这一步骤的前提是必须在 settings.py 中设置sqlite3的相关配置:

from django.db import models
class TbMessage(models.Model):
    message_id = models.AutoField(primary_key=True)
    message_user = models.CharField(max_length=255)
    message_content = models.TextField(blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'tb_message'

接着咱们修改以前 view.hello 的实现,在里面读取数据库表的记录,并将数据呈现到模板文件中,再编写模板文件以前,咱们须要在 settings.py 中设置模板文件所在的目录:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [BASE_DIR+"/templates"],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

咱们将模板文件放在项目根目录下的 templates 目录下,咱们在此目录下新建一个模板文件 test.tmp 内容以下:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
<title>django test</title>
</head>
<body>
{% for msg in msg_list %}
    <div>用户名:{{ msg.message_user }} 消息:{{ msg.message_content }} </div>
{% endfor %}
</body>
</html>

django的模板提供各类包括if、for、过滤器等丰富的模板标签来控制模板的呈现逻辑,使用过MVC方式编写Web应用程序的应该很容易理解,具体的用法很容易在网络上找到,我也再也不说明了,上面的模板实际上就是将后端返回的数据中对应的model数据呈现到模板文件中,而后返回最终呈现的HTML内容,咱们的 testdj/view.py 的内容以下:

# view .py
from django.http import HttpResponse
from django.shortcuts import render
from django.http import JsonResponse
from djapp.models import TbMessage

def hello(request):
    xlist = TbMessage.objects.all().order_by('message_id')
    msg_list = []
    context={"msg_list":msg_list}
    for msg in xlist:
        msg_list.append({"message_user":msg.message_user,"message_content":msg.message_content})
    return render(request, 'test.tmp', context)

django生成的模板类提供了丰富的访问数据库的能力,包括按各类条件去查询数据库以及进行排序等,另外经过 Model.objects.raw() 函数能够直接写自定义的sql,数据访问这部分更多的函数功能能够查询django的文档,这里也不在浪费篇幅说明了,上述操做好以后,咱们再启动django的项目,输入网址,在网页上就能看到结果了:

django sql ok

至此咱们的django项目已经运行起来了,而且能够访问sqlite3数据库中的数据,咱们列出目前为止整个项目目录的结构以及其说明,方便你们参考:

django all tree

到目前为止咱们运行django项目都是经过项目目录下的 manage.py 进行运行,此种方式仅仅是django为方便调试而提供的一个简易的web服务器,在线上环境咱们确定不能这么使用,那么接下来咱们须要经过 Nginx、uWSGI与django结合的方式搭建能够在线上部署的方案

安装uWSGI

在开始这个话题以前,咱们首先来讲明几个比较重要的概念:

首先要说明的是WSGI,他的全称叫作Web服务器网关接口(Python Web Server Gateway Interface,缩写为WSGI)是为Python语言定义的Web服务器和Web应用程序或框架之间的一种简单而通用的接口。WSGI 不是框架,也不是一个模块而是一个接口规范,是Web服务器与Web应用之间的一种通讯规范,该规范不只仅局限于Python语言,任何语言编写的Web服务器和Web应用程序之间均可以使用WSGI来通讯。WSGI标准在 PEP 333 中定义并被许多框架实现,其中包括现咱们这里的django框架

说了这么多到底WSGI是什么呢,WSGI只是一种规范,是用于Web服务器和Web应用程序之间通讯用的,Web服务器咱们知道是提供HTTP服务的服务端程序,例如Nginx、Apache Http Server、Windows IIS 都是常见的Web服务器程序,那么Web应用程序又是什么呢。讲这个以前咱们须要先回顾一下Web程序的发展历史,HTTP协议出来以后,做为服务端的实现,Web服务器开始只能提供对静态资源的访问,例如html、图片资源等等,像下面的形式:

client server

人们不知足于只获取静态的网页内容,就出现了动态的网页技术,由Web服务器调用一个外部的程序来生成动态的HTML内容返回给浏览器端。而这个外部的程序可使用shell,也可使用perl等脚本编写,或者干脆使用C语言编写,这些程序能够访问外部数据源来生成HTML。那么Web服务器程序与这个生成动态HTML内容的外部程序之间经过什么来传递请求参数呢,Web服务器又经过什么方式来得到并返回由外部程序生成的动态HTML内容呢。由此定义了一个规范,也便是Common Gateway Interface,公共网关接口规范,就是咱们常说的CGI了,这些被Web服务器调用的外部程序也所以被称为CGI程序。CGI规范规定:CGI程序从他的标准输入中,接受Web服务器的输入(例如请求参数),并经过标准输出将生成的HTML内容返回给Web服务器。HTTP请求中的一些变量(例如Host,客户端ip地址,浏览器的Agent信息等)则是由Web服务器设置在环境变量中,再由CGI程序从环境变量中读取,这种请求模式变成下面的图:

client server cgi

以后出现了CGI规范的改进版,也即FastCGI规范,FastCGI程序与Web服务器之间的通讯并非经过标准输入与输出,也不经过环境变量来与Web服务器交换HTTP的变量信息,FastCGI程序自己是一个独立的服务端程序,其经过socket监听端口,与Web服务器通讯,只不过通讯协议使用FastCGI协议而已。那么咱们这里说的CGI程序与FastCGI程序是用来处理动态的Web请求并动态生成HTML内容返回给Web服务器的,他们就是咱们所说的Web应用程序。随着动态语言的发展,涌现出了愈来愈多的动态网页技术,可是总归其模式与上面讲的差别不大,例如咱们常见的语言的请求结构以下图所示:

client server other

之因此须要Web服务器与Web应用程序这种架构,是由于Web服务器自己不处理动态内容,动态内容的处理交给Web应用程序去处理,Web应用程序由广大的程序员根据本身的业务需求使用各类各样的语言去编写,而Web服务器与Web应用程序之间经过某种规范或者说协议来规定怎样去通讯,这就出现了各类语言框架下实现的CGI、FastCGI、Servlet、Rack、WSGI等协议或规范,Web服务器与Web应用程序之间若是都遵循相同的协议或实现相同的规范,理论上应该是与语言无关的,因为各类各样的缘由,有些规范或者协议,只在特定的语言的web框架中出现或者说多数状况下是这样,例如Servlet在Java中使用,Rack在Ruby中使用

在一些状况下Web服务器与Web应用程序是两个独立的进程,他们经过socket进行通讯,通讯协议是双方都支持的协议规范(例如FastCGI)。还有一些状况Web服务器与Web应用程序之间的通讯是紧耦合的,好比IIS是经过ISAPI的方式,其实是加载一个dll,调用dll中的相关功能与.NET Web应用交互的。当Nginx与Python Django结合的时候他支持这两种方式,一种是 Nginx+mod_wsgi 方式,这种方式下由Nginx去调用 mod_wsgi 模块中的功能,进而调用python的Web应用程序功能动态生成HTML,其运行的上下文环境在 Nginx 进程中:

 mod wsgi

另外一种方式就是上面截图中展现的经过socket与uWSGI进程交互的方式,Web服务器与uWSGI通讯的协议能够是 HTTP 协议,也能够是二进制的 uwsgi 协议,uWSGI程序支持这两种方式与之通讯,咱们这里使用二进制 uwsgi 协议的方式,不过咱们首先要安装 uWSGI 程序(终于说到本章的正题了,前面讲原理都是作铺垫): 

pip3 install uwsgi
ModuleNotFoundError: No module named '_ctypes'

报错找不到模块 '_ctypes' 经查询咱们须要安装 libffi-devel 命令以下:

yum install libffi-devel -y

安装完成以后,咱们须要从新配置Python3.8.1并从新make以及make install,命令在上面都有,这里就不重复说了,完成以后继续安装 uwsgi 没有报错,安装成功,咱们尝试用下面的命令经过uwsgi启动django应用:

uwsgi --http :8000 --wsgi-file testdj/wsgi.py

咱们以前说过uWSGI程序支持两种方式接受请求,一种是使用 HTTP 协议,另外一种是使用二进制的 uwsgi 协议,这里咱们须要在浏览器中直接访问,因此咱们这里运行 uwsgi 的时候经过 --http 选项指定 http 协议,并指定 wsgi 应用文件所在的路径为django项目根目录下的 testdj/wsgi.py 文件,启动以后在浏览器中输入地址直接访问便可正确出结果,截图与前面同样。接下来咱们须要使用 Nginx 来做为Web服务器并经过uwsgi进程与wsgi应用来处理动态请求。为何咱们须要Nginx呢,上面运行uwsgi不是已经能够直接使用了吗,咱们在以前已经说过了,如今的网站的结构通常都是 Web服务器程序 + 动态语言程序 的结构,是由于各个模块应该各自作本身擅长的事,wsgi应用擅长处理动态的http请求并生成动态的HTML内容,Nginx是专业的Web服务器擅长其余的HTTP请求的处理,事实上uWSGI程序中实现了一个简陋的HTTP服务,因此咱们才能够经过 HTTP 的方式直接在浏览器中访问他,然而若是静态资源也用他来处理,其性能确定比Nginx差不少,因此这里要引入Nginx,引入Nginx的另外一个好处是还能够作负载均衡

安装Nginx

首先咱们须要安装Nginx服务,Nginx是使用很是普遍的高性能Web服务器,在CentOS下安装也很是简单:

yum install nginx 

没有任何报错,直接安装完成,固然本身下载源码安装想要的版本也很方便,下面咱们须要配置Nginx,安装以后的nginx的配置文件地址在 /etc/nginx/conf.d/default.conf  

server {
    ...
    listen       80;
    # 静态文件请求
    location /static {
       alias  /data/testdj/static/;
    }

    # uwsgi_pass 转向到uWSGI的8000端口
    location / {
       uwsgi_pass  127.0.0.1:8000; 
       include     /etc/nginx/uwsgi_params;
    }
    ...
}

这里我列出了比较关键的配置,第一个static匹配用于请求静态资源,咱们的静态资源能够放在一个单独的 static 目录中,这样静态资源请求不会转发到 uWSGI 去处理,而是直接由 Nginx 处理返回,其余的请求咱们经过 uwsgi_pass 配置转发到本机的 8000 端口上,实际上这个配置代表咱们的 uWSGI 进程开启的是以 uwsgi 二进制协议进行 socket 通讯的8000端口,而不是上面的 HTTP 协议的 8000 端口,若是是 HTTP 协议的8000端口,这里直接配置一个普通的 http 代理便可,配置完成以后 ,咱们如下面的命令启动 uWSGI程序:

uwsgi --socket 127.0.0.1:8000 --wsgi-file testdj/wsgi.py

咱们这里使用的是 --socket 而不是 --http 而且监听的是 127.0.0.1 这个地址,由于咱们的Nginx与uWSGI进程运行在同一台机器上,这个端口就不用暴露到外面了,启动 uWSGI 以后,咱们启动 Nginx进程,直接在浏览器中输入 http://ip 便可以正常访问了

在后端运行uWSGI进程

咱们前面经过 uwsgi 命令启动uWSGI的方式,程序跑在咱们shell环境的前端,若是咱们的终端链接断掉则程序会退出,咱们须要之后端服务的形式运行uWSGI,这里咱们须要将 uWSGI 运行所须要的参数放到一个配置文件中,咱们将这些参数放在 uwsgi.ini 中,固然这个文件名字以及放置的具体路径并无特殊要求,文件内容以下:

# uwsgi.ini 
[uwsgi]

# uWSGI的端口
socket = 127.0.0.1:8000

# 直接做为web服务器使用
# http=ip:port

# django项目目录
chdir           = /data/testdj

# 以django项目名命名的wsgi文件,实际上这个文件是不存在的
# 可是配置必须这么配
module          = testdj.wsgi
master          = true

#进程数
processes       = 4
threads = 2
vacuum          = true

# 保存启动以后主进程的pid
pidfile=uwsgi.pid

# 设置uwsgi后台运行,uwsgi.log保存日志信息
daemonize=uwsgi.log

设置好以后,咱们在 uwsgi.ini 文件所在的目录运行下面的命令便可(Nginx不用重启):

# -d 参数表示从后台运行
uwsgi -d --ini uwsgi.ini 

再次访问网页,大功告成

收集必应壁纸

文章开头咱们说咱们要创建一个必应壁纸的收集展现网站,其实主要是介绍 Nginx+uWSGI+Django 的使用,由于网站使用的是 Python语言和Django框架,因此搭建网站也费了一些周折,这个是耗时最多的,其实环境搭建好以后,代码的编写反而很简单,在django中编写程序很方便。收集必应壁纸自己并无什么特别要说明的,就是下载天天的必应美图,将图片保存到本身的网站,并将相关信息入库,在网站上展现出来。不过呢这里简单说一下怎么获取必应的背景壁纸,有一种很容易想到的方法是直接在代码里面请求必应的网站,而后查看网页结构,获取必应壁纸的url,不过必应的壁纸并无这么麻烦,经过在Chrome浏览器中访问必应网站发现,必应其实有提供接口,以下:

bing

经过在Chrome浏览器中请求必应网站,选择 "XHR" 能够看到必应的壁纸是经过一个 Ajax 请求获取的数据,咱们找到这个请求便可,我贴出来:

https://cn.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1&nc=1587287726147&pid=hp

这个接口里面的参数是能够设置的,format表示返回的数据的格式 js 返回的是json格式的数据,n 应该是返回的图片的张数,idx 应该是分页的参数,具体的参数含义,你们能够去网上搜索一下,已经有一些人研究过了。不过好像不管怎么设置,并无办法获取过久的历史图片数据,必应的官网上也只能看到最近一周的图片。也因如此,才有了本篇文章,必应壁纸收集站的实现彻底使用上面提到的技术,网站也会持续完善中,欢迎你们来这里反馈留言:关于必应高清壁纸。另外服务器我直接从阿里云买的低配版本机器,带宽和性能都比较基础,目前来讲是够用的,域名是直接从万网购买并备案的,其实整个流程仍是很便捷的,并且第一年的价格很便宜。 到此本篇介绍就完结了,但愿对你们使用django搭建web网站有所帮助

相关文章
相关标签/搜索