文档章节

换个 timeline 看知乎

兔之
 兔之
发布于 2015/12/14 10:44
字数 1019
阅读 7008
收藏 155

抓取「知乎」网站每天提出的热门 top10 问题聚合显示,提供另一种看知乎的姿势。包含前后端整个项目。项目源码托管在 Github,上传代码的时候把自己的帐号密码也给上传上去了 = =

世界很大,不要被纷繁的 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 来满足需求。

爬虫核心逻辑

dbObject = DataInfo()
def construct_people_db_v2(req, local_cookies, text):
    global dbObject
    soup = BeautifulSoup(text)
    for one in soup(class_='author-link'):
        name = one.get('href').split('/')[-1]

        if not dbObject.is_people_visited(name):
            dbObject.add_to_people_db(name)

    all_people = dbObject.get_all_in_people_db()
    for people in all_people:
        dbObject.add_to_people_visited_db(people)
        dbObject.remove_from_people_db(people)

        another_homepage = 'https://www.zhihu.com/people/' + people
        another_text = crawl_url(req, local_cookies, another_homepage)
        construct_people_db_v2(req, local_cookies, another_text)

    dbObject.close_mysql()

dbObject 是封装的 AO 模块,进行 MySQL 操作。这里主要用两个表去模拟内存中 set 存储抓取到的还未遍历主页的 people 和已遍历主页的 people_visited。

当把一个人主页上的人全部爬完之后,把这些人放入 “set” 中。然后在 “set” 中取这些人的主页爬他们主页上的人。循环直到内存满然后 CRTL-C 结束(比较暴力)。这其实就是广度优先遍历。

目录结构

└── 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

配置 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

输入图片说明

参考

http://www.cnblogs.com/vovlie/p/4178077.html

https://github.com/aui/artTemplate

http://my.oschina.net/lvyi/blog/543155

http://my.oschina.net/lvyi/blog/542662

© 著作权归作者所有

共有 人打赏支持
兔之
粉丝 66
博文 247
码字总数 95896
作品 7
深圳
程序员
加载中

评论(17)

湖心亭看雪
湖心亭看雪
赞一个
久永
久永

引用来自“朱宏青”的评论

上知乎的竟然不知道这个
http://www.kanzhihu.com/
太low拉

引用来自“黄兔之”的评论

自己实现一下,而且需求不一样的。
人家是实现一下,练习下,自己实现下。再说,有开源代码的实现,以后好自己扩展。 为什么世界上愚蠢的人总是以取笑聪明的人来自以为显示自己的“才智”呢?呵呵。
兔之
兔之

引用来自“SunGavin”的评论

调试了一个多小时,终于把几个异常给解决了,楼主加油。排排错误呀
哈哈。辛苦了。 我是边写边调试的,所以有些语句是需要执行后注释掉的。 我再整理一下。
gavinsun
gavinsun
调试了一个多小时,终于把几个异常给解决了,楼主加油。排排错误呀
兔之
兔之

引用来自“SunGavin”的评论

调试了一下,dataAccess.py报错,
_mysql_exceptions.ProgrammingError: closing a closed connection

还有各种报错。
验证码可以从文件夹下的 captcha.gif 得到,为了获取最新的 Cookie,采取这种方法。 报错是因为 mysql 关闭了两次,应该把 transfer_txt_to_mysql 的 close_mysql() 注释掉。
gavinsun
gavinsun
重复关闭了connection,还有其它错误,运行dataSpider.py时要输入验证码
gavinsun
gavinsun
调试了一下,dataAccess.py报错,
_mysql_exceptions.ProgrammingError: closing a closed connection

还有各种报错。
兔之
兔之

引用来自“樂天”的评论

4279
引流。
樂天
樂天
4279
兔之
兔之

引用来自“朱宏青”的评论

上知乎的竟然不知道这个
http://www.kanzhihu.com/
太low拉
自己实现一下,而且需求不一样的。
爬虫知乎登陆

爬虫入门 功能: 知乎算是对爬虫比较友好的网站了,但是! 现在登陆验证码很恶心,需要点击图中倒立的文字!这让我们这种本来识字就不多的人情何以堪/(ㄒoㄒ)/~~。于是采用替换url参数的方法...

OrangeLoveMilan
2017/12/21
0
0
React专利许可证研究

几天前,知乎上出来一个热门话题《如何看待百度要求内部全面停止使用 React / React Native?》,一时间被邀请回答的大咖们就展开了这场没有硝烟的战争。主要有正反两方,跟个大辩论赛似的,很...

jafeney
2017/09/21
0
0
用emoji表情包来可视化北京市历史天气状况!

Emoji表情包天气数据可视化 用emoji表情来可视化北京2016年度每日天气状况! 刚开始的时候走了冤枉路,写了一大段白花花的无用代码! 后来换个思路,过段 弃用了RCrul,转投rvest去了! 图1的...

李晓文
2017/04/12
0
0
画风急转,被热捧React为何突然被集体抵制?

  【IT168 评论】React来源于Facebook对于页面不断重新加载而导致速度过慢的奇思妙想,作为后起之秀,React携着虚拟DOM、组件化以及单向数据流在前端领域掀起了一阵新的潮流,一跃成为Git...

it168网站
2017/09/26
0
0
如何看待“不靠谱”的机器学习论文?

0. 背景 别的领域不了解,知乎的机器学习方向上有不少“如何评价XXX论文”的问题,比如前一阵子评价周志华教授的DeepForest和最近的eForest。昨天我也赶时髦分析了一个研究项目 阿萨姆:如何...

阿萨姆
2017/10/01
0
0

没有更多内容

加载失败,请刷新页面

加载更多

arcgis jsapi接口入门系列:总览

开发环境: arcgis jsapi版本4.9 由于我们这套代码是基于vue,webpack开发的,会有少数vue代码,但总体不影响 里面还有些我们公司的js库和html css,给出的代码不能百分百直接运行,主要还是...

canneljls
2分钟前
0
0
月薪80k阿里架构师漫谈他是如何从一名小码农走到架构师的

01 刚当程序员时,我是属于那种勤勤恳恳类型的员工,工作态度用认真来形容不为过,每天我几乎是团队里最早到公司,又最晚下班的一个。而组员张工一般情况下都是准时上下班的,即使项目进度比...

Java填坑之路
4分钟前
0
0
oracle的resetlogs机制浅析

oracle的resetlogs机制浅析 alter database open resetlogs 这个命令我想大家都很熟悉了,那有没有想过这个resetlogs选项为什么要用?什么时候用? 它的原理机制是什么?他都起哪些作用? 我...

突突突酱
6分钟前
0
0
JAVA 获取两个日期间的所有日期

public static List<String> getDates(String startDate, String endDate){    Date d1 = new SimpleDateFormat("yyyyMMdd").parse(startDate);//定义起始日期    Date d2 = new Simple......

尘叙缘
12分钟前
0
0
Innodb中的事务隔离级别和锁的关系

#一次封锁or两段锁? 因为有大量的并发访问,为了预防死锁,一般应用中推荐使用一次封锁法,就是在方法的开始阶段,已经预先知道会用到哪些数据,然后全部锁住,在方法运行之后,再全部解锁。...

Skqing
26分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部