如何用 100 行 Python 代码实现新闻爬虫?

2018 年 5 月 30 日 开源中国


每天我都要坐地铁上班,而地铁里完全没有手机信号。但我希望在坐地铁的时候读些新闻,于是就写了下面这个新闻爬虫。


我并没有打算做很漂亮的应用,所以只完成了原型,它可以满足我最基本的需求。其思路很简单:


找到新闻源;

用Python抓取新闻;

利用BeautifulSoup分析HTML并提取出内容;

转换成容易阅读的格式并通过邮件发送。


下面详细介绍每个部分的实现。


▌新闻源:Reddit


我们可以通过Reddit提交新闻链接并为之投票,因此Reddit是个很好的新闻来源。但接下来的问题是:怎样才能获取每天最流行的新闻?


在考虑抓取之前,我们应该先考虑目标网站有没有提供API。因为使用API完全合法,更重要的是它能提供机器可读的数据,这样就无需再分析HTML了。


幸运的是Reddit提供了API。我们可以从API列表(https://www.reddit.com/dev/api/)中找到所需的功能:/top。该功能可以返回Reddit或指定subreddit上最流行的新闻。

接下来的问题是:这个API怎么用?


仔细阅读了Reddit的文档(https://github.com/reddit-archive/reddit/wiki/OAuth2)之后,我找到了最有效的用法。


第一步:在Reddit上创建一个应用。登录之后前往“preferences → apps”页面,底部有个名为“create another app...”的按钮。点击后创建一个“script”类型的应用。我们不需要提供“about url”或“redirect url”,因为这个应用不对公众开放,也不会被别人使用。



应用创建之后,可以在应用信息里找到App ID和Secret。



下个问题是如何使用App ID和Secret。由于我们只需获取指定SubReddit上最流行的新闻,而无需访问任何与用户相关的信息,所以理论上来说我们无需提供用户名或密码之类的个人信息。Reddit提供了“Application Only OAuth”(https://github.com/reddit-archive/reddit/wiki/OAuth2#application-only-oauth)的形式,通过这种方式,应用可以匿名访问公开的信息。运行下面这条命令:



该命令会返回access token:



太好了!有了access token之后就可以大展拳脚了。


最后,如果不想自己写API的访问代码的话,可以使用Python客户端:https://github.com/praw-dev/praw


先做一下测试,从/r/Python获取最流行的5条新闻:



成功了!


▌抓取新闻页面


下一步的任务是抓取新闻页面,这其实很简单。通过上一步我们可以得到Submission对象,其URL属性就是新闻的地址。我们还可以通过domain属性过滤掉那些属于Reddit自己的URL:



我们只需要抓取该URL即可,用Requests很容易就可以做到:



这里我们略过了content type不是text/html的新闻地址,因为Reddit的用户有可能会提交直接指向图片的链接,我们不需要这种。


▌提取新闻内容


下一步是从HTML中提取内容。我们的目标是提取新闻的标题和正文,而且可以忽略其他不需要阅读的内容,如页首、页脚、侧边栏等。


这项工作很难,其实并没有通用的完美解决办法。虽然BeautifulSoup可以帮我们提取文本内容,但它会连页首页脚一起提取出来。


不过幸运的是,我发现目前网站的结构比以前好很多。没有表格布局,也没有<font>和<br>,整个文章页面清晰地用<h1>和<p>标出了标题和每个段落。而且绝大部分网站会把标题和正文放在同一个容器元素中,比如像这样:



这个例子中顶层的<div id="#main">就是用于标题和正文的容器。所以可以利用如下算法找到正文:


  • 找到<h1>作为标题。出于SEO的目的,通常页面上只会有一个<h1>;

  • 找到<h1>的父元素,检查该父元素是否包含足够多的<p>;

  • 重复第2步,直到找到一个包含足够多<p>的父元素,或到达<body>元素。如果找到了包含足够<p>的父元素,则该父元素就是正文的容器。如果在找到足够的<p>之前遇到了<body>,说明页面不包含任何可供阅读的内容。


这个算法虽然非常简陋,并没有考虑任何语义信息,但完全行得通。毕竟,算法运行失败时只需要忽略掉那篇文章就行了,少读一篇文章没什么大不了的……当然你可以通过解析<header>、<footer>或#main、.sidebar等语义元素来实现更准确的算法。


用这个算法可以很容易地写出解析代码:



这里我利用len(root.find_all('p')) < 5作为正文过滤的条件,因为真正的新闻不太可能少于5个段落。大家可以根据需要调整这个值。


▌转换成易于阅读的格式


最后一步是将提取出的内容转换为易于阅读的格式。我选择了Markdown,不过你可以写出更好的转换器。


本例中我只提取了<h#>和<p>、<pre>,所以简单的函数就能满足要求:




▌完整的代码


我在Github上分享了完整的代码,链接如下:

https://gist.github.com/charlee/bc865ba8aac295dd997691310514e515


正好100行 ,跑一下试试:



抓取的新闻文件:



最后需要做的是将这个脚本放在服务器上,设置好cronjob每天跑一次,然后将生成的文件发到我的信箱。


我没有花太多时间关注细节,所以其实这个脚本还有很多值得改进的地方。有兴趣的话你可以继续添加更多的功能,如提取图像等。


文章经授权转自:CSDN



参与「程序员专属信用卡调研

让我们打造最适合程序员的信用卡!


美食、购物、航旅…优惠折扣等着你哦~


扫码参与投票




推荐阅读

国产系统“强行”快于国外系统,网友:面对现实这么难?

C++ 协程的近况、设计与实现中的细节和决策

看似简单的 Windows 记事本,其实维护起来并不简单

联想回应“反对预装国产系统”消息:谣言,一直支持国产

吃透这套架构演化图,从零搭建 Web 网站也不难!

点击“阅读原文”查看更多精彩内容

登录查看更多
1

相关内容

新闻,是指报纸、电台、电视台、互联网等媒体经常使用的记录与传播信息的 [2] 一种文体,是反映时代的一种文体。新闻概念有广义与狭义之分。广义上:除了发表于报刊、广播、互联网、电视上的评论与专文外的常用文本都属于新闻,包括消息、通讯、特写、速写(有的将速写纳入特写之列)等等; [3] 狭义上:消息是用概括的叙述方式,以较简明扼要的文字,迅速及时地报道附近新近发生的、有价值的事实,使一定人群了解。新闻一般包括标题、导语、主体、背景和结语五部分。前三者是主要部分,后二者是辅助部分。写法以叙述为主兼或有议论、描写、评论等。新闻是包含海量资讯的新闻服务平台,真实反映每时每刻的重要事件。您可以搜索新闻事件、热点话题、人物动态、产品资讯等,快速了解它们的最新进展。

知识荟萃

精品入门和进阶教程、论文和代码整理等

更多

查看相关VIP内容、论文、资讯等
【2020新书】实战R语言4,323页pdf
专知会员服务
99+阅读 · 2020年7月1日
【实用书】学习用Python编写代码进行数据分析,103页pdf
专知会员服务
192+阅读 · 2020年6月29日
Python导论,476页pdf,现代Python计算
专知会员服务
258+阅读 · 2020年5月17日
【实用书】Python爬虫Web抓取数据,第二版,306页pdf
专知会员服务
116+阅读 · 2020年5月10日
【干货书】流畅Python,766页pdf,中英文版
专知会员服务
224+阅读 · 2020年3月22日
【资源】100+本免费数据科学书
专知会员服务
107+阅读 · 2020年3月17日
【书籍推荐】简洁的Python编程(Clean Python),附274页pdf
专知会员服务
179+阅读 · 2020年1月1日
OpenAI「假新闻」生成器GPT-2的最简Python实现
机器之心
4+阅读 · 2019年4月20日
Python用于NLP :处理文本和PDF文件
Python程序员
4+阅读 · 2019年3月27日
Python用法速查网站
Python程序员
17+阅读 · 2018年12月16日
文本挖掘中特征选择(附python实现)
七月在线实验室
4+阅读 · 2018年5月22日
Python 爬虫实践:《战狼2》豆瓣影评分析
数据库开发
5+阅读 · 2018年3月19日
如何运用Python建一个聊天机器人?
七月在线实验室
17+阅读 · 2018年1月23日
教你用Python来玩跳一跳
七月在线实验室
6+阅读 · 2018年1月2日
文本挖掘之特征选择(python 实现)
数据挖掘入门与实战
4+阅读 · 2017年7月19日
用python和Tesseract实现光学字符识别(OCR)
Python程序员
7+阅读 · 2017年7月18日
如何用Python从海量文本抽取主题?
AI研习社
7+阅读 · 2017年7月6日
Directions for Explainable Knowledge-Enabled Systems
Arxiv
26+阅读 · 2020年3月17日
Arxiv
29+阅读 · 2020年3月16日
Arxiv
92+阅读 · 2020年2月28日
Arxiv
35+阅读 · 2019年11月7日
Arxiv
5+阅读 · 2018年1月30日
Arxiv
3+阅读 · 2012年11月20日
VIP会员
相关VIP内容
【2020新书】实战R语言4,323页pdf
专知会员服务
99+阅读 · 2020年7月1日
【实用书】学习用Python编写代码进行数据分析,103页pdf
专知会员服务
192+阅读 · 2020年6月29日
Python导论,476页pdf,现代Python计算
专知会员服务
258+阅读 · 2020年5月17日
【实用书】Python爬虫Web抓取数据,第二版,306页pdf
专知会员服务
116+阅读 · 2020年5月10日
【干货书】流畅Python,766页pdf,中英文版
专知会员服务
224+阅读 · 2020年3月22日
【资源】100+本免费数据科学书
专知会员服务
107+阅读 · 2020年3月17日
【书籍推荐】简洁的Python编程(Clean Python),附274页pdf
专知会员服务
179+阅读 · 2020年1月1日
相关资讯
OpenAI「假新闻」生成器GPT-2的最简Python实现
机器之心
4+阅读 · 2019年4月20日
Python用于NLP :处理文本和PDF文件
Python程序员
4+阅读 · 2019年3月27日
Python用法速查网站
Python程序员
17+阅读 · 2018年12月16日
文本挖掘中特征选择(附python实现)
七月在线实验室
4+阅读 · 2018年5月22日
Python 爬虫实践:《战狼2》豆瓣影评分析
数据库开发
5+阅读 · 2018年3月19日
如何运用Python建一个聊天机器人?
七月在线实验室
17+阅读 · 2018年1月23日
教你用Python来玩跳一跳
七月在线实验室
6+阅读 · 2018年1月2日
文本挖掘之特征选择(python 实现)
数据挖掘入门与实战
4+阅读 · 2017年7月19日
用python和Tesseract实现光学字符识别(OCR)
Python程序员
7+阅读 · 2017年7月18日
如何用Python从海量文本抽取主题?
AI研习社
7+阅读 · 2017年7月6日
相关论文
Directions for Explainable Knowledge-Enabled Systems
Arxiv
26+阅读 · 2020年3月17日
Arxiv
29+阅读 · 2020年3月16日
Arxiv
92+阅读 · 2020年2月28日
Arxiv
35+阅读 · 2019年11月7日
Arxiv
5+阅读 · 2018年1月30日
Arxiv
3+阅读 · 2012年11月20日
Top
微信扫码咨询专知VIP会员