美文网首页python3学习笔记
初级python爬虫实战一——爬取下厨房首页高清图

初级python爬虫实战一——爬取下厨房首页高清图

作者: 一个王二不小 | 来源:发表于2020-03-14 15:38 被阅读0次

    1. 预备工作

    在花了两天半时间研究学习了urllib,requests,bs4,lxml等库之后,准备开始一个简单的实战——爬取“下厨房”网站首页所有的高清大图。


    下厨房首页

    首先F12观察一下这些图片的真实地址:


    F12观察任意图片地址

    观察到img =之后有一个链接地址,直接访问该地址:

    直接访问观察地址
    显然这是一个小图,不是我要的高清图。再观察复制下来的链接
    链接分析
    不难发现,以@为界,链接可以分为前后两个部分。猜想前一部分是图片地址,后一部分则是对图片进行压缩的参数。试着删除@及其之后的部分,再访问。果然出现了一张高清大图。
    高清大图真实地址
    这下子基础部分基本弄清楚了,预备动作就到这里。

    2. 开爬!

    终于可以开始写我的第一只爬虫了,激动~

    2.1 获取页面,解析结构

    首先,通过requests发起请求

    import requests
    from lxml import etree
    
    # 模拟浏览器访问
    ua = 'Mozilla/5.0 ' \
         '(Windows NT 10.0; Win64; x64) ' \
         'AppleWebKit/537.36 (KHTML, like Gecko) ' \
         'Chrome/80.0.3987.116 Safari/537.36'
    header = {'User-Agent': ua}
    r = requests.get("http://www.xiachufang.com/", headers=header)
    # r = requests.get("http://httpbin.org/", headers=header)
    
    print(r.text)
    et = etree.HTML(r.text)
    data = et.xpath('//img/@src')
    for i in range(len(data)):
        print(data[i])
    print(len(data))
    

    控制窗口的输出信息为:


    控制台输出信息

    可见一共输出了75个数据,但是其中包含很大一部分:

    data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAMAAAAoyzS7AAAAA1BMVEXo6Og4/a9sAAAADUlEQVR42gECAP3/AAAAAgABUyucMAAAAABJRU5ErkJggg
    

    这样的数据。显然这不是我想要的。打印r.text观察一下这些数据在页面中的位置。发现有

    <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAMAAAAoyzS7AAAAA1BMVEXo6Og4/a9sAAAADUlEQVR42gECAP3/AAAAAgABUyucMAAAAABJRU5ErkJggg" 
    data-src="http://i1.chuimg.com/b7933e0a29d54c53aab854f3ea65c9f3_750w_750h.jpg@2o_50sh_1pr_1l_60w_60h_1c_1e_90q_1wh" 
    alt="夏夏2013" 
    width="60" 
    height="60">
    

    原来这些用户分享的图片,真实地址在“data-src”属性中,而非“src”属性。
    查找所有的data-src

    data = et.xpath('//img/@data-src')
    for i in range(len(data)):
        # print(data[i])
        pass
    print(len(data))
    

    输出结果为25,也就是原本链接地址为src的被筛选掉了,那么怎么才能保存所有的图呢?
    想到了一个比较low,但是可行的方案:

    1. 找到img标签中不包含data-src属性但包含src属性中的src值
    2. 找到img标签中包含data-src属性的data-src
    3. 合并前两步中得到的列表
      在代码中体现为:
    et = etree.HTML(r.text)
    # 1. 找到img标签中不包含data-src属性但包含src属性中的src值
    data1 = et.xpath("//img[not(@data-src) and @src]/@src")
    # 2. 找到img标签中包含data-src属性的data-src
    data2 = et.xpath("//img/@data-src")
    # 3. 合并前两步中得到的列表
    img_list= data1 + data2
    for i in range(len(img_list)):
        print(img_list[i])
        # pass
    

    观察输出结果:


    不完美的结果

    结果列表中存在空项。解决办法当然是去除空项:

    # 删除空元素
    while '' in img_list:
        img_list.remove('')
    

    再观察输出结果:


    完美的结果

    完美输出了69个图片链接。这一部分完成!

    2.2 处理img_list列表

    由预备结果中的分析可知,下一步要做的是对列表中每一项进行分割,只保留高清大图部分,删除后面的参数。也即,保留链接中@符号之前的部分。使用urllib中的parse对链接进行分析。
    导入urlparse

    from urllib.parse import urlparse
    for img in img_list:
        o = urlparse(img)
    

    关于urlparse的用法,这里用一个例子说明:

     o = urlparse.urlparse("http://www.google.com/search?hl=en&q=urlparse&btnG=Google+Search")
    

    参数
    o.scheme 'http'
    o.netloc 'www.google.com'
    o.path '/search'
    o.params ''
    o.query 'hl=en&q=urlparse&btnG=Google+Search'
    o.fragment ''

    故可以对列表进行下面的处理:

    for img in img_list:
        o = urlparse(img)
        filename = o.path[1:].split('@')[0]
        url = "%s://%s/%s" % (o.scheme, o.netloc, filename)
        print(url)
    
    处理后的url

    完美!

    2.3 文件操作

    有了真实的url,下面要做的就是下载图片并保存到本地了。使用文件操作,首先必须导入python内置的os模块。

    import os
    

    初始化文件夹,如果不存在就创建一个:

    # 文件操作,初始化xiachufang_image文件夹
    image_dir = os.path.join(os.curdir, 'xiachufang_image')
    if not os.path.isdir(image_dir):
        os.mkdir(image_dir)
    

    2.4 最后一步

    遍历访问处理后的url,并且以filename保存。(二进制写入)

    for img in img_list:
        o = urlparse(img)
        filename = o.path[1:].split('@')[0]
        filepath = os.path.join(image_dir, filename)
        url = "%s://%s/%s" % (o.scheme, o.netloc, filename)
        print(url)
        resp = requests.get(url)
        with open(filepath, 'wb') as f:
            # 二进制以块写入
            for chunk in resp.iter_content(1024):
                f.write(chunk)
    
    

    基本没有问题,但是少下载了几个图。再优化一下:

    for img in img_list:
        o = urlparse(img)
        filename = o.path[1:].split('@')[0]
        filepath = os.path.join(image_dir, filename)
        if not os.path.isdir(os.path.dirname(filepath)):
            os.mkdir(os.path.dirname(filepath))
        url = "%s://%s/%s" % (o.scheme, o.netloc, filename)
        print(url)
        resp = requests.get(url)
        with open(filepath, 'wb') as f:
            # 二进制以块写入
            for chunk in resp.iter_content(1024):
                f.write(chunk)
    

    看看文件夹,已经全部保存,欣赏一下美食吧~


    总览
    大图1
    大图2
    大图3 大图4
    大图5

    成就感和食欲均满满

    3. 完整代码

    贴出完整代码

    import os
    from urllib.parse import urlparse
    import requests
    from lxml import etree
    
    # 模拟浏览器访问
    ua = 'Mozilla/5.0 ' \
         '(Windows NT 10.0; Win64; x64) ' \
         'AppleWebKit/537.36 (KHTML, like Gecko) ' \
         'Chrome/80.0.3987.116 Safari/537.36'
    header = {'User-Agent': ua}
    r = requests.get("http://www.xiachufang.com/", headers=header)
    
    # 开始解析
    et = etree.HTML(r.text)
    # 1. 找到img标签中不包含data-src属性但包含src属性中的src值
    data1 = et.xpath("//img[not(@data-src) and @src]/@src")
    # 2. 找到img标签中包含data-src属性的data-src
    data2 = et.xpath("//img/@data-src")
    # 3. 合并前两步中得到的列表
    img_list = data1 + data2
    # 删除空元素
    while '' in img_list:
        img_list.remove('')
    
    # 文件操作,初始化xiachufang_image文件夹
    image_dir = os.path.join(os.curdir, 'xiachufang_image')
    # if not os.path.isdir(image_dir):
    #     os.mkdir(image_dir)
    
    for img in img_list:
        o = urlparse(img)
        filename = o.path[1:].split('@')[0]
        filepath = os.path.join(image_dir, filename)
        if not os.path.isdir(os.path.dirname(filepath)):
            os.mkdir(os.path.dirname(filepath))
        url = "%s://%s/%s" % (o.scheme, o.netloc, filename)
        print(url)
        resp = requests.get(url)
        with open(filepath, 'wb') as f:
            # 二进制以块写入
            for chunk in resp.iter_content(1024):
                f.write(chunk)
    

    相关文章

      网友评论

        本文标题:初级python爬虫实战一——爬取下厨房首页高清图

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