Python培训
400-996-5531
Python爬虫技术如今非常流行,网络上也充斥着各种教程。而今天,杰哥来教大家写个python爬虫来爬取百度图片。
首先,打开百度图片,随意搜索,能看到图片是随着网页向下的滑动而加载出来的,这是动态加载页面。这就麻烦了,如果查看页面的源代码,是不会发现图片的url的,这可怎么办呢?
不怕,首先要弄明白动态加载的原理,动态加载就是通过运行javascript将图片数据插入到网页的HTML标签里面,所以我们在源代码里看不到图片信息。但是网页中能加载出来图片说明网页请求有数据包,只要找到存放有数据信息的文件就能找到图片的url。
最简单的查看数据包的工具就是浏览器的F12功能键。光标放在网页中,按F12。
现在举个例子,搜索橘猫的百度图片,然后按F12,如果往下滑动就会发现加载出多张图片和多出acjson?tn=resultjson&ipn=…请求的文件,先点击Network然后再点击Preview,就会看到一条json数据,点开就会发现30多条数据,再次点开就会发现,每条数据都包含了一张图片的详细信息。
ok,终于找到了图片的url,接下来就让我们摩拳擦掌,大干一场吧。
这时候细心的你一定会发现每个文件内只有30条数据,那怎么才能得到100条数据呢?那我们就来找不同,如上图有四个acjson?tn=resultjson&ipn=…文件,如果仔细想一想,每请求一次得到30条数据,而且每次请求的数据是不同的所以肯定是请求的url是不同的,将这4个文件的utl放在一起如下,
#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)
输入”橘猫“ ,回车。
运行结束,让我们来看看结果吧!
看,成功了~小伙伴们还等什么,你也赶快快来试试吧!
填写下面表单即可预约申请免费试听! 怕学不会?助教全程陪读,随时解惑!担心就业?一地学习,可全国推荐就业!
Copyright © 京ICP备08000853号-56 京公网安备 11010802029508号 达内时代科技集团有限公司 版权所有
Tedu.cn All Rights Reserved