前言
前几天闲着无聊没事(其实是一大堆事摆在面前作死不愿意做)把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代码,所以看起来会有点糙啦,欢迎各位吐槽。而且如何做到代码通用也是一个让我值得思考的问题,目前的思路颇为烦恼啊。
以上!
[…]全文转载自怡红院落[…]
[…]全文转载自怡红院落[…]
看了楼主的几篇博客,瞬间好膜拜,那种实干的心态是我们的榜样。。。自己写的代码和钻研的太少了
顺便问一句,楼主主要是做什么方向的
谢谢夸奖,其实我做的还远远不够,还需要更加努力才行啊!大家一块加油吧~ 另我现在做前端的东西较多。
啦啦啦
很给力的哈~
Python好强大,不懂的渣渣路过
不明觉厉呀,公子好赞呀
博客卡成翔了,评论也好扭曲
@kslr 哈哈,好像这个主题引了Google的字体~ u know it~ 这个主题不好看,有空的时候换一个吧╮(╯▽╰)╭…
已经越来越强了~~
@小明猪 不行啊,老了都…上回去你博客看那么多文章没我的评论我都已经水不动了…要是以前,恩哼,那还不是分分钟的事情…😃…时间过的真快,你都结婚了,媳妇好漂亮啊T_T…美cry了OwQ…现在只能祝你早日当papa了吧大概?
@公子 时间确实很快。。感觉马上就是阿伯了,我同学生了小孩他老妈张口就说这个人你要叫伯伯= =||||
@小明猪 纳尼?!…你的晋级之路好快…这样说的话你就还差“大爷”和“爷爷”就通关了啊…OwQ…岁月是把杀猪的刀…
敢于把代码贴出来就是相当有勇气啊
@路易大叔 哈哈,怎么换了个中文名字啊你。
@公子 中文名字上档次啊
很高级啊。。完全看不懂。。
@冰剑 JAVA男就好好用好你的爪哇吧……23333
哦,第一个么,趁着早,没习惯,换nodejs好了…更简单,更和谐。
@soulteary 不是第一个→_→…我觉得各有各的好处吧,node会了点js也还能入门。
好棒!我喜欢!小黄图可以攒着看了。。。。
@Lee →→…确实Tumblr上黄图好多→→…
@公子嗯。。想知道liked怎么全部扒下来
@Lee 啥Liked?找到网页给扒下来就好了~