简书下载器——使用BeautifulSoup4解析网页

虽然名字是下载器,不过实际上就是用python写的一个网络爬虫,通过某种规则将网页爬完,然后进行解析,获得自己想要获得信息。

而简书上的文章的集合方式大概有3种:

  • 文集(notebook),url为http://www.jianshu.com/notebooks/文集id/latest
  • 专题(collection),url为http://www.jianshu.com/collection/专题id
  • 用户(users),url为http://www.jianshu.com/users/用户id/latest_articles

下载器主要也就是批量下载这三种集合中的文章。

下面用一篇文章来解释下大概的工作原理。

这篇文章的url是http://www.jianshu.com/p/8862a4250944,可以看出来并没有像某些网页一样,带有.html/.php/.asp之类的后缀,是因为服务器有某些机制可以知道在访问这种没有后缀的url的时候,究竟是想访问哪些文件。

以chrome为例,如果按下F12打开Developer Tools,然后再刷新上面那篇文章,那么可以在Network下看到http://www.jianshu.com/p/8862a4250944.html这个文件的GET请求。如果将这个html文件下载下来,看代码的话,会发现我们想要的文章的内容都在这个html文件中有所体现。

就像wikipedia中说的一样,html只是一种组织信息的一种方法,我们所需要的文章中的信息(包括图片、引用等等)都在html文件中有所体现。我们所需要做的,就是通过html tag的类型,将信息分门别类,并下载到本地。最终再通过某种方式,按其性质制作回pdf文件当中去。

所以工作流程大概就是:获得html文件内容,解析html文件,重新排列内容,并制作成pdf文件。

获得html文件的内容可以使用python内置模块urllib/urllib2,我使用了urllib2(其实对于这么小的问题两个用起来差不多)。

import urllib2
html = urllib2.urlopen("http://www.jianshu.com/p/8862a4250944").read()
print html

这面那段代码可以将那片文章的html文件打开,并读出内容。如果便于理解的话,类似于open()和readlines(),只不过readlines()会返回一个list,这个会返回一个str。看输出的话就会发现str对象html的__str__()方法会返回html文件的内容,第一步完成。

解析html文件使用了BeautifulSoup4,安装方法在这片短文中已经简要介绍了。这个工具的功能就像一个筛子,通过html tag的不同,筛出使用者想要的内容。

from bs4 import BeautifulSoup
import urllib2
html = urllib2.urlopen("http://www.jianshu.com/p/8862a4250944").read()
soup = BeautifulSoup(html)
print soup.title

运行上面一段代码,就会发现输出内容为html文件的title标签的内容:

<title>简书干货内容推荐 - 简书</title>

所谓的筛子的功能,大概就是这样,所需要做的就是先预先找好要筛出来的tag的范围,然后用bs4筛出来。通过观察html的结构,可以看出文章的内容集中在<div class="show-content"></div>中,所以我们所需要做的也就只是找到class是show-content的标签,然后将其从html里面提取出来而已。这样第二步也就完成了。

之后也可以再一次通过标签的内容(比如<strong>、<a>、<blockquote>)再次筛选内容。即完成第三步。不过由于目前制作pdf的方法还在学习当中,输出的文件格式还是txt,也就没有必要进行第三步第四步了。所以现在是通过正则表达式直接删除了所有的html标签,丢掉了格式信息。在学习完了pdf制作方法后应该会再次进行第三步和第四步。