python 爬虫练习项目:爬图片,目标网站 http://www.win4000.com/ 美桌图片
主要思路:
该网站存在’http://www.win4000.com/meinvtag’ + str(i) + ‘_1.html’ 这样的一个链接形式的多个图片分类集合页面,暂时叫做tag页面吧,每个tag下面有5页组成(range(1, 6): # 共5个页面),
1、获取所有tag页面:
遍历所有tag页面,寻找r.status_code 为 200的页面,同时分析页面,通过find(‘h2’)的标签,寻找此tag页面的名称,将存在的页面的名称和地址放入字典返回。
def get_all_tag():
'''
获取 http://www.win4000.com/meinvtag 下所有tag_
'''
2、获取图集地址
每一个tag页面有5页,每页有24个图集,获取这24个图集的地址,讲图集名称和图集地址放入字典返回。
def get_url_dict(tag_name, tag_url):
'''
获取所有this tag_url tag_name页面上,每一个图片集的地址
'''
3、获取图片地址
根据每个图集的其实地址,找到图集的图数量(通过标签h2),通过数量遍历图集的所有地址,通过’img’, class_='pic-large’定位,通过’data-original’找到图片地址,将图集下所有图片的地址放入了list,返回。
def get_image_url(name, url):
'''
获取每一个图集的图片地址
'''
4、通过urllib.request下载,通过os.path 进行下载路径的操作。
代码:
#! /usr/bin/env/python3
# _*_ coding:utf-8 _*_
'''
练习爬虫:获取图片 http://www.win4000.com/meinvtag。。。。。
日期:2020/03/05
功能:
1.0:获取图片url存到list request bs4
2.0:下载图片到本地 os tkinter
3.0:增加所有页面 http://www.win4000.com/meinvtag4_1.html meinv_tag1 2 3 4
'''
import requests as re
from bs4 import BeautifulSoup as bs
import tkinter as tk
from tkinter.filedialog import askdirectory
import urllib.request
import os
def get_html_soup(url):
'''
函数:根据网页返回soup对象
'''
r = re.get(url, timeout=30)
s = bs(r.text, 'lxml')
return s
def get_url_dict(tag_name, tag_url):
'''
获取所有this tag_url tag_name页面上,每一个图片集的地址
'''
count = 0 # 记录图集个数
url_dict = dict() # 存放每一个图片集名称和地址
print('开始获取《' + tag_name + '》下所有图集地址:')
for i in range(1, 6): # 共5个页面
url = tag_url[:-6] + str(i) + '.html'
s = get_html_soup(url)
div_list_s = s.find('div', class_='Left_bar')
for li_list_s in div_list_s.find_all('li'):
# print(li_list_s)
url_values = li_list_s.find('a')['href']
url_name = li_list_s.find('img')['title']
# print(url_name)
# print(url_values)
url_dict[url_name] = url_values # 把图集名称和地址存进字典
# rint('***************')
count += 1 # 计数器加一
if count % 5 == 0:
print('正在获取第{}个图集...'.format(count))
print('《' + tag_name + '》所有图集地址获取完毕,共获取到了{}个图集地址。'.format(count))
# for name, url in url_dict.items():
# print(name+' : '+url)
return url_dict
def get_image_url(name, url):
'''
获取每一个图集的图片地址
'''
url_list = [] # 存放一个图集的图片地址
s = get_html_soup(url)
max_num_of_image = int(s.find('em').text)
# print(name + ' 该图集共有{}张图:'.format(max_num_of_image))
image_url_s = s.find('img', class_='pic-large')
# print(image_url_s)
url_list.append(image_url_s['data-original']) # 第一张图的地址
for i in range(2, max_num_of_image + 1):
url_n = url[:-5] + '_' + str(i) + '.html'
s = get_html_soup(url_n)
image_url_s = s.find('img', class_='pic-large')
url_list.append(image_url_s['data-original'])
return url_list
def down_save_image(tag_name, filepath, all_images_dict):
'''
根据图集名称,以及图集的图片地址下载图片
'''
def callbackfunc(blocknum, blocksize, totalsize):
'''
进度计算函数:
blocknum: 已经下载的数据块
blocksize: 数据块的大小
totalsize: 远程文件的大小
'''
percent = 100.0 * blocknum * blocksize / totalsize
if percent > 100:
percent = 100
if percent % 10 == 0 and percent <= 100:
print('图片已经下载{}%'.format(percent))
images_num = 0
num = 1
for name, images_url_list in all_images_dict.items():
if not os.path.exists(filepath + '/' + tag_name + '/' + name):
os.makedirs(filepath + '/' + tag_name + '/' + name)
count = 1
for image_url in images_url_list:
images_num += 1
print('正在下载第{}个图片集:<'.format(num) + name +
'>的第{}张图片'.format(count))
result = urllib.request.urlretrieve(image_url,
filename=filepath + '/' +
tag_name + '/' + name + '/' +
str(count) + '.jpg',
reporthook=callbackfunc,
data=None)
print('第{}个图片集:<'.format(num) + name +
'>的第{}张图片以保存在:'.format(count) + result[0])
count += 1
num += 1
print('××××××××××××××××××××××××××××××××××××')
print('下载完成,共下载{}张图。'.format(images_num))
def get_filepath(tag_name):
'''
获取文件存放地址
'''
print('选择文件保存位置')
window = tk.Tk()
window.withdraw()
filepath = askdirectory(title=u'选择tag:《' + tag_name + '》的保存路径')
while len(filepath) == 0:
print('重新选择tag:《' + tag_name + '》的保存路径')
filepath = askdirectory(title=u'选择tag:《' + tag_name + '》的保存路径')
# print(filepath)
return filepath
def get_all_tag():
'''
获取 http://www.win4000.com/meinvtag 下所有tag_
'''
key = []
tag_dict = dict()
for i in range(60):
url = 'http://www.win4000.com/meinvtag' + str(i) + '_1.html'
r = re.get(url, timeout=30)
# print('i是{}'.format(i), r)
if r.status_code == 200:
key.append(i)
# print('http://www.win4000.com/meinvtag' + str(i) + '_1.html')
s = bs(r.text, 'lxml')
title_s = s.find('h2')
title = title_s.text
tag_dict[title] = 'http://www.win4000.com/meinvtag' + str(
i) + '_1.html'
print('meinvtag{}是:'.format(i), title)
# print(key)
# for i in tag_dict:
# print(i+' : '+tag_dict[i])
return tag_dict
def main():
'''
主函数
'''
all_tag_dict = get_all_tag() # 获取tag的地址和名称的字典
tag_count = 0 # 记录tag数量
image_num = 0 # 记录图片数量
all_tag_num = len(all_tag_dict)
print('共计{}个tag\n'.format(all_tag_num))
for tag_name, tag_url in all_tag_dict.items():
tag_count += 1
print('总计{}个tag,正在对第{}个tga<{}>进行检索和下载。'.format(all_tag_num, tag_count,
tag_name))
url_dict = get_url_dict(tag_name, tag_url) # 获取改tag的所有图片集的地址
all_images_dict = dict() # 存放this tag所有图片的地址
count = 0 # 记录进度
nums = 0 # 总图数量
for name, url in url_dict.items():
count += 1
print('开始获取《' + tag_name + '》的第{}个图集的图片的地址......'.format(count))
image_all_list = get_image_url(name, url)
all_images_dict[name] = image_all_list
print('《' + tag_name + '》共{}个图集,第{}个图集的图片地址获取完成,该图集共有{}张图'.format(
len(url_dict), count, len(image_all_list)))
nums += len(image_all_list)
print('《' + tag_name + '》的{}个图集的所有图集地址获取完毕,共图片{}张'.format(count, nums))
image_num += nums
# for i in all_images_dict:
# print(i)
filepath = get_filepath(tag_name)
down_save_image(tag_name, filepath, all_images_dict)
print('共进行了{}个tag,共计{}张图'.format(tag_count, image_num))
print('存放在:' + filepath + '/')
if __name__ == '__main__':
main()
初学python,希望大神们多多指教~
主要参考的是:
https://blog.csdn.net/weixin_43087443/article/details/88079081
python自学,在此感谢。
廖雪峰的网站:
https://www.liaoxuefeng.com/wiki/1016959663602400
菜鸟:
https://www.runoob.com/python/python-tutorial.html
小象学院的python课程,应该是梁斌老师吧。