Tumblr整站图片下载

2014-06-15
2265 字
6 分钟阅读时长

提醒:本文最后更新于 4499 天前,文中所描述的信息可能已发生改变,请谨慎使用。

前言

前几天闲着无聊没事(其实是一大堆事摆在面前作死不愿意做)把Python的入门教程又看了一遍,感觉这样做好没有效率啊,遂想拿个东西练练手。Python做好的练手项目就是爬虫了(我也不知道从哪里看到的,反正就有这么一说),正好前两天看了Tumblr的一个图片博客,然后网速渣到爆表,遂想干脆给整站图片都抓下来好了。

说干就干篇

基本的思路非常简单啦,无非就是把页面抓下来然后解析里面的IMG标签得到图片地址最后下载下来就好叻。感谢Tumblr没有对IP访问频率进行限制让我少做了不少工作,ありがとう~

首先要说明Python版本啦,我的版本是Python3.4.1,对2.x不兼容。不过索性代码也非常的简单,无非就是urllib库的问题,稍加修改也是可以转换过去的,这个我就不多表述啦。另外就是我的代码是以http://triketora.tumblr.com/这个博客为基准的,因为每个博客的`DOM`标签可能都不太一样,所以没法做到代码通用,需要根据博客的主题做相应的修改。

页面的抓取我是直接用的urllib.request库,简单粗暴而且非常有效。页面DOM的解析我使用的当然是大名鼎鼎的BeautifulSoup了。至于BeautifulSoup的安装同样不多做表述,其中文文档可参见Beautiful Soup 4.2.0 文档。至于最后一步的图片下载我使用的是urllib.request.urlretrieve函数,这函数简直就是爬虫利器啊有么有,简单快捷高效的就把图片给抓取下来了,简直好顶赞!

实战代码篇

#! /usr/bin/python3
import os, sys, urllib
from urllib import request, parse
from bs4 import BeautifulSoup

def basename(url):
    return os.path.basename(parse.urlparse(url).path)

def download(url, file):
    '''download file'''
    colWidth = 50
    __perLen = 0
    def reporthook(a, b, c):
        nonlocal __perLen
        per = (100*a*b)/c
        if per>100: per=100
        realCol = int(per/100 * colWidth)
        down = '='*(realCol-1)
        undown = ' '*(colWidth-realCol)
        process = '['+down+'>'+undown+']'
        per = '{:.2f}%'.format(per)
        print('\b'*__perLen, per+' '+process, end=' ', flush=True)
        __perLen = len(per)+len(process)+4

    print('Downloading URL File:\t%s' % (url))
    urllib.request.urlretrieve(url, file, reporthook)
    print('Downloaded!')

def downImages(post):
    for image in post.find_all('img'):
        filename = basename(image['src'])
        if(os.path.exists(filename)):
            print(filename+' exists!')
            continue
        download(image['src'], filename)

def spider(url):
    global start
    print("It has ready to parse URL: "+url)
    html = BeautifulSoup( request.urlopen(url).read() )
    for post in html.select(".post"):
        iframe = post.find('iframe')
        if(iframe):
            if 'photoset' not in iframe['class']: continue #! True Video Post
            iframe = BeautifulSoup( request.urlopen(iframe['src']).read() )
            downImages(iframe)
        else: downImages(post)

    start += 1
    spider('%s/page/%d' % (URL, start))

if(len(sys.argv) <= 1): sys.exit('no tumblr blog url')
_, URL, *start = sys.argv
start = int( start[0] if len(start)>0 else 1 )
spider('%s/page/%d' % (URL, start))

HOW TO USE?

首先保证你安装了Python3,以及BeautifulSoup库,复制以上代码到Spider.py文件。然后命令行输入:

Python3 Spider.py http://triketora.tumblr.com/

你还可以指定起始下载页数,比如:

Python3 Spider.py http://triketora.tumblr.com/ 30

将会从第30页开始下载。

友情提示

默认下载的地方是Spider.py的同级目录,所以找个大点的位置放它哦。

作者有话说之还不能完结篇

怎么说呢,这是我写的第一个Python爬虫代码,甚至是第一个真正意义上的Python代码,所以看起来会有点糙啦,欢迎各位吐槽。而且如何做到代码通用也是一个让我值得思考的问题,目前的思路颇为烦恼啊。

以上!

本文作者lizheming

发布于 2014-06-15,最后更新于 2014-06-15

25 评论

冰剑 LBBROWSERWindows 7
2014-06-15 17:10:45

很高级啊。。完全看不懂。。

公子Chrome37.0Windows 7
2014-06-15 18:09:33

@冰剑 JAVA男就好好用好你的爪哇吧……23333

soulteary Chrome35.0macOS 10.9.3
2014-06-15 08:33:20

哦,第一个么,趁着早,没习惯,换nodejs好了…更简单,更和谐。

公子Chrome37.0Windows 7
2014-06-15 18:07:29

@soulteary 不是第一个→_→…我觉得各有各的好处吧,node会了点js也还能入门。

Lee Chrome35.0Windows 8.1
2014-06-15 07:23:10

好棒!我喜欢!小黄图可以攒着看了。。。。

公子Chrome37.0Windows 7
2014-06-15 18:05:46

@Lee →→…确实Tumblr上黄图好多→→…

LeeChrome35.0Windows 8.1
2014-06-19 07:02:46

@公子嗯。。想知道liked怎么全部扒下来

公子Chrome37.0Windows 7
2014-06-19 17:35:21

@Lee 啥Liked?找到网页给扒下来就好了~