网页爬虫抓取百度图片(【干货】网页的壁纸都爬取了,你知道吗?)
优采云 发布时间: 2022-03-05 04:12网页爬虫抓取百度图片(【干货】网页的壁纸都爬取了,你知道吗?)
前言
我想每个人都更喜欢漂亮的照片!不要隐瞒任何事情,每个人都知道对美丽的热爱。小编最近也比较无聊,就去爬壁纸、图片等。所以我添加了一些代码来抓取整个网页的所有壁纸。
目录 1:概述
在电脑上,创建一个文件夹,用来存放爬到对方桌面的图片
这个文件夹下有25个文件夹,对应分类
每个分类文件夹下有几个文件夹,对应页码
在页码文件夹下,存放图片文件
目录二:环境准备
在终端中分别输入以下 pip 命令进行安装
python -m pip install beautifulsoup4
python -m pip install lxml
python -m pip install requests
内容三:分析页面结构
4k类别下的壁纸是网站收入的重要资源,我们对4k壁纸有需求,所以不抓取
我用审美类下的壁纸来讲解下如何爬取图片
1.一共73页,除了最后一页,每页18张图片
但是在代码中,我们最好需要自动获取总页码,嗯,对方桌面壁纸网站的结构真的很舒服,基本上每个页码的html结构都差不多
CSS选择器:div.page a,定位到包裹页数的a标签,只有6个
并且每页第三张图片是同一个广告,需要在代码中过滤掉
每个分页的超链接清晰:/weimei/index_x.htm
x 正是页面的页码
注意:您在类别下看到的图片是低分辨率的缩略图;要得到分辨率为1920×1080的图片,需要进行两次跳转
下图是一个例子
在分类页面中,我们可以直接获取图片的url,但遗憾的是,它的分辨率并不理想;
通过检查,很明显类别页面中显示的每个图像都指向另一个超链接
CSS选择器:div#main div.list ul li a,定位到包裹图片的a标签
点击图片,第一次跳转,跳转到新链接,页面显示如下内容:
CSS选择器:div#main div.endpage div.pic div.pic-down a,找到包裹图片的a标签
点击按钮下载壁纸(1920×1080),第二次跳转,转向新链接,最终达到目的,链接中显示的图片分辨率为1920×1080
几经周折,终于为我找到了图片的1920×1080高清图
CSS选择器:div#main table a img,定位图片的img标签
经过我自己的爬虫检查,很少有图片因为很多碎片问题而无法下载,还有少数图片是因为网站虽然提供了1920×1080分辨率的下载按钮,但还是给了其他决议。
目录4:代码分析
第一步:设置全局变量
index = 'http://www.netbian.com' # 网站根地址
interval = 10 # 爬取图片的间隔时间
firstDir = 'D:/zgh/Pictures/netbian' # 总路径
classificationDict = {} # 存放网站分类子页面的信息
第二步:获取页面过滤后的内容列表
def screen(url, select):
html = requests.get(url = url, headers = UserAgent.get_headers()) # 随机获取一个headers
html.encoding = 'gbk'
html = html.text
soup = BeautifulSoup(html, 'lxml')
return soup.select(select)
第三步:获取所有类别的 URL
# 将分类子页面信息存放在字典中
def init_classification():
url = index
select = '#header > div.head > ul > li:nth-child(1) > div > a'
classifications = screen(url, select)
for c in classifications:
href = c.get('href') # 获取的是相对地址
text = c.string # 获取分类名
if(text == '4k壁纸'): # 4k壁纸,因权限问题无法爬取,直接跳过
continue
secondDir = firstDir + '/' + text # 分类目录
url = index + href # 分类子页面url
global classificationDict
classificationDict[text] = {
'path': secondDir,
'url': url
}
在接下来的代码中,我将使用审美类别下的壁纸来讲解如何通过两次跳转链接爬取高清图片
第四步:获取分类页面下所有页面的url
大多数类别的分页大于等于6页,可以直接使用上面定义的screen函数,select定义为div.page a,然后screen函数返回的列表中的第六个元素可以得到最后一个我们需要的页码
但是,有些类别的页数少于 6 页,例如:
您需要重写一个过滤器函数以通过兄弟元素获取它
# 获取页码
def screenPage(url, select):
html = requests.get(url = url, headers = UserAgent.get_headers())
html.encoding = 'gbk'
html = html.text
soup = BeautifulSoup(html, 'lxml')
return soup.select(select)[0].next_sibling.text
获取分类页面下所有分页的url
url = 'http://www.netbian.com/weimei/'
select = '#main > div.page > span.slh'
pageIndex = screenPage(secondUrl, select)
lastPagenum = int(pageIndex) # 获取最后一页的页码
for i in range(lastPagenum):
if i == 0:
url = 'http://www.netbian.com/weimei/index.htm'
else:
url = 'http://www.netbian.com/weimei/index_%d.htm' %(i+1)
由于网站的HTML结构非常清晰,代码写起来也很简单
第五步:获取分页下图片指向的URL
通过查看可以看到获取到的url是相对地址,需要转换成绝对地址
select = 'div#main div.list ul li a'
imgUrls = screen(url, select)
这两行代码得到的列表中的值是这样的:
星空 女孩 观望 唯美夜景壁纸
第 6 步:找到 1920 × 1080 分辨率的图像
# 定位到 1920 1080 分辨率图片
def handleImgs(links, path):
for link in links:
href = link.get('href')
if(href == 'http://pic.netbian.com/'): # 过滤图片广告
continue
# 第一次跳转
if('http://' in href): # 有极个别图片不提供正确的相对地址
url = href
else:
url = index + href
select = 'div#main div.endpage div.pic div.pic-down a'
link = screen(url, select)
if(link == []):
print(url + ' 无此图片,爬取失败')
continue
href = link[0].get('href')
# 第二次跳转
url = index + href
# 获取到图片了
select = 'div#main table a img'
link = screen(url, select)
if(link == []):
print(url + " 该图片需要登录才能爬取,爬取失败")
continue
name = link[0].get('alt').replace('\t', '').replace('|', '').replace(':', '').replace('\\', '').replace('/', '').replace('*', '').replace('?', '').replace('"', '').replace('', '')
print(name) # 输出下载图片的文件名
src = link[0].get('src')
if(requests.get(src).status_code == 404):
print(url + ' 该图片下载链接404,爬取失败')
print()
continue
print()
download(src, name, path)
time.sleep(interval)
第 7 步:下载图像
# 下载操作
def download(src, name, path):
if(isinstance(src, str)):
response = requests.get(src)
path = path + '/' + name + '.jpg'
while(os.path.exists(path)): # 若文件名重复
path = path.split(".")[0] + str(random.randint(2, 17)) + '.' + path.split(".")[1]
with open(path,'wb') as pic:
for chunk in response.iter_content(128):
pic.write(chunk)
目录五:代码容错
1:过滤图片广告
if(href == 'http://pic.netbian.com/'): # 过滤图片广告
continue
二:第一次跳转到页面,没有我们需要的链接
对方壁纸网站,给第一个跳转页面的链接一个相对地址
但是很少有图片直接给出绝对地址,并且给出类别URL,所以需要分两步处理
if('http://' in href):
url = href
else:
url = index + href
...
if(link == []):
print(url + ' 无此图片,爬取失败')
continue
以下是第二次跳转页面遇到的问题
三:由于权限问题无法爬取图片
if(link == []):
print(url + "该图片需要登录才能爬取,爬取失败")
continue
四:获取img的alt作为下载的图片文件的文件名,名称中带有\t或者文件名中不允许出现的特殊字符:
name = link[0].get('alt').replace('\t', '').replace('|', '').replace(':', '').replace('\\', '').replace('/', '').replace('*', '').replace('?', '').replace('"', '').replace('', '')
五:获取img的alt作为下载的图片文件的文件名,名称重复
path = path + '/' + name + '.jpg'
while(os.path.exists(path)): # 若文件名重复
path = path.split(".")[0] + str(random.randint(2, 17)) + '.' + path.split(".")[1]
六:图片链接404
例如
if(requests.get(src).status_code == 404):
print(url + ' 该图片下载链接404,爬取失败')
print()
continue
目录 6:完整代码
最后
动动你的小手发财,给小编一份关心是小编最大的动力,谢谢!