首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Python爬虫实践——简单爬取我的博客

学任何一门技术,如果没有实践,技术就难以真正的吸收。利用上次博客讲解的三个知识点:URL 管理器、网页下载器和网页解析器来爬取一下我的博客。

我的博客地址

http://weaponzhi.online/

这个博客里面没有技术的文章,主要是我的一些生活上面的记录,可以说是我的日记本,平时会写一些思想感悟,记录些琐事。我们简单以这个博客主页为入口,爬取一下以 weaponzhi.online 为 host 下所有的 URL 。

首先当然是需要一个 URL 管理器了,但和上篇文章说的有所不同,这次我们的待爬取数据结构是队列,实际上 Python 本身的 list 已经可以实现队列的一些操作了,但 list 的一些队列操作比如 pop() 效率是比较低的,Python 官方推荐使用 collection.deque 来完成队列操作。

host 是我们的入口界面同时也作为一个 host 作为后续 URL 拼接使用,这个到后面再说。

URL 管理器相关的数据结构建立好后,我们就可以从入口开始进行我们网页下载器部分的编写了。

我们先从待爬取的队列中 pop 出一个 URL,注意,pop 开头的方法在获取元素的同时会将元素从队列中移除。当我们获取完待爬取的元素的同时也将该 URL 添加到已爬取 URL 容器管理。

因为我们是一个简单的爬虫,并没有作任何的异常处理,所以为了避免爬取过程中遇到一些网络异常状况导致爬虫程序终止,我们将网页下载器的关键代码部分都 try...except 了,在遇到特殊情况的时候,将继续循环流程。

到现在为止都是上一篇文章的内容,不是很难,最复杂和需要花时间处理逻辑的,还是我们的网络解析器部分。

我先小试牛刀,在刚刚的 while 语句下写下了这段代码。

我使用 lxml 作为解析器,这种解析器的速度比 html.parser更快,而且它在 Python 各平台的兼容性也非常好。

我们通过 find_all 拿到了一个节点列表,需要注意的是,通过 soup 对象 find 函数返回的对象类型是bs4.element.Tag,Tag 与 XML 和 HTML 原生文档中的 tag 相同,它有两个重要属性 Name 和 Attributes,在这个例子中,name 就是标签名 a,Attributes 有很多,比如这里的 href,还有 class,id 等等。Attributes 的使用方法和字典一模一样,比如 x['href']。

上面的解析器代码输出的结果如下图所示

从结果来看这个爬虫还是有一定问题的,首先,爬取的 URL 大多都是相对路径,这种路径使用 urlopen 是肯定没法读取的。其次,我们看到我们会爬取到一些和博客地址无关的路径,比如图中的知乎地址,出现这种情况的原因是博客会有一些路径的跳转入口,如果我们放任爬虫去爬取这些路径,除非我们限定了爬取数量,那么爬虫将会无限制的爬取下去,直到天荒地老。

我们的目的是只爬取以 weaponzhi.online 开头的博客内地址,并且记录爬取数,如果队列中的 URL 全部出队,则自动停止循环,修改后的代码如下所示

我这里的处理方式比较简单粗暴,如果 URL 是以 '/' 开头的,我就认为它是一个相对地址,并把该地址与 host 地址作一个拼接。然后,用一个判断语句,确保该 URL 内有 weaponzhi 字段,从而保证了 URL 是博客内地址。当然了,更好的方式是使用正则表达式来代替这些判断语句,这就留给各位看官自行思考了~

来看看现在的代码结果

我将源码上传到了 Github 上,以后相关的文章都会在这个仓库中拓展。

https://github.com/WeaponZhi/PythonSpiner

你也可以在公众号中回复「爬虫」来直接获取 py 文件。

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180122G0Z69O00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券