🌱 Display top 10 topics on Zhihu everday.
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
assets
tool
www
README.md
captcha.gif
dataAccess.py
dataAccess.pyc
dataCGI.py
dataSpider.py
people_db.txt
people_visited_db.txt
question_db.txt

README.md

top-topic-Zhihu

抓取「知乎」网站每天新提出的热门 top10 问题聚合显示,提供另一种看知乎的姿势。包含前后端整个项目。

世界很大,不被纷繁的 timeline 所迷惑。

步骤

需要这几步来完成目标:

抓取 ——> 存储(数据持久化) ——> 分析 ——> 展示

抓取:抓取部分主要是爬虫,先手动输入验证码获取登录 Cookie。然后带着该 Cookie 模拟发出 Get 请求来获得网页数据。思路是从自己的个人主页开始爬,先爬出现在主页 timeline 上的所有人,再爬这些人主页上的其他人...,直到数据量足够大。把人的 ID 存储在 people 中。接着继续爬 people 中所有人主页上提出的问题,并获得问题的关注人数和提问时间。把抓取到的问题存储在 question 中。

存储:存储可以把上面的 people,question 写入文本或者 MySQL 数据库,。中间数据也应该放到数据库中,不然内存会被无穷多的递归生成的中间数据填满。本项目使用带主键的 MySQL 表模拟内存 set 来存储 people。

分析:网站目的是获取每天或者一个时间段内新提出的 top10 热门问题,所以需要对时间过滤,对关注人数排序。这都可以在 SQL 查询中完成。

展示:展示包括后台和前端两部分,后台需要在 DB 中取得数据构造成 JSON 格式以 CGI 的形式提供给前端调用。这里使用 Python Flask 框架提供 CGI 后台服务。前端页面主要是跨域 AJax 请求后台 CGI 来获得数据,结合定义的模板来展示页面。在版本 V1 中使用 AngularJS 来简单的编写模板及 AJax 请求的逻辑部分,在版本 V2 中使用 artTemplate 和封装原生的 Js 来满足需求。

目录结构

└── top-topic-Zhihu
    ├── assets
    │   └── demo.png
    ├── captcha.gif    # 拉取到本地的验证码
    ├── dataSpider.py  # 爬虫
    ├── dataAccess.py  # AO 服务
    ├── dataCGI.py     # Python Flask 提供给前端的 CGI
    ├── people_db.txt  # 抓到的人
    ├── people_visited_db.txt
    ├── question_db.txt# 抓到的问题
    ├── README.md
    ├── tool           # 工具
    │   └── cron.sh    # 定时任务 每天 23:00 执行 dataSpider.py
    └── www            # 网站文件
        ├── assets    
        │   ├── tuzhii.ico
        │   └── tuzhii.jpg
        ├── css
        │   ├── button.css   # 按钮样式
        │   └── toptopic.css # 网页样式
        ├── index.html
        └── js
            └── template.js  # artTemplate 库

依赖

  • BeautifulSoup
  • requests
  • MySQLdb
  • flask
  • flask.ext.cors

使用方法

  • 本地 MySQL 中建数据库 top_topic_zhihu。dataAccess.py 中 init 构造方法 MySQL 的密码更改为自己的密码

  • dataSpider.py 中 get_login_cookies() 函数中 email 和 password 修改为自己的账户密码,main 中

text = crawl_url(req, local_cookies, 'https://www.zhihu.com/people/your_id')

your_id 修改为自己的用户 ID

  • index.html 中请求的服务器地址 your_ip 修改为自己机器的 IP。dataCGI.py main 下面的 your_ip 也修改为此 IP。
var resource_url = "http://your_ip:5000/toptopic/api/topics/"
  • 执行 dataAccess.py 下列方法建表
    info.create_question_table()
    info.create_people_table()
    info.create_people_merged_table()
  • 执行 dataSpider.py 下列方法抓取 people 数据,需要手动输入本目录下图片中的验证码
    req, local_cookies = get_login_cookies()
    # 第一次获取自己主页的网页
    text = crawl_url(req, local_cookies, 'https://www.zhihu.com/people/your_name')

    # 构造 people 的数据库
    construct_people_db_v2(req, local_cookies, text)
  • 执行 dataAccess.py 下列方法合并 people 表
    info.merge_people_of_db()
  • 执行 dataSpider.py 下列方法抓取 question 数据
    convert_from_people_to_question(req, local_cookies)
  • 运行 dataCGI.py 文件,在浏览器输入 http://127.0.0.1/ 即可访问网站

配置 Nginx

网站写好后需要服务器来提供访问,由于是前后端分离的 SPA(Single Page Application),所以使用 Nginx 提供静态页面的 HTTP 服务。作下面的配置:

  • 在 Nginx 安装目录 /usr/local/nginx/html 下新建一个到网站源码的软链接:

ln -s /your-src/www ./www

把所有的源码放在 /your-src/www 目录。这样便于版本管理。当源码发生更改,只需要更改软链接。

  • 修改 Nginx 配置文件
http {
    server {
        listen       80;
        server_name  localhost;

        location / {
            root   html/www;
            index  index.html index.htm;
        }
    }
}

root 修改为 html/www,因为上一步是把源码放在了文件夹 www 下。

  • 更改文件和目录权限,以免出现 403 Forbidden 错误。

find ./ -type d | xargs chmod 755

  • 重启 Nginx 服务
cd /usr/local/nginx/sbin
./nginx -c nginx.conf

Demo

image