简介 1.这是一个图片爬虫,运行后输入一个关键词,它就会自动爬取图片并下载到一个以关键词来命名的文件夹里 2.爬取到的图片的像素并不高,都是几十kb左右 3.爬取到的数量为一两百张,根据关键词的热度而波动 4.图片的来源主要是百度,搜狗跟必应,考虑到谷歌需要翻墙就没有爬 5.当然还有许多搜索引擎是可以爬的,不过考虑到爬虫的合法性跟大量爬取图片可能会封禁ip就没有爬 6.从程序运行到爬取完毕大概需要一两分钟,请耐心等待
让我们开始吧!
导入必要的库:
import requests #用于打开网址并获取源码,下载图片
import os #用于检测与自动创建文件
import urllib.parse #用于url编码与解码
import re #用于调用正则表达式来解析百度的html源码
定义我们的爬虫函数,即输入一个url与本地文件夹地址,实现将对应url下载到文件夹的功能:
def reptile(url,path):
try:
global iter1#iter1全局化
r=requests.get(url,timeout=1)#单次下载最多等待一秒
if str(r)=="<Response [200]>":#http状态码为200表示下载的图片有效
with open(f"{path}\\text{iter1}.jpg",'wb') as f:
f.write(r.content)#以二进制的方式来保存图片
print(f"正在下载第{iter1}张照片,网址为:", url)
iter1+=1#爬取到的图片数+1
except Exception as e:
print("爬取失败,原因",str(e))
定义一个函数,能够从一大堆文本中截取出可能包含图片的url
def url_cut(str_url):
#这个函数的主要作用是传入一串必应与搜狗中的html源码,截取其中可能有用的部分并以列表的方式返回
list_header=["http://","https://","HTTP://","HTTPS://","http%3A%2F%2F","https%3A%2F%2F","HTTP%3A%2F%2F","HTTPS%3A%2F%2F"]#可能的图片网址的开头
list_back=[".jpg",".jpeg",".png",".JPG",".JPEG",".PNG"]#可能的图片网址的结尾
str_temp=""
list_url = []#最后要返回的所有的有用的网址
for i in range(len(str_url)):
try:#下面的判断挺乱的,就不写注释了qwq,差不多就是截取字符串,然后看是否匹配头跟尾
list_headers=[str_url[i:i+7],str_url[i:i+8],str_url[i:i+13],str_url[i:i+14]]
if list_headers[0] in list_header or list_headers[1] in list_header or list_headers[2] in list_header or list_headers[3] in list_header:
iter1=i
while True:
str_temp += str_url[iter1]
iter1 += 1
list_headers_new = [str_url[iter1:iter1 + 7], str_url[iter1:iter1 + 8], str_url[iter1:iter1 + 13], str_url[iter1:iter1 + 14]]
if list_headers_new[0] in list_header or list_headers_new[1] in list_header or list_headers_new[2] in list_header or list_headers_new[3] in list_header:
str_temp=""
break
if str_url[iter1:iter1+4] in list_back:
str_temp += str_url[iter1:iter1 + 4]
break
elif str_url[iter1:iter1+5] in list_back:
str_temp += str_url[iter1:iter1 + 5]
break
if str_temp!="" and str_temp not in list_url:
if "%3A%2F%2F" in str_temp and ";" not in str_temp and "\"" not in str_temp:
#通过多次观察分析得出我们爬到的网址里面带有;与“的都是模糊或重复的图片因此我们筛选掉,下面的elif也一样
list_url.append(urllib.parse.unquote(str_temp))
elif ";" not in str_temp and "\"" not in str_temp:
list_url.append(str_temp)
str_temp=""
except IndexError:#超范围后跳出
break
return list_url#返回必应中有效的网址
开始编写我们的主程序流程:
#程序从这里开始运行↓↓↓
search=input("请输入关键词:")
path=f"C:\\Users\\陈瑞达\\Desktop\\{search}"#爬取到的图片保存在这里(我们默认为自己的卓面)
if not os.path.exists(path): # 如果没有叫做关键字的文件就创建一个
os.mkdir(path)
os.startfile(path)#运行程序时要打开这个文件夹吗?不需要的话就注释掉这行代码吧!
header={#百度搜索需要的请求头
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.79',
'Accept':'image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8',
'Accept-Encoding':'gzip, deflate, br',
'Accept-Language':'"zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
'Cookie':'BIDUPSID=94AEA4DEC3EF71B28FD08AE5BDB3AB75; PSTM=1673000303; BAIDU_WISE_UID=wapp_1684500397023_656; ZFY=lFiRU0fHCfhud:BJlouUD1MJwa336xtJs9Xj0ZFzwN5Y:C; BAIDUID=46D2DB680FF44A69136E99D71C43C5D9:FG=1; BAIDUID_BFESS=46D2DB680FF44A69136E99D71C43C5D9:FG=1; __bid_n=1889a235efbab1c2a14207; FPTOKEN=9cLjaziMBDvxKzWCDR2991GTcZXw0BeuD1NE/ao44KC/A7Jlf0VuLuThbXzuy+Wbz4t5qQIxszUjPLNwGcT1x4O0aXDZe7pFATjvNIjemgIMH/t2Gu0PW9np0WmJSH1KpZcQl199I4AzN+N2qJpzmfbZcm/a0IH086VMXgehrvv+y5avtIp+loFb8vvndA1kpfb67/8u6jhkQ1FEg7rUydqc2iCS8RT55xsx5zoeO6ZFoojhbWvfC4Mq0FDxhQpDYgEuowLQjjNpuUAJ1Ga+lrAytK4ASnhn9B23P72rgtx3U4jyYWP3E/G5jVx0ygUoD+6yCsVo2iIp1jtpoEeGd8W2S/HBu5Xko4O3hG1Gph+TQzFIfM57J+0+TcFPmWLXmJFikuvKOK48pFnEVUTlVY/I9a7F6gzeBCyhkRkAogd9TRMWoqpAXHwd3UqSdUJp|Rf+S6jts9ZTrgWBfh8/y81KJFacXr5X2qclxvZC1tTQ=|10|059448e35b8083400428fec8f3650b82; BDUSS=JzWXFaZWxjZ3BnbGs3RVNONWtDYkJKS3FZQ1EtcVJUci04cVNXVkVrU1Z2OHhrRVFBQUFBJCQAAAAAAQAAAAEAAADUbSpOt7Kzvm14dDcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJUypWSVMqVkSH; BDUSS_BFESS=JzWXFaZWxjZ3BnbGs3RVNONWtDYkJKS3FZQ1EtcVJUci04cVNXVkVrU1Z2OHhrRVFBQUFBJCQAAAAAAQAAAAEAAADUbSpOt7Kzvm14dDcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJUypWSVMqVkSH; ariaDefaultTheme=undefined; BA_HECTOR=01840g8k00al80ah25002ka51ib2gkb1p; BDRCVFR[feWj1Vr5u3D]=I67x6TjHwwYf0; PSINO=7; delPer=0; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; BDRCVFR[dG2JNJb_ajR]=mk3SLVN4HKm; BDRCVFR[-pGxjrCMryR]=mk3SLVN4HKm; H_PS_PSSID=36552_38642_39024_38943_38958_38956_39009_39039_38972_38811_38986_39088_38636_26350_39041_39092_39053_39101; RT="z=1&dm=baidu.com&si=1878aad8-d340-4951-bfc1-9be710527471&ss=lk2lwbu7&sl=2&tt=2xt&bcn=https%3A%2F%2Ffclog.baidu.com%2Flog%2Fweirwood%3Ftype%3Dperf&ld=1ezn&nu=1ggl9aas1&cl=1esf&ul=1yxq&hd=1yyo"; userFrom=www.baidu.com; ab_sr=1.0.1_Yzg0ZWUzODI5NWQ1MTJkYmIxMjE4NmYwNDZjZTJhNzcwNGQ3MDRmYjFjM2E0NmM4MmIzOTQ2ODUyY2JkOTNlMjhiMzk3NmNjOGEwYzZlNmUwMjhiZTc3ZTFjOTg4ZjFmZmUyMDVkNzZlMWRmNzZkOWJmMGQxNjQxZjUzOWEwNjU3MDAwNjY2YTYyYTZkOTMxNGY4MWVhNjYwNjE3OTJlMg=='
}
url_bing =f"https://cn.bing.com/images/search?q={urllib.parse.quote(search)}" #在必应中需要搜寻的东西
url_baidu=f"https://image.baidu.com/search/index?tn=baiduimage&word={urllib.parse.quote(search)}" #在百度中需要搜寻的东西
url_sougo=f"https://pic.sogou.com/pics?query={urllib.parse.quote(search)}" #在搜狗中需要搜寻的东西
str_url1=str(requests.get(url_baidu,headers=header).content) #获取百度源码,需要传入请求头来伪装成浏览器,否则会被拦截
str_url2=str(requests.get(url_bing).content) #获取必应的源码
str_url3=str(requests.get(url_sougo).content) #获取搜狗的源码
img_url_baidu=re.findall('"thumbURL":"(.*?)"',str_url1)#使用正则表达式获取百度中的有用的图片网址
for i in range(len(img_url_baidu)):
# 这个for主要是筛选掉重复的图片,他们的url只有http与https处不同
try:
if img_url_baidu[i][img_url_baidu[i].index("u="):img_url_baidu[i].index("&fm=")]==img_url_baidu[i+1][img_url_baidu[i+1].index("u="):img_url_baidu[i+1].index("&fm=")]:
del img_url_baidu[i]
except:
continue
img_url_bing=url_cut(str_url2) #获取并同时过滤必应中由有用的图片网址
img_url_sougo=url_cut(str_url3) #获取并同时过滤搜狗中由有用的图片网址
list_url=img_url_baidu+img_url_bing+img_url_sougo#将得到的所有的有效网址加起来
print(f"共找到{len(list_url)}个可能的网址")
iter1 = 1#iter用来计数,一共爬取了多少张图片
for i in range(len(list_url)):
reptile(list_url[i],path)#开始调用函数并从可能的有效网址中爬取图片
print(f"共得到{iter1-1}个有效的图片,地址为:{path}")
运行即可。有任何问题可向作者提出。