思路:
- 根据输入的关键字,获取想要爬取的百度图片页的url地址
- 为了方便抓取,把瀑布页的展示模式改为翻页式
- 寻找翻页url的规律,获取需要抓取的url地址
- 分析url和html源码,通过正则表达式获取原始图片的url地址
- 通过正则表达式处理将来需要保存的图片名称
- 获取图片数据,并保存为指定名称
# !/usr/bin/python
# Filename: 通过正则表达式爬取瀑布页百度图片.py
# Data : 2020/07/23
# Author : --king--
# ctrl+alt+L自动加空格格式化
import requests
import re
import urllib.parse
import time
# 1. 获取想要爬取的百度图片url
base_url = 'https://image.baidu.com/search/index?tn=baiduimage&word='
keyword = input('请输入您想要爬取的图片类型名称:')
# 通过parse.quote处理汉字成url地址
url = base_url + urllib.parse.quote(keyword)
# print(url)
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3756.400 QQBrowser/10.5.4043.400',
'Connection': 'close'}
# 2. 把瀑布页的显示模式改为翻页式的
# 把url中的index换位flip
url = url.replace('index', 'flip')
# print(url)
# 3. 对比翻页的url区别,生成url列表
# 第1页:https://image.baidu.com/search/flip?tn=baiduimage&ie=utf-8&word=%E6%B1%BD%E8%BD%A6&pn=0&gsm=64&ct=&ic=0&lm=-1&width=0&height=0
# 第2页:https://image.baidu.com/search/flip?tn=baiduimage&ie=utf-8&word=%E6%B1%BD%E8%BD%A6&pn=20&gsm=3c&ct=&ic=0&lm=-1&width=0&height=0
# 一页显示的图片为20张,所以,是pn=控制的页数,第n页的pn值为为(n-1)*20
page = int(input('请输入需要爬取的页数:'))
page_list = []
for i in range(page):
pn = i * 20
page_url = url + '&pn=' + str(pn)
page_list.append(page_url)
# print(page_list)
# 4. 分析每页的url,用正则表达式过滤出需要下载的图片地址
# 分析第一张图片的url
for page_url in page_list:
# img_url = 'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1950373094,1563522557&fm=26&gp=0.jpg'
# 查看网页源代码,发现该地址出现多次
# {"thumbURL":"https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1950373094,1563522557&fm=26&gp=0.jpg","middleURL":"https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1950373094,1563522557&fm=26&gp=0.jpg","largeTnImageUrl":"","hasLarge" :0,"hoverURL":"https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1950373094,1563522557&fm=26&gp=0.jpg","pageNum":19,"objURL":"http://5b0988e595225.cdn.sohucs.com/images/20180111/3af197dd52dd4d3fae2943ff039a7416.jpeg"}
# 发现objURL与众不同,打开链接发现就是该原始图片
# thumbURL,middleURL,largeTnImageUrl,hasLarge,hoverURL是该图片的不同尺寸和功能对应的图片地址
# 缩略图,中等大小,大图,超大图,悬停图
# 所以我们只需要抓取objURL对应的图片即可
# 请求html页面内容
image_html = requests.get(page_url, headers=headers).text
# 对html源码进行正则匹配
image_urls = re.findall(r'"objURL":"(.*?)"', image_html)
# 如果没有数据,首先检查是否拿到了正确的html,其次检查正则
for image_url in image_urls:
# print(image_url)
# 5. 处理需要保存的文件名对图片进行下载保存
# 注意'.'这种特殊符号,需要用'\'进行转义
image_name = re.search(r'http://.*?(.{8})\.[jpg,jpeg,png,gif,bmp]', image_url, re.I)
# 处理图片地址不带后缀名的情况
if image_name == None:
# 处理文件名中多余的'/'',替换为'_'
image_name = image_url[-8:].replace('/', '_').replace('.', '_') + '.jpg'
print(image_name)
else:
# 处理文件名中多余的'/',替换为'_'
image_name = image_name.group(1).replace('/', '_').replace('.', '_') + '.jpg'
print(image_name)
with open('img/' + image_name, 'wb') as f:
# 防止连接错误导致程序中断,进行异常处理
try:
req = requests.get(image_url, headers=headers).content
f.write(req)
time.sleep(0.5)
except Exception as e:
print(e)
time.sleep(3)
print('第', page_list.index(page_url) + 1, '页下载完毕')
需要注意的地方:
- url请求中的中文关键字需要进行urllib.parse.quote()进行解析处理
- 瀑布页到翻页式的转换,index → flip只在百度适用
- 百度图片存在多种格式,原始页面地址要在html源码中查找获得
- 正则表达式的匹配要注意对匹配partten前加r,要对特殊字符前加‘'进行处理
- 图片名称中可能存在特殊字符,如‘\’,会影响文件保存,要替换为其他字符
- 为了避免请求速度过快,添加延时
- 为了避免连接问题导致程序中断,加入异常处理

本文介绍了如何使用Python进行网络爬虫,针对百度图片进行爬取。内容包括利用正则表达式抓取图片URL,处理中文关键字,将瀑布流页面转化为翻页模式,处理图片名称及异常,以及加入延时策略防止请求过快。
1253

被折叠的 条评论
为什么被折叠?



