其实从接触python到现在已经快大半年了,中间看过不少的视频,也跟着别人的教程写过不少东西,但是到现在还感觉没有入门。其实中间也明白是为什么,就好比小学生上课一样,上课认真听,认真做笔记,可是下了课之后就从来不看笔记,也从来不写作业。上课一听就懂,自己一写啥都不会,我相信很多人跟我现在是一样的感觉,所以现在创建这个作业集,一来是想鞭策自己真真正正的写点东西,二来也是希望广大的读者老师能够给我批改批改作业,大家相互学习共同进步。
好了,现在开始进入正题。
第一弹 邪恶集

为什么会想到爬邪恶集呢?是因为之前看到过msq3大神写的邪恶集爬虫,所以自己也想照着他的写一写。不过碍于自己水平有限,msq3用了面向对象编程,其实我还不太会。所以就用自己的方法写了。写的不好的地方还请各位老师多指点指点。
第一步 请求页面

get_page函数专门用于请求网页的,这里需要注意的地方是网页的编码格式不是通常的utf8,所以要指定网页编码是gb2312,不然返回的网页无法显示中文。

但是我在这里还是遇到了一个小问题。比如说


标题没办法显示,有没有大神知道是为什么?
第二步 获取所有漫画的url

从图中我们可以看到一共有19页661部漫画,所有我们只要写个列表生成式,这样就可以把所有19页的url放进一个列表中然后依次请求每一页的url就能获取所有漫画的url了。很简单吧!

我们可以看到漫画的链接在class="piclist listcon"的列表中,但是链接是不完整的,我们必须继续拼出完整的url才行。

get_comic_url函数就是用来获取所有漫画的url并且将其保存到comic_list的列表中。一共661个url。

Beautifulsoup我就不多说了,了解爬虫的应该都知道。这里我们用到了parse.urljoin()函数(from urllib import parse)这个函数呢是用来拼接url的(我只知道这么多,(⊙﹏⊙)b,感觉自己好水。。。会用就好了。)
第三步 解析漫画详情页获取漫画标题和图片的链接
上一步呢我们获取了所有漫画的url保存在了一个list当中,现在我们挨个请求comic_list中的url。
通过观察网页我们发现我们可以从网页上直接看到漫画一共有多少页(page_num),也就是多少张图片。
(上一章下一章点开之后会发现跳到了另外一部漫画,所有我们不用在意,这里的一部漫画很短)



正则是用来提取数字。
然后我们一页一页的点击观察url的变化会发现除了第一页的url就是漫画的url外,其他从第二页一直到最后的url都是有规律的




找到规律这就简单了,跟先前构造漫画url差不多。我们构造构造除了第一页外的其他页数的url

先去掉html,在加上_{}.html。
这样我们就可以获取漫画的标题(用来作为文件夹的名字)和漫画每一张图片的链接。方便之后的下载和保存。
第四步 保存漫画
保存漫画分两步,首先是创建文件夹,其次是保存。

其中的filename就是第三步中获取的漫画标题。
保存图片我们用到了urllib库中request.urlretrieve()如果直接保存的话可能会报403的错。所以我们需要把User-agent加进去。

我们用图片链接的后面四位(如这里是dd12)作为每一张图片的名字(title)用于区分图片

这样的话我们就可以把所有的漫画都爬下来啦。是不是很简单!



完整的代码在我的GitHub上,喜欢的就赏个星星。
第二弹 风之动漫全站爬虫

风之动漫相比较邪恶集呢稍微有点难度,不过也是大同小异,跟着我的步骤,我相信你可以看明白。
第一步 先分析网页
打开风之动漫拉到最下面我们可以看到在网站的最下面有一个网站地图

打开之后呢我们可以看到全站的所有漫画都在里面。

这下就简单多了,爬取map页的所有漫画的url,然后放入一个list中,依次请求list中漫画的url,从而爬取所有的漫画。
这里的漫画跟邪恶集不同的是,每一部漫画都有很多话。每一话又有很多的图片。所有在处理的时候稍微有点麻烦。
第二步 获取漫画每一话的url
漫画每一话
获取漫画每一话的标题和对应的url,保存到字典comic_chapter_url_dict中


如果不明白什么是****kwargs的,请自行百度“什么是args和****kwargs”,写这个爬虫之前我也不懂,写完之后一知半解。我的理解就是args呢表示可以把列表当参数传给函数进行处理,****kwargs**表示可以把字典当做参数传给函数进行处理。不知道怎么用的可以看看我的爬虫源码。
第三步 解析每一话,爬取所有图片
最难的部分来了。
首先通过F12 我们可以看到图片的链接在一个id="mhpic"的img标签中

如果直接爬这个标签是什么也爬不到的。因为图片的src是通过js加载的,直接爬是不行。
其次我们该如何创建文件夹才能把图片保存到对应的漫画对应的一话中呢?
最后我们该如何翻页呢?

风之动漫不像邪恶集直接告诉我们一共有多少页。风之动漫如果不翻到最后一页的话是不知道一共有多少页的。
带着这三个问题我们继续往下看。
解决第一个问题我们使用selenium+PhantomJS就可以了,selenium是自动化测试框架,可以模拟浏览器操作,PhantomJS是一个无界面的浏览器。我相信大家应该都知道。如果不懂的话推荐大家看一下崔庆才老师的用selenium模拟浏览器抓取淘宝商品美食信息我也是看这个才明白的。

接下来我们创建文件夹



最后轮到翻页。这个也挺简单的,我们只要在爬取每一页的时候判断一下这一页有没有字符“下一頁”,如果有就有下一页如果没有就是最后一页。停止爬取。





听起来是不是挺简单的?其实实现起来还是需要自己多动动脑筋的。大家可以根据我的思路先实现一下,不明白的地方可以参考一下我的源码
两个爬虫虽然可以实现漫画的爬取,但是呢爬虫其实写的很粗糙,有很多地方可以改善。比如说,很多异常处理没有加进去在保存图片的时候经常就会遇到这样的报错

最后希望能够帮助那些比我还小白的小白,也希望各位大神看过之后能够指点一二,不胜感激。
两个爬虫的GitHub地址
网友评论