通过re、requests、urlib、BeautifulSoup、os模块实现从百度下载指定类别图片。包含代码逐行解析。
python
import re
# 进行http请求的第三方库
import requests
from urllib import error
# 解析HTML和XML文档的库
from bs4 import BeautifulSoup
import os
num = 0
numPi = 0
file = ''
List = []
def makefile(word):
file = word + '文件'
file_na = os.path.exists(file)
if file_na == 1:
print('该文件已存在,请重新输入')
file = input('请建立一个存储图片的文件夹,输入文件夹名称即可: ')
os.mkdir(file)
else:
os.mkdir(file)
return file
# 根据地址去查找 对应的图片的信息
# 获取网页中图片URL函数
# url是目标网页的URL,A是用来发送http请求的类,通常是Request对象
def Find(url, A):
global List # 保存信息的列表,保存获取图片的URL
t = 0 # 请求时间
i = 1 # 请求次数
s = 0 # 当前获取到的图片总数
while t < 60000:
# 时间戳 不间断刷新访问网址
# 目标网页的URL与当前时间戳t拼接,形成一个新的url
Url = url + str(t)
try:
# get获取数据,访问拼接后的url
Result = A.get(Url, timeout=7, allow_redirects=False)
# 捕获所有请求超时、URL错误等异常
except BaseException:
# 每一页有60张图片所以
t = t + 60
continue
else:
# 拿到网站的数据,捕获到的网页内容给result变量
result = Result.text
# 找到图片url,使用正则表达式从网页内容中提取图片url,并将结果赋值给pic_url变量
pic_url = re.findall('"objURL":"(.*?)",', result, re.S)
# 图片总数
# 提取到的图片url数量加到s变量上
s += len(pic_url)
# 如果提取到的图片URL数量为 0,表示网页中没有图片,跳出循环
if len(pic_url) == 0:
break
else:
# 将提取到的图片 URL 添加到 List 列表中。
List.append(pic_url)
# 将时间戳 t 增加 60 秒,然后继续循环
t = t + 60
return s
# 记录相关数据
def recommend(url):
Re = []
try:
# 向网页发送一个请求并返回响应
html = requests.get(url, allow_redirects=False)
except error.HTTPError as e:
return
else:
html.encoding = 'utf-8'
# html文件解析,解析响应的文件内容,html.text 是 HTML 文档的源代码,
# 'html.parser' 是解析器,用于指定如何解析 HTML 文档
bsObj = BeautifulSoup(html.text, 'html.parser')
# 找到页面中id为topsRS的div元素
div = bsObj.find('div', id='topRS')
# 从该div元素中找到所有a的标签,并提取其中文本内容
if div is not None:
listA = div.findAll('a')
for i in listA:
if i is not None:
Re.append(i.get_text())
return Re
# 下载图片
def dowmloadPicture(html, keyword):
# 记录已经下载的图片数量
global num
# 找到图片url
# 正则表达式从 HTML 中提取所有包含图片 URL 的字符串。re.S 参数表示使正则表达式对大小写不敏感。
# (.*?):这是一个捕获组,用于匹配括号内的内容。点号(.)表示匹配任意字符,*? 表示匹配任意数量的字符,匹配一个引号、匹配一个逗号
# 查找 html 中所有以 "objURL" 开头,并且以双引号和逗号结尾的字符串,并将这些字符串作为匹配结果返回
pic_url = re.findall('"objURL":"(.*?)",', html, re.S)
print('找到:' + keyword + '的图片,开始下载....')
# 遍历图片的url
for each in pic_url:
print('正在下载第' + str(num + 1) + '张图片,图片地址:' + str(each))
# 处理异常,主要处理图片下载失败的情况
try:
if each is not None:
# 请问时间不能超过7s
pic = requests.get(each, timeout=7)
else:
continue
except BaseException:
print('错误,当前图片无法下载')
continue
else:
# 构建图片保存路径
string = file + r'\\' + str(num) + '.jpg'
# 以二进制写入模式打开新建文件
fp = open(string, 'wb')
# 将下载的图片内容写入文件
fp.write(pic.content)
# 关闭文件
fp.close()
# 已经下载一张图片加1
num += 1
# 检查是否已经下载所有需要下载的图片
if num >= numPi:
return
if __name__ == '__main__': # 主函数入口
# 模拟浏览器 请求数据 伪装成浏览器向网页提取服务,有的网站识别出你是python就会拒绝
# 请求头是在发送http请求时,由客户端向服务器发送一些元数据,描述请求的特性和客户端的能力
# 请求头通常由浏览器自动设置,也可由程序(python)脚本手动设置
# 返回的文档语言,客户端和服务端建立一个持久的连接,客户端的身份,客户端是否愿意升级不安全的请求
headers = {
'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
'Connection': 'keep-alive',
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0',
'Upgrade-Insecure-Requests': '1'
}
# 创建一个请求的会话
A = requests.Session()
# 设置头部信息
A.headers = headers
choice = int(input("请问需要搜索多类图片还是单类图片?如果是单类请输入0,如果是多类请输入1:"))
if choice == int(0):
word = input("输入要搜索的关键词:")
numPi = int(input('输入要下载的数量:'))
# 拼接路径
url = 'https://image.baidu.com/search/flip?ct=201326592&cl=2&st=-1&lm=-1&nc=1&ie=utf-8&tn=baiduimage&ipn=r&rps=1&pv=&fm=rs1&word=' + word
# 根据路径去查找
total = Find(url, A)
# 记录相关推荐图片
Recommend = recommend(url)
print('经过检测%s类图片共有%d张' % (word, total))
file = makefile(word)
t = 0
tmp = url
while t < numPi:
try:
url = tmp + str(t)
result = requests.get(url, timeout=10)
print(url)
except error.HTTPError as e:
print('网络错误,请调整网络后重试')
t = t + 60
else:
dowmloadPicture(result.text, word)
t = t + 60
else:
tm = int(input('请输入每类图片的下载数量 '))
numPi = tm
line_list = []
with open('./name.txt', encoding='utf-8') as file:
line_list = [k.strip() for k in file.readlines()] # 用 strip()移除末尾的空格
for word in line_list:
#url = 'https://image.baidu.com/search/flip?ct=201326592&cl=2&st=-1&lm=-1&nc=1&ie=utf-8&tn=baiduimage&ipn=r&rps=1&pv=&fm=rs1&word=' + word
url = 'https://image.baidu.com/search/flip?tn=baiduimage&ie=utf-8&word=' + word + '&pn='
tot = Find(url,A)
Recommend = recommend(url) # 记录相关推荐
print('经过检测%s类图片共有%d张' % (word, tot))
file = makefile(word)
t = 0
tmp = url
while t < numPi:
try:
url = tmp + str(t)
result = A.get(url, timeout=10, allow_redirects=False)
print(url)
except error.HTTPError as e:
print('网络错误,请调整网络后重试')
t = t + 60
else:
dowmloadPicture(result.text, word)
t = t + 60
numPi = numPi + tm