python简易图片爬虫(基于requests而非selenium)

简介
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}")

 运行即可。有任何问题可向作者提出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值