突然想搞个这样的工具,写来写去都不知道在干嘛了,本来两个文件,现在整合在一起了。

乱得不行,懒得整理了,能用就行。

下载部分用了多线程,但是下载一个文件还是用的单线程,也就是没管http头的range问题。貌似速度也不咋地。

开始遇到的一个问题是直接用urllib的urlretrieve或者是先urlopen再read()出来老是出错,或者丢失,后来本来打算外挂一个wget.exe来下载,想来想去还是得不偿失,所以现在分几个block来读,应该是可以的。

另外百度相册用了ajax的动态页面加载技术,所以在浏览器上看到的带#号或者#!的url不能直接用urllib去open,#后的东西是不会POST到服务器的。

后来用浏览器的审查元素工具,切换到网络页面,发现请求的url,其实还是传递了参数的,这就比较好解决了。

算了,丢代码吧。

PS:最近发现美版的《极速前进》很好看,这段时间一直在看

# -*- coding: cp936 -*-
import urllib,re,urllib2
import os,os.path
import time
import threading
import sys IS_DEBUG = False
MULTI_THREAD = False
MAX_Thread = 20 tieba_info_fp = "" #tbName = raw_input("输入贴吧名称:")
tbName = ""
tieba_url_base = "http://tieba.baidu.com"
pgUrl_base="http://tieba.baidu.com/photo/g?kw="
photo_url_base = "http://imgsrc.baidu.com/forum/pic/item/" BLOCK_SIZE = 4096
threadLock = threading.Lock() # 打印信息到文件和屏幕
def print_f(msg):
global tieba_info_fp
print msg
tieba_info_fp.write(msg+'\n')
tieba_info_fp.flush() def download_file(url,path):
if os.path.isfile(path):
return
r = urllib.urlopen(url)
fileName = ""
if path != "":
fileName = path
elif r.info().has_key('Content-Disposition'):
fileName = r.info()['Content-Disposition'].split('filename=')[1]
fileName = fileName.replace('"', '').replace("'", "")
else:
fileName = url[url.rfind('/')+1:] if os.path.isfile(fileName):
return
else:
file_length = int(r.info()['Content-Length'])
download_size=0
f = open(fileName, 'wb')
try:
while download_size<file_length:
dat = r.read(BLOCK_SIZE)
l = len(dat)
if l>0:
f.write(dat)
download_size += l
else:
f.close()
os.remove(fileName)
raise Exception,"time out"
except Exception,e:
f.close()
os.remove(fileName)
raise Exception,e
finally:
f.close() class MultiDownload(threading.Thread):
def __init__(self,dat):
threading.Thread.__init__(self)
self.dat = dat
def run(self):
while 1:
pos,url,path = self.dat.start_one()
if pos == None:
break
try:
download_file(url,path)
self.dat.end_one(pos)
#出错标记为未下载
except Exception,e: self.dat.renew_one(pos)
print url,e class DData:
def __init__(self):
self.pos = 0
self.url = []
self.path = []
#0 1 2
self.status = [] def add(self,url,path):
self.url.append(url)
self.path.append(path)
self.status.append('0')
self.pos += 1 #获取一条未下载的数据,并设置为1(正在下载),返回pos,所有都下载完返回None
def start_one(self):
try:
pos = self.status.index('0')
threadLock.acquire()
self.status[pos] = '1'
threadLock.release()
return pos,self.url[pos],self.path[pos]
except ValueError:
return None,None,None #结束一条下载
def end_one(self,pos):
threadLock.acquire()
self.status[pos] = '2'
threadLock.release() #标记未下载一条下载
def renew_one(self,pos):
threadLock.acquire()
self.status[pos] = '0'
threadLock.release() def multi_download_run(url_list,path_list=[],MAX_Thread=10):
dat = DData()
for i in xrange(0,len(url_list)):
if path_list==[]:
fn = url[url.rfind('/')+1:]
path = os.path.join(os.getcwd(),fn)
else:
path = path_list[i]
dat.add(url_list[i],path)
threads = []
for i in xrange(0,MAX_Thread):
threads.append(MultiDownload(dat))
for t in threads:
t.start()
for t in threads:
t.join() def multi_download(pic_list):
url_list = []
path_list =[]
for id in pic_list:
fn = id + ".jpg"
url = photo_url_base + fn
path = os.path.join(os.getcwd(),fn)
url_list.append(url)
path_list.append(path)
multi_download_run(url_list,path_list,MAX_Thread=10) # 进入子目录,如果不存在则创建
def chsubdir(dirname):
cwd=os.getcwd()
subdir = os.path.join(cwd,dirname)
if os.path.exists(subdir) == False:
os.mkdir(subdir)
os.chdir(subdir) ## 读取相册
def read_album(tid,name):
chsubdir(name)
if IS_DEBUG == True:
return
url= 'http://tieba.baidu.com/photo/bw/picture/guide?kw=%s&tid=%s&see_lz=1&from_page=0&alt=jview&next=15'%(tbName,tid)
# print url
pageData = urllib.urlopen(url).read()
#print pageData
p = re.compile('"pic_amount":(\d+),')
pic_amount = p.search(pageData).group(1)
print_f ("┗━━"+name + ' '+pic_amount + '张')
p = re.compile('"original":{"id":"(\S+?)"')
find_list = p.findall(pageData)
pic_list = find_list
i= len(pic_list)
pic_amount=int(pic_amount) # 转化为整数型
while pic_amount>i:
#print i
url2 = url+"&prev=0&pic_id="+pic_list[-1]
pageData = urllib.urlopen(url2).read()
p = re.compile('"original":{"id":"(\S+?)"')
find_list = p.findall(pageData)
pic_list = pic_list + find_list[1:]
i=len(pic_list)
multi_download(pic_list) ## 读取相册集
def read_catalog(url,name):
if name != '':
chsubdir(name)
print_f(name)
page = 1
while 1:
url_page = "%s&pn=%d"%(url,page)
pageData = urllib2.urlopen(url_page).read()
p = re.compile ('<div class="grbm_ele_title.+?href="(\S+?)".+?title="(.+?)"',re.S)
result = p.findall(pageData)
root_dir = os.getcwd()
if len(result)==0:
break
else :
for a in result:
#cUrl = tieba_url_base + a[1]
tid=a[0][3:]
cName = a[1]
os.chdir(root_dir)
read_album(tid,cName)
page += 1 ## 读取根目录信息
def read_root(url,name):
global tieba_info_fp
chsubdir(name)
try:
tieba_info_fp = file('%s吧信息.txt'%(name),"w")
print_f('【%s】'%(name))
pageData = urllib.urlopen(url).read()
#1、读取总相片数量
p = re.compile ('<div class="picture_amount_total">共有图片 (\d+?) 张</div>',re.S)
result = p.findall(pageData)
picture_amount_total = 0
if len(result) == 0:
print_f('可能这个贴吧不存在,或者这个程序已经不能使用')
tieba_info_fp.close()
return
else:
picture_amount_total = int(result[0])
print_f('共有图片 %d 张'%(picture_amount_total)) #2、先尝试存在相册分类的情况
p = re.compile ('<li class="catalog_li_normal.+?href="(\S+?)".+?catalog_a_inner">(.+?)<span class="catalog_a_amount">\((\d+?)\)</span>',re.S)
result = p.findall(pageData)
root_dir = os.getcwd()
if len(result)>0:
for a in result:
cat_id = a[0][10:]
cat_name = a[1]
os.chdir(root_dir)
cat_url = url+ "&cat_id=" + cat_id
read_catalog(cat_url,cat_name)
#3、没有相册分类,直接获取所有相册目录
else:
cat_url = url+ "&cat_id=all"
read_catalog(cat_url,'')
except Exception,e:
print e
finally:
tieba_info_fp.close() def main():
global tbName
args = len(sys.argv)
if args>1:
for i in range(1,args):
tbName = sys.argv[i]
print sys.argv[i]
pgUrl = pgUrl_base + tbName
read_root(pgUrl,tbName)
else:
tbName = raw_input("输入贴吧名称:")
pgUrl = pgUrl_base + tbName
read_root(pgUrl,tbName) if __name__ == '__main__':
main()

  

python写的百度贴吧相册下载的更多相关文章

  1. python写的百度图片爬虫

    学了一下python正则表达式,写一个百度图片爬虫玩玩. 当技术遇上心术不正的人,就成我这样的2B青年了. python3.6开发.程序已经打包好,下载地址: http://pan.baidu.com ...

  2. 用python写一个百度翻译

    运行环境: python 3.6.0 今天处于练习的目的,就用 python 写了一个百度翻译,是如何做到的呢,其实呢就是拿到接口,通过这个接口去访问,不过中间确实是出现了点问题,不过都解决掉了 先晾 ...

  3. 用python实现的百度音乐下载器-python-pyqt-改进版

    之前写过一个用python实现的百度新歌榜.热歌榜下载器的博文,实现了百度新歌.热门歌曲的爬取与下载.但那个采用的是单线程,网络状况一般的情况下,扫描前100首歌的时间大概得到40来秒.而且用Pyqt ...

  4. 疯狂Python讲义PDF高清完整版免费下载|百度网盘

    百度网盘:疯狂Python讲义PDF高清完整版免费下载 提取码:uzba 内容简介 <疯狂Python讲义>既是一本适合初学者入门Python的图书(一个8岁的小朋友在未出版前已学习了本书 ...

  5. 从Python开始学编程|PDF百度网盘免费下载|Python新手入门

    百度网盘免费下载:从Python开始学编程|附PDF免费下载 提取码:7nkf 豆瓣评分: 本书封面: 读者评论: 内容简介  · · · · · · 改编自Vamei博客的<Python快速教 ...

  6. 笨办法学Python 3|百度网盘免费下载|新手基础入门书籍

    点击下方即可百度网盘免费提取 百度网盘免费下载:笨办法学Python 3 提取码:to27 内容简介: 本书是一本Python入门书,适合对计算机了解不多,没有学过编程,但对编程感兴趣的读者学习使用. ...

  7. Python编程导论第2版|百度网盘免费下载|新手学习

    点击下方即可免费下载 百度网盘免费下载:Python编程导论第2版 提取码:18g5 豆瓣评论: 介绍: 本书基于MIT 编程思维培训讲义写成,主要目标在于帮助读者掌握并熟练使用各种计算技术,具备用计 ...

  8. 像计算机科学家一样思考Python(第2版)|百度网盘免费下载|Python新手入门资料

    像计算机科学家一样思考Python(第2版)|百度网盘免费下载 提取码:01ou 内容简介  · · · · · · 本书以培养读者以计算机科学家一样的思维方式来理解Python语言编程.贯穿全书的主 ...

  9. 《谁说菜鸟不会数据分析》高清PDF全彩版|百度网盘免费下载|Python数据分析

    <谁说菜鸟不会数据分析>高清PDF全彩版|百度网盘免费下载|Python数据分析 提取码:p7uo 内容简介 <谁说菜鸟不会数据分析(全彩)>内容简介:很多人看到数据分析就望而 ...

随机推荐

  1. Android 仿百度网页音乐播放器圆形图片转圈播放效果

    百度网页音乐播放器的效果  如下 : http://www.baidu.com/baidu?word=%E4%B8%80%E7%9B%B4%E5%BE%88%E5%AE%89%E9%9D%99& ...

  2. Oracle 课程八之跟踪事件set event

    一.Oracle跟踪文件 Oracle跟踪文件分为三种类型: 一种是后台报警日志文件,记录数据库在启动.关闭和运行期间后台进程的活动情况,如表空间创建.回滚段创建.某些alter命令.日志切换.错误消 ...

  3. MySQL 5.6 复制:GTID 的优点和限制(第一部分)

    全局事务标示符(Global Transactions Identifier)是MySQL 5.6复制的一个新特性.它为维护特定的复制拓扑结构下服务器的DBA们大幅度改善他们的工作状况提供了多种可能性 ...

  4. adb remount 失败remount failed: Operation not permitted

    1. 进入shell adb shell 2. shell下输入命令 shell@android:/ $ sushell@android:/ # mount -o rw,remount -t yaff ...

  5. LeetCode题解——Palindrome Number

    题目: 判断一个数字是不是回文数字,即最高位与最低位相同,次高位与次低位相同,... 解法: 求出数字的位数,然后依次求商和求余判断是否相等. 代码: class Solution { public: ...

  6. QT5.3+VS2013+QCustomPlot+QwtPlot+QwtPlot3D使用环境配置

    VS安装QT后运行环境所需配置 安装好QT和QT在VS下的插件之后: 1.打开VS,找到QT5→QT Option,如下: 2.配置电脑环境变量,在系统变量→Path下增加QT的动态库所在文件夹,也就 ...

  7. Lucene学习笔记: 五,Lucene搜索过程解析

    一.Lucene搜索过程总论 搜索的过程总的来说就是将词典及倒排表信息从索引中读出来,根据用户输入的查询语句合并倒排表,得到结果文档集并对文档进行打分的过程. 其可用如下图示: 总共包括以下几个过程: ...

  8. IOS下arm64汇编疑问

    之前所有关于32位下的纯汇编.s代码,在编译arm64的时候,很多错误,不得已只能用C代码. 但是arm_neon.h内部类C接口的汇编,基本上没有问题.不敢完全保证,还有待确认.关于arm64位的汇 ...

  9. homework03

    代码实现真的是大问题……在第二次作业还没有真正实现的情况下只能写这么一篇博客来整理一下从各位大神那里看到的东西. 两个弱菜加起来同样是弱菜,所以我和我的小伙伴的配合就是悲剧的聚合. 首先,大家都说C# ...

  10. ubuntu下修改时区

    使用一个虚拟机服务,其时区设置的为格林兰标准时区,我北京时区在东八区,较其快八个小时. 修改时区需要执行 tzselect 一步步选择下来,注意确认后的information Therefore TZ ...