python爬虫、四(百度图片爬取)

python爬虫、四(百度图片爬取)

我们在观察百度图片的时候,发现他的图片仿佛无穷无尽,可以一直下拉,然后我们观察他的网页,发现刚开始刷新和下拉之后的源代码不同,增加了一些内容。通过谷歌浏览器的查找功能发现图片的链接就保存在这些新增的代码中,这就是异步加载,所需要的内容并不直接在页面源代码中,而是一次次的加载。
1、在检查之后的network -> 下拉加载更多图片,可以发现有许多的加载文件,选择XRL文件,大概每三十张图片加载一个XRL文件。
2、选择Headers可以看到一个Request URL链接,可以用浏览器打开,就是加载的XRL文件的内容,不过很乱,不方便观察(也可以点开Response,里面就是他的内容,和用浏览器打开是一样的)。也可以点开旁边的Preivew,这个界面是XRL文件,但像网页源代码一样被整理过的,比较好观察。点开之后可以观察到其中的内容,其中有很多的链接。

在这里插入图片描述
如下图,一共三十个,每个都包含了一张图片,然后我们需要找到他们的链接。

在这里插入图片描述
看了很多别人的博客,然后知道页面里面有四种图片链接,middleURL、hoverURL、thumbURL、objURL。其中objURL(注意不是ObjURL)是原图,我们也是下载这个。

然后现在就是要写代码了,就两个地方需要提一下:
1、params,观察每个XRL文件的Query String Parameters,会发现他和XRL链接是一样的,每个就几个字段不同,然后可以发现pn就是第几页*30,gsm是pn的16进制数,最后面那一串数字不知道是什么,但是貌似没有关系,所以就构造出一个获取图片链接资源的函数。

在这里插入图片描述
2、找到objURL链接。有了XRL文件可以直接用正则表达式去匹配:'objURL":"(.*?)",'。然后我们可以发现他是乱码,反而其他链接可以下载,我尝试了thumbURL,下载的也很正常,但为什么objURL是这样的呢?
objURL:"ippr_z2C$qAzdH3FAzdH3Ft_z&e3B8080nv1g_z&e3Bv54AzdH3FduigehAzdH3FYWxqwGBuAzdH3Fv4fnAzdH3F1xskeTk4vgqCF54_z&e3B3r2""
因为他是加密的(我也搞不懂为什么别的博客貌似没有这个问题,可能以前没有吧),看到了一篇博客解析百度objURL

然后下面就是所有的代码

# 这一次想要弄一个爬虫,爬取百度图库的图片并保存在指定文件夹中
'''
接口:
输入搜索的名字,图片个数
下载图片
'''
import re
import requests
import time
import os

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (K\
    HTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36'
}

# 给定网址,获取其源代码
def get_html(url, param):
    i = 1
    while i < 6:
        try:
            html = requests.get(url, headers=headers, params=param, timeout=2 + i * 3)
            return html
        except requests.exceptions.RequestException as e:
            print("获取页面" + url + " 时  第" + str(i) + "次失败   \n原因为:" + str(e))
            i += 1
    return 1


# 给定你一个图片的链接,保存路径,图片名字,将其下载到本地
def download_picture(url, path, name):
    r = get_html(url,None)
    if r == 1:
        print('下载图片' + name + '失败!')
        return 0
    img_name = path + name
    with open(img_name, 'wb') as f:
        f.write(r.content)
        f.flush()
    f.close()
    print("正在下载:" + name)
    return 1

#获取不同页面的地址信息,keyword为搜索关键字,page为
def get_page(keyword, pages):
    params = []
    for i in range(0,pages+1):
        params.append({
            'tn': 'resultjson_com',
            'ipn': 'rj',
            'ct': 201326592,
            'is': '',
            'fp': 'result',
            'queryWord': keyword,
            'cl': 2,
            'lm': -1,
            'ie': 'utf-8',
            'oe': 'utf-8',
            'adpicid': '',
            'st': -1,
            'z': '',
            'ic': 0,
            'word': keyword,
            's': '',
            'se': '',
            'tab': '',
            'width': '',
            'height': '',
            'face': 0,
            'istype': 2,
            'qc': '',
            'nc': 1,
            'fr': '',
            'pn': i*30,
            'rn': 30,
            'gsm': '1e',
            '1526377465547': ''
        })
    return params


def get_one_page_url(html):
    pattern_pic = 'objURL":"(.*?)",'
    g1 = re.findall(pattern_pic, html, re.S)
    pic_links = []
    for link in g1:
        pic_links.append(baidtu_uncomplie(link))
    return pic_links

#转码函数,百度图片的objURL链接都是加密的,通过这个函数将其转码
def  baidtu_uncomplie(url):
    res = ''
    c = ['_z2C$q', '_z&e3B', 'AzdH3F']
    d= {'w':'a', 'k':'b', 'v':'c', '1':'d', 'j':'e', 'u':'f', '2':'g', 'i':'h', 't':'i', '3':'j', 'h':'k', 's':'l', '4':'m', 'g':'n', '5':'o', 'r':'p', 'q':'q', '6':'r', 'f':'s', 'p':'t', '7':'u', 'e':'v', 'o':'w', '8':'1', 'd':'2', 'n':'3', '9':'4', 'c':'5', 'm':'6', '0':'7', 'b':'8', 'l':'9', 'a':'0', '_z2C$q':':', '_z&e3B':'.', 'AzdH3F':'/'}
    if(url==None or 'http' in url):
        return url
    else:
        j= url
        for m in c:
            j=j.replace(m,d[m])
        for char in j:
            if re.match('^[a-w\d]+$',char):
                char = d[char]
            res= res+char
        return res

def main():
    url_host = 'https://image.baidu.com/search/index'
    keyword = input('请输入百度图片搜索关键词:')
    num = int(input('请输入下载个数:'))
    path = "D:/百度图片下载/"
    if os.path.exists(path) == False:
        os.makedirs(path)
    params = get_page(keyword, int(num / 30) + 1)
    name = 1
    p1 = 0
    count = 0
    for param in params:
        html = get_html(url_host, param).content.decode('utf-8')
        pic_links = get_one_page_url(html)
        for link in pic_links:
            p1 = p1 + 1
            print(p1, link)
            count = count + download_picture(link, path, keyword + str(p1) + '.jpg')
            if count >= num:
                return

if __name__ == '__main__':
    print('图片都在 D:/百度图片下载/ 中')
    main()
    print('下载完毕!将在10秒后自动退出!')
    time.sleep(10)

参考的几篇博客,比我的详细(我太懒了)
1
2
3
4

一些反爬虫的问题

关于headers(UA、referer、cookies)
爬虫实战7-应对反爬虫的策略
关于反爬虫的一些总结
之前爬取 https://www.mzitu.com/all/ 的图片无法下载,一直403禁止访问,就是因为没有加referer
’referer’: 'https://www.mzitu.com/'

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值