python 爬虫 入门 commit by commit -- commit1

"F12是爬虫开发的最好的朋友" -- by 我自己

代码你可以在https://github.com/rogerzhu/relwarcDJ 上得到,并且带有我完整的commit记录。

既然叫commit by commit,那就要按照自己给自己定下的规矩来写。在把代码clone到本地之后,你可以用git reset --hard 6fda96eae来退回到代码的第一个版本。别担心回不去后面的版本,这commit都在github都能看到,即使你不知道一些奇技淫巧的git命令也没啥,大胆干。

首先,我觉得我应该说这个commit我想干嘛,第一个commit,我是想作为熟悉的门槛,所以这个commit最开始我的本意是想获得京东图书编程语言第一页上面的书名,链接。

对于这个commit,当你输入如下命令开始运行时:

你应该能看到如下的结果:

前面已经扯了两篇了,那么从这篇开始步入技术的正轨了,其实从骨子里我是很讨厌那种教程里敲半个小时代码,最后发现就是一个输出了一个星号组成的图案。我觉得,入门级别的代码得用不超过10分钟的时间干出一点你能看得到,有成就感的正事才能吸引大部分的注意力。可惜啊,C++在这方面确实很难做到,而python在这方面绝对是擅长。所以,第一个commit虽然我的comment是ugly commit,但是绝对能干活。

既然是入门级别的文章,那么就从最基本的部分开始,当你浏览一个网页的时候,实际上,你在浏览什么?实际上你在浏览的是服务器传回来的一系列文件,这一系列文件由浏览器解析,然后呈现给你。比如我想看看京东图书编程语言下面的所有图书,我只要用鼠标一点一点的点到我想要的地方就可以看到我需要的网页。

但是作为一个程序员,GUI并算是一个高效的交互方式,一个简单的例子,对于文本可以一目十行,GUI除非你眼睛传感器异于常人或者大脑CPU比一般人要性能好,不然很难做到。对于爬虫,他不会关心GUI,它的食物只有一种,各类带格式的文件。所以,我们需要看到界面背后的源码。市面上只要你能见到的浏览器,在右键菜单里一定会有让你看到源码的菜单。但是,在现代网页越来越丰富的情况下,一个页面的源码文件实在是太丰富了,按照我最开始的说法,我想找到书名和价格,咋办?不能用ctrl+f吧,低效不是程序员的作为。在这个时候,职业的本能应该驱使你去寻找工具。

开心的是,主流浏览器都带有这种工具,而且获取这一组工具的方法都是只要简单的按下F12就可以了,我敢保证,当你按下这个键的时候,你有一种打开了新世界的感觉。比如我用的火狐,按下F12之后在最左边,你会看到这样一个图标:

点击一下这个图标再移到界面上,你会发现你可以以矩形的方式选择页面上的元素。根据人的本能,点击一下,你会发现图标下面的html会自动定义到选中的元素!这样,拿到什么信息,你只要负责选择就好了,浏览器自带的工具会自动帮你定位。比如,我想要的图书的名字和价格,我选中某一格的图书,就会看到这样的输出:

html是一种格式化并且是带有层级的语言,这样就会自然引申出一个问题,当我选取一个元素时候,到底采用怎样的粒度?比如说,就以这个图书的名字来说,他是在一个列表(li)元素中的一个div中的一个text中的,那么完全可以直接选取这个text,第二个是通过父级别一点一点的选取。这其实就是一个数据结构大小取舍的问题,而写程序,我觉得要考虑到扩展性和人思维的自然认知性,以便于升级和维护。所以,我一般都是从我自己最自然的认知出发,当我的眼睛看到这个网页时,我的呆脑,哦不,是大脑会自然把每个图的一个缩略图,名称和价格组成的这个方块归类为一个小组,于是,我选择的粒度就是遵从我的内心。

那么我就用上面说的小箭头选取到我决定的方块,可以得到标识这每一方块的元素是<li>。而在这个HTML中,有无数的li,我们怎么能定位到我们需要的这个li呢?这里,让我不得不想起一个谚语,叫赠人玫瑰手有余香。在前端程序员在开发他们的网页时,他们需要对元素进行标识,这样他们才能在代码中方便的写出想要的逻辑。而这个行为,给爬虫程序员们提供了便利,你可以用他们归类的标识来定位你需要的元素,当然,我这里说的是在代码里。而beautifulsoup这个包可以非常的方便的让你完成这件事情,你可以选择用id,class等等来找到你需要的元素。而在这里,如果你按照我说的使用箭头工具的话,会很容易的看到在这个网页中gl-item这样的class来标识每一个列表块。那么剩下的就是按照已经发现的,翻译成为程序语言了。

在第一个commit里面,代码一共22行,我都忍不住用截图的方式展示一下以便于说明。

首先python提供了非常方便的方法获取网页的源码,我以前最开始的时候使用C++写过爬虫,怎么形容呢?如果python爬虫的给力程度是他娘的意大利炮,那么c++就是纯物理攻击了。你只需要使用urllib中的request.urlopen就能直接获取到网页源码。而需要的参数仅仅是网页的url。一如第九行所示。

当有了源码之后,按照前面介绍的逻辑,就是寻找对应的元素了,而这个时候就是BeautifulSoup包上场的时候了,把得到的源码字符串作为参数传给BeautifulSoup库,你就会得到一个强大的方便解析的BeautifulSoup对象。而在BeautifulSoup中,使用findAll你就可以找到全部的带有某种标识的某种元素。比如说,在我们要爬取的页面上,有很多的书,而我们又知道每个书所存在的块是以gl-item的class来标识的列表,那么只要对findAll传入元素名称和标识规则就行了。而BeautifulSoup还提供一个find函数,用来找到第一个符合标识的对象。

既然已经得到需要的一大块了,剩下的就是在这一大块中找到自己想要的信息,比如我想要的书名和链接地址。其实这后面的过程就是前面描述的过程的重复。大致就是找到页面->按下F12->使用选择工具->找到对应的元素块。但是程序员嘛,都很懒,能少动几下鼠标是几下,所以,如果一个块中元素规模不大的并且基本都相像的情况下,我会使用这样的一种办法:把一大块的html片段输出到一个文件里。如果你觉得我说的有点绕了,那么其实我想表达的就是第12行语句的意思,虽然我这里用的是print,但是你可以使用重定向的功能将这个输出到一个文件中,也就是"> item.txt"类似的语句。而如果你查看这个commit的目录结构,你就会看到这么一个文件。如果好奇心仍驱使你打开它,那么你就可以看到一个li中的所有内容。这样就省去了前面那四个步骤的烦恼,而且你可以反复查看,而不用反复的打开浏览器。

当然,这是在我下面的循环还没有写出来的时候先输出的。

谈到这个while循环,在这里你可以完全忽略,或者说你可能会揣测这到底有什么深意。其实没啥深意,就是为了后面用的,而且还是比较后面的commit中才会用到。我只是有点懒,懒得删除。实际上,这个程序的第15,16以及22行完全可以删除,对于最后的结果完全没有任何影响。

而这里的for循环是肯定必要的。python的语法,按照其cookbook上说,已经非常接近自然语言了,从有的方面看真的是这样的,比如说第17行,表示是依次取出allItem中的所有元素,对于每一个元素就是一个li块,剩下的只要从这些li块中再继续寻找需要的信息就可以了。比如,书的标题实在class为p-name的div元素之中。而在这个页面上,真正的标题文字是放在强调标签<em>之中。这都不能难住强大的BeautifulSoup库,其对象可以像访问结构中成员一般一层一层的找到需要的元素。如果想要获得某个标签中的文字,只需要使用get_text函数就可以获得。用代码说话的话就是18,19行。

而有的时候我们不是要获取某个标签中的元素,而是要获取某个标签中的属性怎么办?BeautifulSoup用近乎完全符合自然思维的方式实现了这一点。比如超链接,一般都是在<a>标签中href属性之中,那么href就是a这个成员(字典)的一个关键词,通过这个关键词,你就可以取得其中的值,一如你看到的href="xxx"一样,典型的key,value结构。也就是程序的第20行,通过这样的方式,就可以取得每个图书的链接。

剩下来,就是你怎么呈现这个数据的部分了,我这里就简单大方而又明了的输出,keep it simple,stupid。

这里,第一个commit就结束了,去掉不需要while循环,一共就19行代码,在环境配好的情况下,无脑敲完不需要5分钟,运行python myGAND.py,你就可以看到京东图书编程语言第一页的书名和链接打印在控制台或者文件中。说实话,如果是C++,你可能还在写各种字符串解析函数的过程中。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏小筱月

关于 Element 组件的穿梭框的重构

前端的发展迅速,层出不穷。很多公司的项目,在使用框架很好能解决 UI 与数据状态同步的难题,但随着公司业务发展,数据量的庞大以及数据处理越来越复杂,官方组件也难...

9613
来自专栏腾讯开源的专栏

腾讯 Web UI 解决方案 QMUI Web : 探索与沉淀

QMUI Web 是一个 Web UI 的解决方案,从零开始,由编码规范,到组件和工具方法的制作,再到工作流的整合,不断在迭代,也不断在优化,走过了不少的路。

4073
来自专栏北京马哥教育

13个Python GUI库

Python是一门高级编程语言。它用于通用编程。Python语言由Guido van Rossum创建,并于1991年首次发布。Python的设计哲学着重于代码...

2190
来自专栏Crossin的编程教室

【Python 第2课】print

今天早上醒来,发现咱们的同学人数一夜之间多了50,后来又陆陆续续来了很多,于是我坚持下去的信心又增加了不少。在这里感谢连客官微的宣传,表示今晚将用加班写代码来表...

2817
来自专栏逸鹏说道

Bootstrap-Select 动态加载数据的小记

关于前端框架系列的可以参考我我刚学Bootstrap时候写的LoT.UI http://www.cnblogs.com/dunitian/p/4822808.h...

3369
来自专栏phodal

「微信小程序」剖析(二):框架原理 | 在桌面浏览器上运行的尝试

本来想的是昨天晚上写这篇文章的,后来昨天在写一个Cordova上的iOS插件的时候各种不顺。对接的第三方SDK不给力,于是六点多回到家的时候,我就就开始娱乐了...

2569
来自专栏web前端教室

什么生命周期,在我看来就是各种回调 &&电商项目作业检查 -- 张xx

今天咱们的零基础课讲到了react的生命周期,什么三种状态啊,五种处理事件啊,函数的名字都特别的长。还有表单应用和react中哪使用ajax方法,以及get回来...

1798
来自专栏程序员的知识天地

Web 前端模板引擎的选择

模板引擎负责组装数据,以另外一种形式或外观展现数据。 浏览器中的页面是 Web 模板引擎最终的展现。

7613
来自专栏花叔的专栏

解读10.13发布的小程序新功能

距离上次更新已经有一个月了,小程序终于又更新了,但其实所更新的内容并不太多,这有点违背微信团队的快速迭代的习惯,难道在酝酿更大的迭代吧?嘿嘿~~~ 回归正题,先...

39512
来自专栏take time, save time

八个commit让你学会爬取京东商品信息

我发现现在不用标题党的套路还真不好吸引人,最近在做相关的事情,从而稍微总结出了一些文字。我一贯的想法吧,虽然才疏学浅,但是还是希望能帮助需要的人。博客园实在不适...

2364

扫码关注云+社区

领取腾讯云代金券