这会儿是国内时间6点半了,感觉我是依然乐此不疲地学习怎么取爬取网站的图片,经过上一次的实验,感觉初步浅显地基本关键包的用法,以及自己本来就具有HTML的基础,这次我是找到了一个网站,从头到尾自己独立实验成功,内心有点小激动,感觉自己融会贯通的能力有上一层楼啊,于是赶紧写下来纪念一下。
话不多说,整起!
我们来爬取https://divnil.com/wallpaper/iphone/ 这个网址下的图片。
这是个日语网站,但不影响我们推理和爬取图片,总体看上去呢,网站具有一定的分层结构,https://divnil.com/wallpaper/iphone/,是根url,下面挂在了很多的tag标签的html。
每个页面的class都是“tag_link”,这样方便我们找出所有的标签,但是即得到要去重。
选择某个标签,就会出现分页式的html,命令也很有规律,就是在后面加上_num的方式。
下面这些统计是代码中爬取图片时候顺带统计打印出来的,在最后我贴了完整代码,只需要把 save_all_images 函数调用注释即可打印出所有需要访问的目录,注释到这样快一些,因为我只想看访问链接。
点击某个标签页,比如:
就会在网页下方出现
的按钮,虽然是日语,但是猜也能猜到这是下一页的意思。点击它进入分页。
所以如果我们确定了搜索某个tag,只要一直找这样的标签就能继续跳到下一个页面去爬取图片,找到这个按钮的href,经过观察,只要还在分页中,class=“btn_next”的数目就一定是等于2的,且第一个一定是按钮【下一个】,也就是我们要找的。
那么直到所有分页完了是什么情况呢?
经过观察,当分页结束了的最后一页的时候,class=“btn_next”的数目就不是2,且页面没有按钮【下一个】的字样。所以从这里可以判断出分页结束与否。
接下来我们看看每个图片的url有什么规律?
每个图片区域的< a>的“rel=wallpaper”,但是包含的img的href有的属性名是src,有的是original,这个也很好办,这里需要注意下就是。
完整测试代码如下:
import os
import requests
from bs4 import BeautifulSoup
rootrurl = 'https://divnil.com/wallpaper/iphone/'
save_dir = 'D:/estimages/'
no_more_pages = 'END'
# 这是一个集合,不能重复,也就是不能重复下载图片
image_cache = set()
index = len(image_cache)
# step 1: 找到所有的标签页
# 随便挑选了一个tag最多最全的一个页面来获取
tmpurl = 'https://divnil.com/wallpaper/iphone/%E6%98%9F%E7%A9%BA%E3%81%AE%E5%A3%81%E7%B4%99.html'
html = BeautifulSoup(requests.get(tmpurl).text, features="html.parser")
tag_list = set()
for link in html.find_all('a', {'class': 'tag_link'}):
tag_list.add(link.get('href'))
print("the number of unique tag is : %d" % len(tag_list))
print(tag_list)
# step 2: 按照每个标签页反复区按照分页形式不断往下寻找
def save_all_images(html, saveDir):
global index
imgs = html.find_all('a', {'rel': 'wallpaper'})
print('total imgs is %d:' % len(imgs))
for img in imgs:
# 有一些图片的href是src, 有一些图片的href是original,因此都是要考虑的。
href = img.find('img').get('src')
if href == '/wallpaper/img/app/white.png':
href = img.find('img').get('original')
print(href)
# 判断是否重复下载
if href not in image_cache:
with open(
'{}/{}'.format(saveDir, href.split("/")[-1]), 'wb') as jpg: # 请求图片并写进去到本地文件
jpg.write(requests.get(rootrurl + href).content)
image_cache.add(href)
print("正在抓取第%s条数据" % index)
index += 1
def findNextPage(html):
nextBtn = html.find_all('li', {'class': 'btn_next'}) # 找到next按钮,获得下一个连接网页的位置
if len(nextBtn) != 2: # 只要分页没结束,这个数目一定是2
print('no more page ============================ ')
return no_more_pages
else:
tmpurl = nextBtn[0].find('a').get('href') # 只要分页没结束,这个数目一定是2,且第一个元素一定是我们要找的“下一个”按钮。
return rootrurl + tmpurl
def serachSubPages(tag):
# 建立这个标签的子目录,图片太多了,按照标签建立子目录,方便存储和整理
tag_name = tag.split(".")[0]
if not os.path.exists(save_dir + tag_name):
os.mkdir(save_dir + tag_name)
print("current tag is : " + tag_name)
url = rootrurl + tag
while 1:
print("next page: " + url)
html = BeautifulSoup(requests.get(url).text, features="html.parser")
save_all_images(html, save_dir + tag_name)
url = findNextPage(html)
if url == no_more_pages:
break;
if __name__ == '__main__':
for tag in tag_list:
serachSubPages(tag)
测试一些后我终止了程序,因为太慢了。
效果如下: