前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Python实战】 ---- 爬虫练习 爬取 CSDN 2020 博客之星投票数据

【Python实战】 ---- 爬虫练习 爬取 CSDN 2020 博客之星投票数据

作者头像
Rattenking
发布2021-09-07 16:35:40
5880
发布2021-09-07 16:35:40
举报
文章被收录于专栏:Rattenking

效果

2020 博客之星年度总评选排名

分析网页数据

  1. 2020 博客之星年度总评选
  2. 页面数据接口分析 2.1 (以谷歌浏览器为例)

浏览器打开2020 博客之星年度总评选 ===》 F12(鼠标右键 ===》 检查) ===》 Network ===》 XHR ===》 在列表中找到数据接口点击

2.2 查看接口和请求方式

当前实例数据接口:https://bss.csdn.net/m/topic/blog_star2020/getUsers 请求方式:POST

2.3 查看请求头和请求参数

2.4 查看接口返回结果

爬取投票信息

爬取数据并保存到 csdn2020.js 文件中
  1. 引入 requests 和 json 模块;
  2. 设置常量 url 和 headers ;
  3. 创建抓取数据的方法 getCSDNBlogStar;
  4. 捕获抓取中存在的异常;
  5. requests 抓取数据,json 解析数据;
  6. 对返回数据判断是 list 同时长度大于 0,将数据更新到 UP_DIR_JS + “csdn2020.js” 文件中;
  7. 如果返回数据不满足上一条件,就到 UP_DIR_JS + “csdn2020.js” 文件读取原来的数据返回。
代码语言:javascript
复制
"""
@Author  :Rattenking
@Date    :2021/02/07 09:35
@CSDN	 :https://blog.csdn.net/m0_38082783
"""
import requests
import json
url = "https://bss.csdn.net/m/topic/blog_star2020/getUsers"
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.162 Safari/537.36",
    "Referer": "https://bss.csdn.net/m/topic/blog_star2020"
}
def getCSDNBlogStar():
  try:
    res = requests.get(url, headers=headers)
    results = json.loads(res.text)['data']
    if(isinstance(results, list) and len(results) > 0):
      file = open(UP_DIR_JS + "csdn2020.js", 'w', encoding='utf-8')
      file.write(json.dumps(results))
      file.close()
    else:
      with open(UP_DIR_JS + "csdn2020.js", encoding='utf-8') as csdn2020:
        content = csdn2020.read()
        results = json.loads(content)
    return results
  except Exception as e:
    print(e)
    return "获取 CSDN 2020 博客之星排名失败!"
通过 api 接口将数据返回
  1. 调用 getCSDNBlogStar 获取数据;
  2. resultGenerator 类对结果进行统一封装处理;
代码语言:javascript
复制
@api.route('/csdn/star2020',methods=['POST','GET'])
def getCSDNStar():
  try:
    return resultGenerator.genSuccessResult(getCSDNBlogStar())
  except Exception as e:
    print(e)
    return resultGenerator.genFailResult("查询异常!")

HTML 请求数据并展示

  1. 使用媒体查询做适配处理;
  2. 使用 vue 2.0 做数据渲染;
  3. jQuery 的 post 请求抓取的数据;
  4. 对抓取的数据 通过 sort 排序;
  5. jumpBlog 跳转当前博主在 CSDN 的博客首页!
代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <meta name="referrer" content="no-referrer" />
  <meta content="email=no" name="format-detection">
  <meta content="telephone=no" name="format-detection">
  <meta name="msapplication-tap-highlight" content="no">
  <meta content="yes" name="apple-mobile-web-app-capable">
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  <meta content="black" name="apple-mobile-web-app-status-bar-style">
  <meta content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no" name="viewport">
  <link rel="shortcut icon" href="https://www.tyfo.com/market/content/home_image/favicon.ico" type="image/x-icon" />
  <title>CSDN 2020博客之星排名</title>
  <script src="https://www.tyfo.com/common/js/jquery.js"></script>
  <script src="/static/assets/js/vue.js"></script>
  <link rel="stylesheet" href="/static/assets/css/common.css">
  <style>
    body{background-color: #111;}
    @media screen and (max-width: 1100px) {
      html {
        font-size: calc(100vw / 7.5);
      }
    }
    @media screen and (min-width: 1100px) and (max-width: 1920px) {
      html {
        font-size: calc(750px / 7.5);
      }
    }
    .rui-blog-star{
      max-width: 1100px;
      margin: 0 auto;
      box-sizing: border-box;
      padding: 0.3rem;
      display: -webkit-flex;
      display: flex;
      flex-wrap: wrap;
    }
    .rui-star-li{
      width: 49%;
      flex: none;
      border: 1px solid #0afcf0;
      border-radius: 3px;
      box-sizing: border-box;
      padding:0.3rem 0.1rem;
      margin-right: 2%;
      margin-bottom: 0.3rem;
    }
    .rui-star-li:nth-child(2n){margin-right: 0;}
    .rui-star-icon{
      width: 1.5rem;
      height: 1.5rem;
      flex: none;
      display: block;
      margin: 0 auto;
      border-radius: 50%;
    }
    .rui-star-name{
      font-size: 0.3rem;
      color: #F9F9F9;
      background: linear-gradient(
      0deg
      , #0787ff 0%, #04feef 46.24023438%, #0789ff 100%);
      -webkit-background-clip: text;
      -webkit-text-fill-color: transparent;
      line-height: 2;
      margin-top: 0.15rem;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
      text-align: center;
    }
    .rui-vote-num{
      color: #07F5F2;
      font-size: 0.3rem;
    }
    .rui-star-code{
      color: #fff;
      font-size: 0.22rem;
      text-align: center;
      margin-top: 0.1rem;
    }
    .rui-star-vote{
      color: #fff;
      font-size: 0.3rem;
      display: -webkit-flex;
      display: flex;
      align-items: center;
      justify-content: center;
      margin-top: 0.1rem;
    }
    .rui-flex-ac{
      display: -webkit-flex;
      display: flex;
      align-items: center;
    }
    .rui-star-sort{
      font-size: 0.3rem;
      margin-bottom: 0.2rem;
      color: #fff;
      text-align: center;
    }
    .rui-title{
      font-size: 0.4rem;
      color: #fff;
      text-align: center;
      margin: 0.5rem;
    }
  </style>
</head>

<body>
  <div id="app">
    <div class="rui-title">CSDN 2020 博客之星最终排名</div>
    <div class="rui-blog-star">
      <div class="rui-star-li" v-for="(item,index) in list" @click="jumpBlog(item.title)">
        <div class="rui-star-sort">第<span  class="rui-vote-num" v-html="index + 1"></span>名</div>
        <img :src="item.avatar" class="rui-star-icon" alt="">
        <div v-html="item.nick_name" class="rui-star-name"></div>
        <div class="rui-star-code">码龄<span v-html="item.codeLevel"></span>年</div>
        <div class="rui-star-code">2020年度原创博文: <span v-html="item.brief"></span>篇</div>
        <div class="rui-star-vote">
          <div class="rui-flex-ac">最终票数:<div v-html="item.vote_num" class="rui-vote-num"></div>票</div>
        </div>
      </div>
    </div>
  </div>
  <script>
    var app = new Vue({
      el: '#app',
      data: {
        list: []
      },
      created() {
        this.getStar();
      },
      methods: {
        jumpBlog(title){
          kk = `https://blog.csdn.net/${title}`;
        },
        getStar() {
          let _this = this;
          $.post('/api/csdn/star2020', res => {
            console.log(res.data)
            let list = res.data || [];
            _this.list = res.data.sort((a, b) => b.vote_num - a.vote_num)
          })
        }
      }
    })
  </script>
</body>

</html>

预览

2020 博客之星年度总评选排名

开发中的报错

  1. file.write 写入传的是字符串,开始采用的 str 方法,读取采用的是 list 方法,发现解析不正确;
  2. json 数据转字符串用 json.dumps,json 字符串转 json 用 json.loads;
  3. img 读取图片报 403 ,可以使用!
代码语言:javascript
复制
<meta name="referrer" content="no-referrer" />
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/02/07 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 效果
  • 分析网页数据
  • 爬取投票信息
    • 爬取数据并保存到 csdn2020.js 文件中
      • 通过 api 接口将数据返回
      • HTML 请求数据并展示
      • 预览
      • 开发中的报错
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档