美文网首页
40行python代码教你爬取100张百度图片

40行python代码教你爬取100张百度图片

作者: 隐墨留白 | 来源:发表于2018-10-31 15:08 被阅读0次

    现在网上精美的壁纸数不胜数,能让人挑花了眼,左瞧瞧,右看看,都想要怎么办?呜呜呜....到嘴的肥肉咱不能让他飞了呀,今天就教大家写个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("<Button-1>",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://img.haomeiwen.com/i14750449/9a2b27c4cefab440.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    还等什么,快来试试吧!

    相关文章

      网友评论

          本文标题:40行python代码教你爬取100张百度图片

          本文链接:https://www.haomeiwen.com/subject/uwtatqtx.html