windows系统已经可以直接运行,下载地址:
https://pan.baidu.com/s/13JBRXRFKCtpe9qHhDXajHw 提取码: hnw3
import re,os,time,random,lxml,sys
from lxml import etree
import requests
from bs4 import BeautifulSoup
from requests.adapters import HTTPAdapter
from concurrent.futures import ThreadPoolExecutor,wait,ALL_COMPLETED
os.system('title 优美图吧整站爬虫程序 @小伍的游乐场')#设置窗口标题
#coding:utf-8
down_path = 'meitu11'
if not os.path.exists(down_path):
os.makedirs(down_path)
def theuseragent(html):#访问,且带着useragent,return的是text文本内容
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36'}
# i = random.randint(1,3)#不需要,如果要速度快,这里和下面则屏蔽
# time.sleep(i)#最大问题就是这里,time.sleep就应该放这里,然后下边的requests.get设置timeout
print('=' * 20)
print(f'已开启随机等待,等待时间为{i}秒')
s = requests.session()#加入会话保持系统
s.mount('http://', HTTPAdapter(max_retries=10))#http和https都为最大重试10次
s.mount('https://', HTTPAdapter(max_retries=10))
print(time.strftime('%Y-%m-%d %H:%M:%S'))
x = 0
while x < 10:#while错误重试10次,与上面的max_retries相同,加起来等于每个链接重试21次
try:
r = s.get(html,headers=headers,timeout = (20,20))
if r.status_code == 200:
return r.text
print('该地址已经return')
except requests.exceptions.RequestException as e:#必须加入except,否则程序爆出的错误让你无法定位,之前没加我的程序报我语法错误,且错误在pagenum()
print(e)
x += 1
print(time.strftime('%Y-%m-%d %H:%M:%S'))
#首页内找到所有翻页,共计72页,这里用正则无法获取每个href,改为使用xpath直接获取最大页数
def pagenum(html):
html = etree.HTML(html)
#下边是在首页里找到最大翻页数量
result = html.xpath('/html/body/div[5]/div/nav/div/a[6]/text()')
return result[0]
def fenxi(html):#分析文本内容模块,正则寻找href的网址链接
zhengze = re.compile('li class.*?a href="(.*?)"',re.S)
first_pic_url = re.findall(zhengze,html)
if len(first_pic_url) == 0:#判断列表是否为空
print('该页面为空!不存在url分页列表')
return 0
else:
return first_pic_url
def lastpage(content):#获取每一页的lastpage
zhengze = re.compile('page-numbers".*?"最后页">(.*?)</a>',re.S)
title1 = re.compile('<h1>(.*?)</h1>',re.S)
picurl = re.findall(zhengze,content)#取得每个页面的最大page,例如某图集最大42页
title = re.findall(title1,content)
if len(picurl) == 0:#判断列表是否为空
print('该页面为空,不存在最大页面: ',title)
return 0
else:
lastpage = picurl[0]#最大page是列表,取出来使用
return lastpage
def down_pic(content):
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36'}
picnamezz = re.compile('content_left.*?<a.*?"(.*?)".*?title.*?查看下一张',re.S)
picname = re.findall(picnamezz,content)
picname1 = re.sub('\W','',picname[0])
print('picname1是:',picname1)
jpgnow = re.compile('content_left.*?<a.*?".*?".*?title.*?查看下一张.*?src="(.*?)"',re.S)
jpgdown = re.findall(jpgnow,content)#图片绝对地址
html = etree.HTML(content)
filename = html.xpath('/html/body/div[3]/div/div/div[1]/div/text()[3]')#取的是发布时间,因为windows下创建目录有很多符号不支持
print('该图集名称为:',filename)
s = requests.session()#加入会话保持系统
s.mount('http://', HTTPAdapter(max_retries=3))#http和https都为最大重试3次
s.mount('https://', HTTPAdapter(max_retries=3))
try:
jpgget = s.get(jpgdown[0],headers=headers,timeout = (30,30))#这里的timeout分别是链接时间和读取时间,超时自动放弃
except requests.exceptions.RequestException as e:#必须加入except,否则程序爆出的错误让你无法定位,之前没加我的程序报我语法错误,且错误在pagenum()
print(e)
print(time.strftime('%Y-%m-%d %H:%M:%S'))
pass
down_path1 = f'meitu11/{filename}'
if not os.path.exists(f'meitu11/{filename}'):
os.makedirs(f'meitu11/{filename}')
try:
#print(jpgdown) #打印图片绝对网址
with open(f'meitu11/{filename}/{picname1}.jpg','wb') as f:
f.write(jpgget.content)
print(f'已完成{picname}的下载')
except:
print('该图片下载超时,自动跳过...')
def main():
ex = ThreadPoolExecutor(max_workers=20)#多线程处理模块,开启10线程赋值给变量ex
start_url = 'https://www.umtuba.com/'
urlsnum = []
urls = []
urls2 = []
html = theuseragent(start_url)
for i in range(1,int(pagenum(html))+1):#element格式转换为int格式
urlsnum.append('https://www.umtuba.com' + f'/page_{i}.html')
print(f'正在添加首页的分页到urlsnum:\n',urlsnum[-1])
for i in urlsnum:#遍历urlsnum里面的每一条url
html = theuseragent(i)
if fenxi != 0:
for num in fenxi(html):
urls.append('https://www.umtuba.com' + num)#将这些相册的url用append方法从尾部添加到urls列表内
print('正在添加分页的相册到urls: ')
print(num)
else:
print('已判断相册为空,Pass!')
continue
for url in urls:
print('#' * 50)
print(url)
aurl = theuseragent(url)
lastpage(aurl)
if lastpage != 0:#如果这里加入判断,在pastpage模块也必须加入判断,否则报错
i = int(lastpage(aurl))
print('=-' * 50)
print('该条url是:' + url)
print('该图集有:',i,'页.')#这里打印每一页的最大page
for x1 in range(1,i+1):
pingjie1 = re.sub('.html','',url)#将.html替换为空
pinjie2 = pingjie1+'_'+ str(x1) +'.html'
urls2.append(pinjie2)
# print('已添加第:',x1,'页的:',pinjie2)#这里打印的是网图的绝对网址
# print('=' * 50)
print('网址拼接中,请耐心等待!')
elif lastpage == 0:
print('已判断页面为空,Pass!')
pass#判断页面为空则不需要拼接网址,所以这里pass,不影响for url in urls的循环
continue
# for item in urls2:#如果从这里就开始循环,等于多线程没有用上
# html2 = theuseragent(item)
future = [ex.submit(down_pic,theuseragent(item)) for item in urls2]#应该从这里开始循环.(变量ex就是20线程,上面有说明,)
wait(future,return_when=ALL_COMPLETED)#多线程处理模块的wait,等待括号内的所有内容结束,加入timeout
print('=' * 50)
print('程序运行完毕,请关闭!')
main()
2020年4月2008:48
我发现爬的真的挺慢的,以下图片是我程序运行12小时以上的截图,他已经爬了一晚上了,程序不再中断了,可是真的下载了一晚上也还在下
2020年4月19日21:01,程序测试后运转正常,timeout依然存在,只是在4次timeout之外依然加入了10次重试!测试发现有些图集是会员登录才能查看的,本程序不支持,如果有会员账号的可以借我使用
4月19,18:05不动声色地改了改
修复了fenxi()模块的出错,加入if
按照我之前写的程序逻辑,可能x1循环部分没办法加入多线程了...这样程序需要运行很久,烦躁中
4月18日10:53分我手动停止了程序,程序从昨天开始跑起,到现在我起床,一切正常,依然在运行..
还担心硬盘装不下,没想到程序目录写的有问题,程序压根就没保存到本地....
目前已修复
2020-4-18 01:42,昨天开始运行,由于对方服务器问题中断过几次,没有什么大的修改,代码已更新,目前很久了,程序一直在跑,没停下来.跑了很久很久了,我都困了.一会还在跑我就去睡觉,让他继续跑,估计我盘装不下那么多图. 囧...
2020年4月17日20:15分
已经完成所有内容,只差windows下直接运行打包为exe程序了.程序依然有部分由于网站延迟导致的错误,对方网站在海外,等以后慢慢更新吧,应该做一个文档记录url,每down一个就删除该url
自动下载每个图集自动创建文件夹,文件夹的名称并非图集的名称,而是网站创建的时间为名称,因为windows下很多符号不支持创建文件夹,而图集包含这些符号,所以只能使用发布的时间来创建文件夹
2020年4月17日更新
基本已经完成了,lastpage的问题已经解决,挂在这里等他down了,出门了
22:12更新
暂时没有找到 lastpage为None的解决办法,明天再说
4月16日 17:24更新
程序运行后发现编号56130的url页面内没有任何东西,程序每次卡在这里,终于定位到了这个页面,现在将lastpage更新,若不存在最大页面,直接pass.
pass会中断程序,改为了print.
拼接模块有问题,lastpage需要+1
且本次更新之后本文最上面的代码保持为最新,不再另外记录错误代码,也不再保存.
每次更新的内容改为填写在代码下更新段落的第一行,旧的直接被顶下去.
2020年4月15日18:58更新内容
更新为爬取整站图片(等待时间很长,downer注意)
更新自动添加文件夹,每个系列自动创建文件夹且将图片放入该文件夹
更新各种BUG
更新加入了xpath
程序为全自动程序,等待时间漫长,且不做任何下载记录,若你下载过的或者没下载过的,程序都不做记录
每次运行从头开始运行.
以后也不打算加入记录功能,因为涉及到数据库或者本地文档的读取
以后打算加入的功能:
选择功能(使用者键入1,2,3,4这样的数字来选择下载哪一个图集)
import re,os,time,random,lxml
from lxml import etree
import requests
from bs4 import BeautifulSoup
from concurrent.futures import ThreadPoolExecutor,wait,ALL_COMPLETED
#coding:utf-8
i = random.randint(1,5)
down_path = './meitu11'
if not os.path.exists(down_path):
os.makedirs(down_path)
def theuseragent(html):#访问,且带着useragent,return的是text文本内容
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36'}
time.sleep(i)#最大问题就是这里,time.sleep就应该放这里,然后下边的requests.get设置timeout
print('=' * 20)
print(f'已开启随机等待,等待时间为{i}秒')
r = requests.get(html,headers=headers,timeout = (10,10))
if r.status_code == 200:
return r.text
print('该地址已经return')
return None
def pagenum(html):#首页内找到所有翻页,共计72页,这里用正则无法获取每个href,改为使用xpath直接获取最大页数
html = etree.HTML(html)
result = html.xpath('/html/body/div[5]/div/nav/div/a[6]/text()')#在首页里找到最大翻页数量
return result[0]
def fenxi(html):#分析文本内容模块,正则寻找href的网址链接
zhengze = re.compile('li class.*?a href="(.*?)"',re.S)
first_pic_url = re.findall(zhengze,html)
#print(first_pic_url)
return first_pic_url
def lastpage(content):#获取每一页的lastpage
zhengze = re.compile('page-numbers".*?"最后页">(.*?)</a>',re.S)
picurl = re.findall(zhengze,content)#取得每个页面的最大page,例如某图集最大42页
lastpage = picurl[0]#最大page是列表,赋值给lastpage变量为int整数,取出来使用
return lastpage
def down_pic(content):#获取图片的name及下载地址及下载到本地
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36'}
picnamezz = re.compile('content_left.*?<a.*?"(.*?)".*?title.*?查看下一张',re.S)
picname = re.findall(picnamezz,content)
picname1 = re.sub('\W','',picname[0])
jpgnow = re.compile('content_left.*?<a.*?".*?".*?title.*?查看下一张.*?src="(.*?)"',re.S)
jpgdown = re.findall(jpgnow,content)
html = etree.HTML(html)
filename = html.xpath('/html/body/div[5]/div/ul/li[2]/a/text()')
jpgget = requests.get(jpgdown[0],headers=headers,timeout = (30,30))#这里的timeout分别是链接时间和读取时间,超时自动放弃
try:
#print(jpgdown) #打印图片绝对网址
with open(f'./meitu11/{filename}/{picname1}.jpg','wb') as f:
f.write(jpgget.content)
# time.sleep(i) #time.sleep不因该在这里,我移到上边的theuseragent模块了
print(f'已完成{picname}的下载')
except:
print('该图片下载超时,自动跳过...')
def main():
ex = ThreadPoolExecutor(max_workers=20)#多线程处理模块,开启10线程赋值给变量ex
start_url = 'https://www.umtuba.com/'
urlsnum = []
urls = []
urls2 = []
html = theuseragent(start_url)
for i in range(1,int(pagenum(html))+1):#element格式转换为int格式
urlsnum.append('https://www.umtuba.com' + f'/page_{i}.html')
for i in urlsnum:#遍历urlsnum里面的每一条url
html = theuseragent(i)
for num in fenxi(html):
urls.append('https://www.umtuba.com' + num)#将这些相册的url用append方法从尾部添加到urls列表内
print('正在添加以下URL: ')
print(num)
for url in urls:
aurl = theuseragent(url)
lastpage(aurl)
# print('=' * 50)
# print(lastpage(aurl))#这里打印每一页的最大page
for x1 in range(0,int(lastpage(aurl))):#网址拼接部分
pingjie1 = re.sub('.html','',url)#将.html替换为空
urls2.append(pingjie1+'_'+ str(x1) +'.html')#将pingjie1的内容加上_再加上x1的值在加上.html
# print(urls2)#这里打印的是网图的绝对网址
# print('=' * 50)
print('网址库更新中,请耐心等待!')
# time.sleep(0.1)
for item in urls2:#如果从这里就开始循环,等于多线程没有用上
html2 = theuseragent(item)
future = [ex.submit(down_pic,theuseragent(item)) for item in urls2]#应该从这里开始循环.(变量ex就是20线程,上面有说明,)
wait(future,return_when=ALL_COMPLETED)#多线程处理模块的wait,等待括号内的所有内容结束,加入timeout
print('=' * 50)
print('程序运行完毕,请关闭!')
main()
程序运行视频1:
https://v.qq.com/x/page/y0951r65lbl.html
=====================
2020年4月15日晚上到16日13:24更新(错误记录IndentationError: unexpected unindent)代码如下,留以备用
13:49已修复问题,问题为加入了session()会话保持和重试次数之后,记得后边的except必须加入,否则莫名其妙的错误.
记得,千万千万不要把代码复制粘贴到QQ对话框,你会发现你有改不完的空格,Tab,和标点符号
import re,os,time,random,lxml
from lxml import etree
import requests
from bs4 import BeautifulSoup
from requests.adapters import HTTPAdapter
from concurrent.futures import ThreadPoolExecutor,wait,ALL_COMPLETED
#coding:utf-8
i = random.randint(1,5)
down_path = './meitu11'
if not os.path.exists(down_path):
os.makedirs(down_path)
def theuseragent(html):#访问,且带着useragent,return的是text文本内容
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36'}
time.sleep(i)#最大问题就是这里,time.sleep就应该放这里,然后下边的requests.get设置timeout
print('=' * 20)
print(f'已开启随机等待,等待时间为{i}秒')
s = requests.session()#加入会话保持系统
s.mount('http://', HTTPAdapter(max_retries=3))#http和https都为最大重试3次
s.mount('https://', HTTPAdapter(max_retries=3))
try:
r = s.get(html,headers=headers,timeout = 20)
if r.status_code == 200:
return r.text
print('该地址已经return')
return None
#首页内找到所有翻页,共计72页,这里用正则无法获取每个href,改为使用xpath直接获取最大页数
def pagenum(html):
html = etree.HTML(html)
#下边是在首页里找到最大翻页数量
result = html.xpath('/html/body/div[5]/div/nav/div/a[6]/text()')
return result[0]
def fenxi(html):#分析文本内容模块,正则寻找href的网址链接
zhengze = re.compile('li class.*?a href="(.*?)"',re.S)
first_pic_url = re.findall(zhengze,html)
#print(first_pic_url)
return first_pic_url
def lastpage(content):#获取每一页的lastpage
html = etree.HTML(content)
lastpage = html.xpath('//*[@id="image_div"]/div/a[8]/text()')#取得每个页面的最大page,例如某图集最大42页
return lastpage[0]
def down_pic(content):#获取图片的name及下载地址及下载到本地
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36'}
picnamezz = re.compile('content_left.*?<a.*?"(.*?)".*?title.*?查看下一张',re.S)
picname = re.findall(picnamezz,content)
picname1 = re.sub('\W','',picname[0])
jpgnow = re.compile('content_left.*?<a.*?".*?".*?title.*?查看下一张.*?src="(.*?)"',re.S)
jpgdown = re.findall(jpgnow,content)
html = etree.HTML(html)
filename = html.xpath('/html/body/div[5]/div/ul/li[2]/a/text()')
jpgget = requests.get(jpgdown[0],headers=headers,timeout = (30,30))#这里的timeout分别是链接时间和读取时间,超时自动放弃
down_path1 = f'./meitu11/{filename}'
if not os.path.exists(f'./meitu11/{filename}'):
os.makedirs(f'./meitu11/{filename}')
try:
#print(jpgdown) #打印图片绝对网址
with open(f'./meitu11/{filename}/{picname1}.jpg','wb') as f:
f.write(jpgget.content)
print(f'已完成{picname}的下载')
except:
print('该图片下载超时,自动跳过...')
def main():
ex = ThreadPoolExecutor(max_workers=20)#多线程处理模块,开启10线程赋值给变量ex
start_url = 'https://www.umtuba.com/'
urlsnum = []
urls = []
urls2 = []
html = theuseragent(start_url)
for i in range(1,int(pagenum(html))+1):#element格式转换为int格式
urlsnum.append('https://www.umtuba.com' + f'/page_{i}.html')
for i in urlsnum:#遍历urlsnum里面的每一条url
html = theuseragent(i)
for num in fenxi(html):
urls.append('https://www.umtuba.com' + num)#将这些相册的url用append方法从尾部添加到urls列表内
print('正在添加以下URL: ')
print(num)
for url in urls:
aurl = theuseragent(url)
lastpage(aurl)
print('=-' * 50)
print(url)
print(lastpage(aurl))#这里打印每一页的最大page
for x1 in range(0,lastpage(aurl)):#网址拼接部分
pingjie1 = re.sub('.html','',url)#将.html替换为空
urls2.append(pingjie1+'_'+ str(x1) +'.html')
# print(urls2)#这里打印的是网图的绝对网址
# print('=' * 50)
print('网址库更新中,请耐心等待!')
for item in urls2:#如果从这里就开始循环,等于多线程没有用上
html2 = theuseragent(item)
future = [ex.submit(down_pic,theuseragent(item)) for item in urls2]#应该从这里开始循环.(变量ex就是20线程,上面有说明,)
wait(future,return_when=ALL_COMPLETED)#多线程处理模块的wait,等待括号内的所有内容结束,加入timeout
print('=' * 50)
print('程序运行完毕,请关闭!')
main()