一键下载小说(二):如何在Django中部署
分析
在Django服务器中实施部署长时段的在线任务有两个关键的问题,如参数传递和超时问题。参数传递的HTTP/HTTPS传输方式一般有两种:GET和POST方法。GET方法使用明文将参数拼接在URL地址后面传输,而POST则将表单参数加密后再发送,对于用户是不可见的。本文中的案例中,在本地搭建小说下载器,使用GET方法。至于超时问题,通常的惯例做法是在客户端使用Javascript脚本进行跳转或表单提交。需要的参数通过客户端Form表单提交和服务端渲染Django模板返回的组合方式进行交换。
流程
实现
Myappname / views.py
def novel_cc(request):
counter, book, referer, cookies = 0, None, None, None
if request.method == 'GET':
url = request.GET.get('url')
if url is not None and httpkit.valid_https(url):
book = request.GET.get('name', 'unk_' + hashio.md5(url))
counter = int(request.GET.get('index', 1))
referer = request.GET.get('from', None)
cookies = request.GET.get('token', None)
print(url, book)
text, next_page, referer, cookies = cdxsw_cc_1.test(start_url=url, index=counter, referer=referer,
cookies=cookies,
book_name=book)
print(counter, referer, cookies)
else:
next_page, referer, cookies = None, None, None
else:
next_page, referer, cookies = None, None, None
counter += 1
context = {'index': counter, 'book': book, 'next': next_page, 'from': referer, 'token': cookies}
return render(request, 'Myappname/novelCc.html', context)
Myappname / templates / novelCc.html
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
{% if index %}
<title>Page {{index}}</title>
{% else %}
<title>Novel</title>
{% endif %}
</head>
<body>
<form id="book-form" action="/Myprojectname/novelWidget/" method="get">
{% if index %}
<label for="counter">Page:</label>
<input id="counter" name="index" value="{{index}}" hidden>
{% else %}
<label for="counter">Page:</label>
<input id="counter" name="index" value="1" hidden>
{% endif %}
{%csrf_token%}
<label for="input2">书名: </label>
{% if book %}
<input type="text" id="input2" name="name" value="{{book}}">
{% else %}
<input type="text" id="input2" name="name">
{% endif %}
{% if next %}
<script type="text/javascript">
setTimeout(function(){var book_form = document.getElementById("book-form"); book_form.submit();}, 3000);
</script>
<label for="input1">下一页: </label>
<input type="text" id="input1" name="url" value="{{ next }}">
{% else %}
<label for="input1">输入URL: </label>
<input type="text" id="input1" name="url">
{% endif %}
{% if from %}
<label for="input3">上一页: </label>
<input id="input3" name="from" value="{{from}}">
{% endif %}
{% if token %}
{% if not next %}
<script type="text/javascript">alert('End!');</script>
{% endif %}
<input name=“token" value="{{token}}">
{% endif %}
<input type="submit" value="搜索" class="sub">
</form>
</body>
</html>
部署
Myprojectname / urls.py
"""Myprojectname URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/3.2/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('Myprojectname/', include('Myappname.urls')),
path('admin/', admin.site.urls),
]
Myappname / urls.py
"""Myappname URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/3.2/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.urls import path
from . import views
app_name = 'Myappname'
urlpatterns = [
path('novelWidget/', views.novel_cc, name='novelWidget'),
]
运行
自动下载
窗口列表
笔记
渲染Django模板HTML时,也可以选择原生HTML源代码。只不过Django模板输出HTML代码时,默认进行转义操作,可能避免一些意外的“麻烦”。本案例中,使用Django模板语言也很简洁。