Python漫画爬虫两弹

作者: VB过得VB | 来源:发表于2017-07-07 22:19 被阅读215次

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

    好了,现在开始进入正题。

    第一弹 邪恶集

    dd01.jpg
    为什么会想到爬邪恶集呢?是因为之前看到过msq3大神写的邪恶集爬虫,所以自己也想照着他的写一写。不过碍于自己水平有限,msq3用了面向对象编程,其实我还不太会。所以就用自己的方法写了。写的不好的地方还请各位老师多指点指点。
    第一步 请求页面
    get_page函数请求网页
    get_page函数专门用于请求网页的,这里需要注意的地方是网页的编码格式不是通常的utf8,所以要指定网页编码是gb2312,不然返回的网页无法显示中文。 Paste_Image.png

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


    Paste_Image.png
    Paste_Image.png
    标题没办法显示,有没有大神知道是为什么?
    第二步 获取所有漫画的url
    Paste_Image.png
    从图中我们可以看到一共有19页661部漫画,所有我们只要写个列表生成式,这样就可以把所有19页的url放进一个列表中然后依次请求每一页的url就能获取所有漫画的url了。很简单吧!
    19页url
    我们可以看到漫画的链接在class="piclist listcon"的列表中,但是链接是不完整的,我们必须继续拼出完整的url才行。
    Paste_Image.png
    get_comic_url函数就是用来获取所有漫画的url并且将其保存到comic_list的列表中。一共661个url。
    获取所有漫画url
    Beautifulsoup我就不多说了,了解爬虫的应该都知道。这里我们用到了parse.urljoin()函数(from urllib import parse)这个函数呢是用来拼接url的(我只知道这么多,(⊙﹏⊙)b,感觉自己好水。。。会用就好了。)
    第三步 解析漫画详情页获取漫画标题和图片的链接

    上一步呢我们获取了所有漫画的url保存在了一个list当中,现在我们挨个请求comic_list中的url。
    通过观察网页我们发现我们可以从网页上直接看到漫画一共有多少页(page_num),也就是多少张图片。
    (上一章下一章点开之后会发现跳到了另外一部漫画,所有我们不用在意,这里的一部漫画很短)


    Paste_Image.png
    获取一共多少页
    获取一共多少页

    正则是用来提取数字。

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


    第一页url
    第二页url
    第三页url
    第十二页url

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


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

    保存漫画分两步,首先是创建文件夹,其次是保存。

    创建文件夹
    其中的filename就是第三步中获取的漫画标题。
    保存图片我们用到了urllib库中request.urlretrieve()如果直接保存的话可能会报403的错。所以我们需要把User-agent加进去。
    保存图片
    我们用图片链接的后面四位(如这里是dd12)作为每一张图片的名字(title)用于区分图片
    图片链接
    这样的话我们就可以把所有的漫画都爬下来啦。是不是很简单!
    Paste_Image.png
    Paste_Image.png
    Paste_Image.png
    完整的代码在我的GitHub上,喜欢的就赏个星星。

    第二弹 风之动漫全站爬虫

    女帝
    风之动漫相比较邪恶集呢稍微有点难度,不过也是大同小异,跟着我的步骤,我相信你可以看明白。
    第一步 先分析网页

    打开风之动漫拉到最下面我们可以看到在网站的最下面有一个网站地图

    网站地图
    打开之后呢我们可以看到全站的所有漫画都在里面。
    所有漫画
    这下就简单多了,爬取map页的所有漫画的url,然后放入一个list中,依次请求list中漫画的url,从而爬取所有的漫画。
    这里的漫画跟邪恶集不同的是,每一部漫画都有很多话。每一话又有很多的图片。所有在处理的时候稍微有点麻烦。
    第二步 获取漫画每一话的url 漫画每一话

    获取漫画每一话的标题和对应的url,保存到字典comic_chapter_url_dict

    Paste_Image.png
    Paste_Image.png
    如果不明白什么是****kwargs的,请自行百度“什么是args和****kwargs”,写这个爬虫之前我也不懂,写完之后一知半解。我的理解就是args呢表示可以把列表当参数传给函数进行处理,****kwargs**表示可以把字典当做参数传给函数进行处理。不知道怎么用的可以看看我的爬虫源码。
    第三步 解析每一话,爬取所有图片

    最难的部分来了。
    首先通过F12 我们可以看到图片的链接在一个id="mhpic"的img标签中

    图片链接
    如果直接爬这个标签是什么也爬不到的。因为图片的src是通过js加载的,直接爬是不行。
    其次我们该如何创建文件夹才能把图片保存到对应的漫画对应的一话中呢?
    最后我们该如何翻页呢?
    翻页
    风之动漫不像邪恶集直接告诉我们一共有多少页。风之动漫如果不翻到最后一页的话是不知道一共有多少页的。
    带着这三个问题我们继续往下看。
    解决第一个问题我们使用selenium+PhantomJS就可以了,selenium是自动化测试框架,可以模拟浏览器操作,PhantomJS是一个无界面的浏览器。我相信大家应该都知道。如果不懂的话推荐大家看一下崔庆才老师的用selenium模拟浏览器抓取淘宝商品美食信息我也是看这个才明白的。 获取图片链接 html = brower.page_source就是js加载之后的网页,这个时候我们用正则匹配出图片的链接就可以了。
    接下来我们创建文件夹 文件夹名 我们可以看到在“位置”之中正好有我们要的文件夹名字(旋风管家 旋风管家561话)这就简单了。
    文件夹名 使用正则表达式匹配出我们想要的字符分别保存在path1和path2中作为路径,然后调用make_file()函数创建文件
    make_file()
    最后轮到翻页。这个也挺简单的,我们只要在爬取每一页的时候判断一下这一页有没有字符“下一頁”,如果有就有下一页如果没有就是最后一页。停止爬取。 翻页 每一页的url也是有规律的形如index_1,index_2,index_3。。。构造一下就出来了,依次请求依次爬取每一张图片。
    结果1
    结果2
    结果4
    结果4
    听起来是不是挺简单的?其实实现起来还是需要自己多动动脑筋的。大家可以根据我的思路先实现一下,不明白的地方可以参考一下我的源码
    两个爬虫虽然可以实现漫画的爬取,但是呢爬虫其实写的很粗糙,有很多地方可以改善。比如说,很多异常处理没有加进去在保存图片的时候经常就会遇到这样的报错 报错 网站没有反爬,如果有反爬我们又该怎么处理呢?这么多漫画爬起来会很慢,我们可以加入多进程和多线程。最后呢,我觉得可以用到面向对象来写可能会更好一点,但是碍于自己水平有限,还不太会用面向对象方法。

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

    相关文章

      网友评论

      • 52448b04fe5a:msq3大神写的邪恶集爬虫 我看完后有很多困惑,不知能否交流交流?
      • 苏鑫的博客:有反扒可以自己写hearder模拟浏览器,我遇到过的是这样做的,而且我就遇见一个。如果访问次数过多,网站会ban掉你的IP可以考虑通过代理解决,这个我没遇见过。
        VB过得VB: @笔芯er 好的👌
        苏鑫的博客: @大叔你好嫩 糗事百科有反爬你可以试试爬爬
        VB过得VB: @笔芯er 确实是的,只是这两个网站比较简单没有反爬措施,所以我也没用到相应的应对措施,只是在用到request.urlretrieve()保存图片的时候会遇到403的错误。

      本文标题:Python漫画爬虫两弹

      本文链接:https://www.haomeiwen.com/subject/fqdkhxtx.html