现在网上精美的壁纸数不胜数,能让人挑花了眼,左瞧瞧,右看看,都想要怎么办?呜呜呜....到嘴的肥肉咱不能让他飞了呀,今天就教大家写个python爬虫来爬取100张百度图片。

打开百度图片,随意搜索,能看到图片是随着网页向下的滑动而加载出来的,这是动态加载页面。这就麻烦了,如果查看页面的源代码,是不会发现图片的url的,这可怎么办呢?不怕,首先要弄明白动态加载的原理,动态加载就是通过运行javascript将图片数据插入到网页的HTML标签里面,所以我们在源代码里看不到图片信息。但是网页中能加载出来图片说明网页请求有数据包,只要找到存放有数据信息的文件就能找到图片的url。

最简单的查看数据包的工具就是浏览器的F12功能键。光标放在网页中,按F12。

现在举个例子,搜索橘猫的百度图片,然后按F12,如果往下滑动就会发现加载出多张图片和多出acjson?tn=resultjson&ipn=…请求的文件,先点击Network然后再点击Preview,就会看到一条json数据,点开就会发现30多条数据,再次点开就会发现,每条数据都包含了一张图片的详细信息。

8WY{~V8ZBF6BX6FP$L5W%98.png

ok,终于找到了图片的url,接下来就让我们摩拳擦掌,大干一场吧。

这时候细心的你一定会发现每个文件内只有30条数据,那怎么才能得到100条数据呢?那我们就来找不同,如上图有四个acjson?tn=resultjson&ipn=…文件,如果仔细想一想,每请求一次得到30条数据,而且每次请求的数据是不同的,所以肯定请求的url也是不同的,将这4个文件的url放在一起如下,

http://image.baidu.com/search/acjson?tn=resultjson_com&ipn=rj&ct=201326592&is=&fp=result&queryWord=%E6%A9%98%E7%8C%AB&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=&z=&ic=&word=%E6%A9%98%E7%8C%AB&s=&se=&tab=&width=&height=&face=&istype=&qc=&nc=1&fr=&pn=30&rn=30&gsm=1e&1521792798667=
http://image.baidu.com/search/acjson?tn=resultjson_com&ipn=rj&ct=201326592&is=&fp=result&queryWord=%E6%A9%98%E7%8C%AB&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=&z=&ic=&word=%E6%A9%98%E7%8C%AB&s=&se=&tab=&width=&height=&face=&istype=&qc=&nc=1&fr=&pn=60&rn=30&gsm=3c&1521792798749=
http://image.baidu.com/search/acjson?tn=resultjson_com&ipn=rj&ct=201326592&is=&fp=result&queryWord=%E6%A9%98%E7%8C%AB&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=&z=&ic=&word=%E6%A9%98%E7%8C%AB&s=&se=&tab=&width=&height=&face=&istype=&qc=&nc=1&fr=&pn=90&rn=30&gsm=5a&1521792801242=
http://image.baidu.com/search/acjson?tn=resultjson_com&ipn=rj&ct=201326592&is=&fp=result&queryWord=%E6%A9%98%E7%8C%AB&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=&z=&ic=&word=%E6%A9%98%E7%8C%AB&s=&se=&tab=&width=&height=&face=&istype=&qc=&nc=1&fr=&pn=120&rn=30&gsm=78&1521792801416=

就会发现:除了pn和gsm的前两个字母不同外其他的都相同。嗯 ,我好像发现什么秘密,pn是以30为步幅递增的,而gsm的前两个字母是pn的16进制数的两位,发现规律后这就简单多了。一起来写代码吧。

导入库

import urllib.request
import urllib.parse
import re
import os
保存图片的路径
#获得保存下载图片文件夹的路径
def Imgpath(word):
file_path = os.getcwd()[:-4] + word #获得当前的文件路径后创建带有关键词的路径
if not os.path.exists(file_path): #判断新建路径是否已经存在
os.makedirs(file_path) #不存在,创建文件夹
else:
file_path = file_path + '1' #存在,给文件夹重新命名
os.makedirs(file_path ) #创建文件夹
return file_path
获得图片的url
def Imgurl(word):
rep_list = []
#模拟浏览器,需要用到浏览器的信息和目标url
header = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36',
"referer": "https://image.baidu.com"
}
#将中文关键字加密成浏览器能识别的乱码
content= urllib.parse.quote(word,encoding='utf-8')
#依据pn的规律从30到121循环4次,间隔为30
for num in range(30,121,30):
gsm = hex(num)[2:] #将十进制数num转换成16进制数并取后两位
url = 'https://image.baidu.com/search/acjson?tn=resultjson_com&ipn=rj&ct=201326592&is=&fp=result&queryWord='+content+'&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=&z=&ic=&word='+content+'&s=&se=&tab=&width=&height=&face=&istype=&qc=&nc=&fr=&pn='+str(num)+'&rn=30&gsm='+ gsm +'&1521707235798=' #根据规律每次循环生成正确的请求地址
req = urllib.request.Request(url=url,headers=header) #获得请求对象
page = urllib.request.urlopen(req).read() #请求并读取返回信息
try: #如果返回信息遇到不在utf-8范围内的字符,跳过
response = page.decode('utf-8') #解码返回的信息
 imgpattern = re.compile(r'"thumbURL":"(.*?)\.jpg') #编写正则
 rsp_data = re.findall(imgpattern, response) #通过正则匹配
rep_list += rsp_data
except UnicodeDecodeError:
pass
return rep_list
下载图片
def download_img(word):
# 下载图片
x = 1 # 计数
 img_urllist = Imgurl(word)
 img_path = Imgpath(word)
 for url in img_urllist[:100]: #循环提取Imgurl列表中的前100个字符串
pngurl = url.replace(r'"thumbURL":"', " ") #获得字符串里面的url
 path = img_path + '\\' + word + str(x) + '.png' #下载图片的路径
pngdata = urllib.request.urlopen(pngurl).read() #下载图片数据
f = open(path, 'wb') #必须用二进制写入
f.write(pngdata) #下载图片
f.close()
x += 1
运行代码
if __name__ == '__main__':
word = inout("请输入中文关键词:")
download_image(word)
添加一个简单的操作窗口
import tkinter
win = tkinter.Tk()
win.title("百度图片爬虫")
win.geometry("400x200+400+200"
entry = tkinter.Entry(win,width=28) #e就代表输入框这个对象
entry.insert(10,"请输入关键词")
def func1(event):
entry.delete(0, 20)
#bind 给控件绑定事件
entry.bind("",func1)
#按钮BUTTON
#command 关联函数 注意 = 后加函数名,但是并不用加()
def func2():
word = entry.get()
 download_img(word)
button = tkinter.Button(win,text="确定",command = func2,
width=6,height=1)
#显示出来
entry.place(x=100,y=50)
button.place(x=170,y=100)
win.mainloop()
UAB$BS`~8$5XPZEZ%9N4838.png
结果
![VTJ0{)]R}3WY4XFQ@70WK.png](https://upload-images.jianshu.io/upload_images/14750449-9a2b27c4cefab440.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

还等什么,快来试试吧!