Python零基础之爬取瀑布页百度图片(正则表达式,爬虫,反爬,延时,异常处理)

本文介绍了如何使用Python进行网络爬虫,针对百度图片进行爬取。内容包括利用正则表达式抓取图片URL,处理中文关键字,将瀑布流页面转化为翻页模式,处理图片名称及异常,以及加入延时策略防止请求过快。

通过正则表达式爬取瀑布页百度图片

思路:

  1. 根据输入的关键字,获取想要爬取的百度图片页的url地址
  2. 为了方便抓取,把瀑布页的展示模式改为翻页式
  3. 寻找翻页url的规律,获取需要抓取的url地址
  4. 分析url和html源码,通过正则表达式获取原始图片的url地址
  5. 通过正则表达式处理将来需要保存的图片名称
  6. 获取图片数据,并保存为指定名称
# !/usr/bin/python
# Filename: 通过正则表达式爬取瀑布页百度图片.py
# Data    : 2020/07/23
# Author  : --king--
# ctrl+alt+L自动加空格格式化


import requests
import re
import urllib.parse
import time

# 1. 获取想要爬取的百度图片url
base_url = 'https://image.baidu.com/search/index?tn=baiduimage&word='
keyword = input('请输入您想要爬取的图片类型名称:')
# 通过parse.quote处理汉字成url地址
url = base_url + urllib.parse.quote(keyword)
# print(url)
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3756.400 QQBrowser/10.5.4043.400',
    'Connection': 'close'}

# 2. 把瀑布页的显示模式改为翻页式的
# 把url中的index换位flip
url = url.replace('index', 'flip')
# print(url)

# 3. 对比翻页的url区别,生成url列表
# 第1页:https://image.baidu.com/search/flip?tn=baiduimage&ie=utf-8&word=%E6%B1%BD%E8%BD%A6&pn=0&gsm=64&ct=&ic=0&lm=-1&width=0&height=0
# 第2页:https://image.baidu.com/search/flip?tn=baiduimage&ie=utf-8&word=%E6%B1%BD%E8%BD%A6&pn=20&gsm=3c&ct=&ic=0&lm=-1&width=0&height=0
# 一页显示的图片为20张,所以,是pn=控制的页数,第n页的pn值为为(n-1)*20
page = int(input('请输入需要爬取的页数:'))
page_list = []
for i in range(page):
    pn = i * 20
    page_url = url + '&pn=' + str(pn)
    page_list.append(page_url)
# print(page_list)

# 4. 分析每页的url,用正则表达式过滤出需要下载的图片地址
# 分析第一张图片的url
for page_url in page_list:

    # img_url = 'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1950373094,1563522557&fm=26&gp=0.jpg'
    # 查看网页源代码,发现该地址出现多次
    # {"thumbURL":"https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1950373094,1563522557&fm=26&gp=0.jpg","middleURL":"https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1950373094,1563522557&fm=26&gp=0.jpg","largeTnImageUrl":"","hasLarge" :0,"hoverURL":"https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1950373094,1563522557&fm=26&gp=0.jpg","pageNum":19,"objURL":"http://5b0988e595225.cdn.sohucs.com/images/20180111/3af197dd52dd4d3fae2943ff039a7416.jpeg"}
    # 发现objURL与众不同,打开链接发现就是该原始图片
    # thumbURL,middleURL,largeTnImageUrl,hasLarge,hoverURL是该图片的不同尺寸和功能对应的图片地址
    # 缩略图,中等大小,大图,超大图,悬停图
    # 所以我们只需要抓取objURL对应的图片即可
    # 请求html页面内容
    image_html = requests.get(page_url, headers=headers).text
    # 对html源码进行正则匹配
    image_urls = re.findall(r'"objURL":"(.*?)"', image_html)
    # 如果没有数据,首先检查是否拿到了正确的html,其次检查正则
    for image_url in image_urls:
        # print(image_url)
        # 5. 处理需要保存的文件名对图片进行下载保存
        # 注意'.'这种特殊符号,需要用'\'进行转义
        image_name = re.search(r'http://.*?(.{8})\.[jpg,jpeg,png,gif,bmp]', image_url, re.I)
        # 处理图片地址不带后缀名的情况
        if image_name == None:
            # 处理文件名中多余的'/'',替换为'_'
            image_name = image_url[-8:].replace('/', '_').replace('.', '_') + '.jpg'
            print(image_name)
        else:
            # 处理文件名中多余的'/',替换为'_'
            image_name = image_name.group(1).replace('/', '_').replace('.', '_') + '.jpg'
            print(image_name)

        with open('img/' + image_name, 'wb') as f:
        	# 防止连接错误导致程序中断,进行异常处理
            try:
                req = requests.get(image_url, headers=headers).content
                f.write(req)
                time.sleep(0.5)
            except Exception as e:
                print(e)
                time.sleep(3)
    print('第', page_list.index(page_url) + 1, '页下载完毕')

需要注意的地方:

  1. url请求中的中文关键字需要进行urllib.parse.quote()进行解析处理
  2. 瀑布页到翻页式的转换,index → flip只在百度适用
  3. 百度图片存在多种格式,原始页面地址要在html源码中查找获得
  4. 正则表达式的匹配要注意对匹配partten前加r,要对特殊字符前加‘'进行处理
  5. 图片名称中可能存在特殊字符,如‘\’,会影响文件保存,要替换为其他字符
  6. 为了避免请求速度过快,添加延时
  7. 为了避免连接问题导致程序中断,加入异常处理
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kingx3

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值