一个简单的demo,Python采集下载图片,其中图片下载的时候采用了简单的多线程下载,未涉及到其他知识,比较简单,属于拿来就能使用的demo,供大家参考和学习,如有疑问可以加本渣渣微信探讨!
目标网址:http://www.nendo.jp/en/release/2020/
佐藤大官网作品集获取,从2003年作品到2020年作品,一键采集下载!
该网站结构比较清晰明了,适合新人爬取测试学习,推荐吧!对了,网站应该是用Wordpress开源程序搭建的!
按照惯例,几个关键点,简单阐述一下!
四次重试
在应用requests库访问的时候,可能会存在访问超时,或者出错的情况,设置好重试机制,避免你二次数据补坑,还是比较推荐的!
参考代码:
#四次重试
def get_req(self,url,headers,timeout=8,num_retries=4):
print(f">>正在爬取{url}")
try:
response=requests.get(url,headers=headers,timeout=timeout)
time.sleep(2)
except:
if num_retries > 0: ##num_retries是我们限定的重试次数
time.sleep(6) ##延迟六秒
print(u'获取网页出错,8S后将获取倒数第:', num_retries, u'次')
return self.get_req(url, headers,timeout, num_retries - 1)
else:
print(f">> 访问 {url} 失败!")
with open("fail_url.txt", 'a+', encoding='utf-8') as f:
f.write(f'{url}\n')
print(f'保存访问失败网页链接成功!')
response=[]
return response
多线程下载图片
由于详情页面可能存在不少图片需要采集,这里简单的应用了多线程,获取到页面上的所有图片,进行多线程采集下载。
参考代码:
#多线程下载图片
def dowm_imgs(self,img_urls,path):
threadings=[]
for img_url in img_urls:
t= threading.Thread(target=self.get_img,args=(img_url,path))
threadings.append(t)
t.start()
for x in threadings:
x.join()
print("多线程下载图片完成")
异常处理,可能存在链接是列表页的情况处理
很多时候,在实际采集的过程中,可能会出现各种异常,突发情况,这个时候你就需要兼容处理了,在异常的时候,或者说没有考虑到的问题上进行处理,补坑采集,比如这里出现的情况,那就是列表页面采集到的链接存在并非详情页的情况,还是一个列表页面,这里简单应用if判断,重新调用列表页链接的获取来进行处理,这样才能完整采集,跑完整个程序。
参考代码:
#获取详情页数据
def parse(self,url,year):
r = self.get_req(url, self.headers, timeout=8, num_retries=4)
html = r.content.decode('utf-8')
tree = etree.HTML(html)
if len(tree.xpath('//div[@class="entry-content"]/p'))>0:
print("该页面为详情页面")
h1 = tree.xpath('//h1[@class="entry-title"]/text()')[0]
pattern = r"[\/\\\:\*\?\"\<\>\|]"
title = re.sub(pattern, "_", h1) # 替换为下划线,去除待存储目录特殊字符
print(title)
path = f'{year}/{title}/'
os.makedirs(path, exist_ok=True)
imgs = tree.xpath('//div[@class="entry-content"]//img/@src')
print(imgs)
self.dowm_imgs(imgs, path)
else:
print("该页面非详情页面")
self.get_parseurls(url, year)
爬取效果:
完整项目源码获取
请关注本渣渣公众号
后台回复:nendo