10. 爬虫训练场,分页爬虫案例前端页面制作

Posted 梦想橡皮擦

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了10. 爬虫训练场,分页爬虫案例前端页面制作相关的知识,希望对你有一定的参考价值。

本篇博客重点在分页逻辑与前端页面渲染实现,如果不是顺序阅读过来,可以先查看上一篇博客
《9. 爬虫训练场,分页爬虫案例设计 Demo,打通 Python Flask 和 MySQL》

文章目录

Python Flask 分页实现

实现 Python Flask 分页会涉及如下参数值。

  • 总页数:计算总页码使用
  • 当前页:获取数据使用
  • 偏移量:计算下一页数据起点

除了重要参数外,实现一个分页对象还需要如下参数变量。

    page_obj = 
        "prev_page": page - 1,
        "next_page": page + 1,
        "current_page": 0,
        "total_page": 0,
        "max_page": 0,
        "page_size": 20,
        "total": total,
        "offset": 0,
        "page_range": None
    

其中 pagetotal 通过外部传递,page_size 为单页数据量,可以硬编码,也可以通过配置文件进行读取。

接下来就先实现分页函数逻辑,示例代码如下。

def Pagination(page, total):
    """
    Pagination 用于封装分页参数到字典变量中,并返回到前台
    :param page: 传入参数,页码
    :param total: 数据总量
    :return:
    """
    page_obj = 
        "prev_page": page - 1,
        "next_page": page + 1,
        "current_page": 0,
        "total_page": 0,
        "max_page": 0,
        "page_size": 20,
        "total": total,
        "offset": 0,
        "page_range": None
    

    page_obj["total_page"] = math.ceil(total / page_obj["page_size"])
    page_obj["max_page"] = page_obj["total_page"]

    if page <= 1:
        page = 1
        page_obj["prev_page"] = 1

    if page >= page_obj["max_page"]:
        page = page_obj["max_page"]
        page_obj["next_page"] = page_obj["max_page"]

    page_obj["current_page"] = page

    if total == 0:
        page_obj["offset"] = 0
    else:
        page_obj["offset"] = (page_obj["current_page"] - 1) * page_obj["page_size"]

    page_range = []
    for i in range(1, page_obj["max_page"] + 1):
        page_range.append(i)
    page_obj["page_range"] = page_range

    return page_obj

total_page 是总页码,需要进行向下取整,所以使用 math.ceil() 函数,获得该值之后,在将其赋值给 max_page,对于第一页和最后一页的逻辑,参考下述代码即可。

    if page <= 1:
        page = 1
        page_obj["prev_page"] = 1

    if page >= page_obj["max_page"]:
        page = page_obj["max_page"]
        page_obj["next_page"] = page_obj["max_page"]

偏移量参数为 offset,其计算表达式为 (page_obj["current_page"] - 1) * page_obj["page_size"],即(当前页-1)*每页的数据量,如果总数量为 0,偏移量默认也设置为 0 。

最后一段代码设置的是页码范围,用于后续展示页码数字

    page_range = []
    for i in range(1, page_obj["max_page"] + 1):
        page_range.append(i)
    page_obj["page_range"] = page_range

Python Flask 分页控制器实现

分页函数编写完毕,就可以实现控制器函数的升级了,代码如下所示,这里修改的是 app/school/index.py 文件代码。

@s.route('/list')
def list_school():
    # schools = School.query.all()
    page = int(request.args.get("page",1)) # 获取页码
    query = School.query

    total = query.count() # 获取数据总量
    pagination = Pagination(page, total) # 获取分页对象详细参数

    if total != 0:
        data_list = query.offset(pagination["offset"]).limit(pagination["page_size"]).all()
    else:
        data_list = []
    pagination["data_list"] = data_list

    return render_template('school/index.html', pagination=pagination)

上述代码首先通过 request.args.get("page",1) 获取用户请求页码,然后在通过 query 对象分别获取总数据和数据对象清单 data_list。最后将数据组合到 pagination 对象中,便于传递到前端页面进行渲染。

前端分页组件实现

控制器部分代码编写完毕,就可以编写前端分页组件了,这里前端渲染使用的是 Bootstrap 和 Python jinjia2 模块,示例代码如下。

<div class="row">
  <div class="col">
    <span class="pagination_count">合计 pagination.total 条数据</span>
    <ul class="pagination pagination-sm no-margin pull-right">
      <li>
        <a href="url_for('school.list_school')?page=pagination.prev_page ">上一页</a>
      </li>

      % for p in pagination.page_range % % if pagination.current_page == p %
      <li class="active">
        <a href=" url_for('school.list_school') ?page= p "> p </a>
      </li>
      % else %
      <li>
        <a href=" url_for('school.list_school') ?page= p "> p </a>
      </li>
      % endif % % endfor %
      <li>
        <a href=" url_for('school.list_school') ?page= pagination.next_page ">下一页</a>
      </li>
    </ul>
  </div>
</div>

结果预览页面之后发现所有的页码都被罗列出来了,效果如下。

这样的分页非常难看,我们需要针对性的处理,即隐藏部分页码,这里简单处理,我们仅展示上一页和下一页。

<div class="container">
    <div class="row">
        <div class="col">
            <span class="text-dark float-end align-middle" style="line-height: 40px;">合计  pagination.total 条数据</span>
            <ul class="pagination float-end">
                <li class="page-item">
                    <a class="page-link" href="url_for('school.list_school')?page=pagination.prev_page ">上一页</a>
                </li>
                <li class="page-item"><a class="page-link"
                                         href=" url_for('school.list_school') ?page= pagination.next_page ">下一页</a>
                </li>
            </ul>
        </div>
    </div>
</div>

最终得到的效果图如下所示,并且点击分页,地址已经发生变化。

📢📢📢📢📢📢
💗 你正在阅读 【梦想橡皮擦】 的博客
👍 阅读完毕,可以点点小手赞一下
🌻 发现错误,直接评论区中指正吧
📆 橡皮擦的第 806 篇原创博客

从订购之日起,案例 5 年内保证更新

以上是关于10. 爬虫训练场,分页爬虫案例前端页面制作的主要内容,如果未能解决你的问题,请参考以下文章

9. 爬虫训练场,分页爬虫案例设计Demo,打通 Python Flask 和 MySQL

9. 爬虫训练场,分页爬虫案例设计Demo,打通 Python Flask 和 MySQL

爬虫案例分享

8. 爬虫训练场,第一个爬虫目标页设计,单页爬虫案例

11. 爬虫训练场,学校数据分页呈现,Bootstrap5 媒体组件

爬虫训练场基础铺垫,BT加载器,分页,列表组,卡片,下拉菜单一文掌握