【python_9】爬取斗图吧无限制下载表情图

爬取链接:http://www.doutula.com/photo/list/?page=1

首先F12查看该链接,对比可以看到,没有任何加密,可以解析图片链接,然后下载;

不过要仔细看,有个小坑:图片有两张, 未加载成功显示是白色的图片,加载成功后显示才是正确的;

 

未加载成功前的网页:

 

加载成功后:

 

查看标签页:每个a标签对应一张图片

 

右键查看源代码,搜索图片名字:

可以发现第一个src链接打开的是一个空白图片,也就是未加载成功的网页图片,显然不是我们想要的,第二个data-original打开显示才是我们想要的,接下来我们可以开始解析,拿到图片链接和图表名字:

 

xpath解析: 直接把获取到a标签,然后依次遍历:使用yield方法传递:

def parse_page(html):
    data = etree.HTML(html)
    div_list = data.xpath('//*[@id="pic-detail"]/div/div[2]/div[2]/ul/li/div/div/a')
    for i in div_list:
        yield{
            "pic": i.xpath("./img/@data-original")[0],
            "name": i.xpath("./img/@alt")[0]
        }

 

解析完成功,传递给其他函数,执行下载任务:
 

def save_pic(pic):
    title = "表情包合集"              # 设置文件名字
    url = pic.get("pic")            # 拿到url
    filename = pic.get("name")      # 设置图片名字
    imgname = re.sub(r"\\|\*", "", filename)       # 过滤特殊字符,防止命名错误
    if not os.path.exists(title):
        os.mkdir(title)
    r = requests.get(url, headers=kv)
    try:
        if r.status_code == 200:
            if url[-3:] == "gif":
                file_path = "{0}\{1}.{2}".format(title, imgname, "gif")
                if not os.path.exists(file_path):
                    with open(file_path, "wb") as f:
                        try:
                            f.write(r.content)
                            print("该图片已下载完成")
                        except:
                            print("名字格式错误,无法报错")
                else:
                    print("该图片%s已下载" % imgname)
            else:
                file_path = "{0}\{1}.{2}".format(title, imgname, "jpg")
                if not os.path.exists(file_path):
                    with open(file_path, "wb") as f:
                        try:
                            f.write(r.content)
                            print("该图片已下载完成")
                        except:
                            print("名字格式错误,无法报错")
                else:
                    print("该图片%s已下载" % imgname)
    except RequestException as e:
        print(e, "图片获取失败")
        return None

考虑到动态图片的后缀名不一样,因为在拿到url链接,先判断链接的后三个字符串(gif、jpg),两个不同类型的存储,

完成以后,设置翻页,可以无限下载,不用担心发爬措施;

 

完整代码如下:

import requests
from requests.exceptions import RequestException
from lxml import etree
import os
from multiprocessing import Pool
import time
import re

start_time = time.time()
kv = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.80 Safari/537.36"
}


# 下载图片
def save_pic(pic):
    title = "表情包合集"              # 设置文件名字
    url = pic.get("pic")            # 拿到url
    filename = pic.get("name")      # 设置图片名字
    imgname = re.sub(r"\\|\*", "", filename)       # 过滤特殊字符,防止命名错误
    if not os.path.exists(title):
        os.mkdir(title)
    r = requests.get(url, headers=kv)
    try:
        if r.status_code == 200:
            if url[-3:] == "gif":
                file_path = "{0}\{1}.{2}".format(title, imgname, "gif")
                if not os.path.exists(file_path):
                    with open(file_path, "wb") as f:
                        try:
                            f.write(r.content)
                            print("该图片已下载完成")
                        except:
                            print("名字格式错误,无法报错")
                else:
                    print("该图片%s已下载" % imgname)
            else:
                file_path = "{0}\{1}.{2}".format(title, imgname, "jpg")
                if not os.path.exists(file_path):
                    with open(file_path, "wb") as f:
                        try:
                            f.write(r.content)
                            print("该图片已下载完成")
                        except:
                            print("名字格式错误,无法报错")
                else:
                    print("该图片%s已下载" % imgname)
    except RequestException as e:
        print(e, "图片获取失败")
        return None


# 解析请求页面
def parse_page(html):
    data = etree.HTML(html)
    div_list = data.xpath('//*[@id="pic-detail"]/div/div[2]/div[2]/ul/li/div/div/a')
    for i in div_list:
        yield{
            "pic": i.xpath("./img/@data-original")[0],
            "name": i.xpath("./img/@alt")[0]
        }


# 获取请求
def get_one_page(i):
    url = "http://www.doutula.com/photo/list/?page=" + str(i)
    r = requests.get(url, headers=kv)
    try:
        if r.status_code == 200:
            return r.text
    except RequestException as e:
        print("请求失败:", e)
        return None


def main(page):
    for i in range(1, page):
        html = get_one_page(i)
        data = parse_page(html)
        for pic in data:
            save_pic(pic)


if __name__ == '__main__':
    p = Pool(3)
    p.map(main, (500, ))
    end_time = time.time() - start_time
    print("程序运行了%.2f秒" % end_time)

-----------------------------------------------------------------------分割线---------------------------------------------------------------------------------------

 

这里不建议使用 request.urlretrieve()方法来进行下载,这样很容易遭到反爬,上次使用该方法爬取了250张就爬取不了

 

我这里用原始的老办法,加了请求头,基本不会有问题,我爬取了500页,毫无问题;基本可以一直爬一直爬;

还有在这里 yield方法非常好用,直接传递过去,当然也可以使用列表的方法,全部存储在列表里,然后依次读取去下载,

不过推荐yield,比较方便。

------------------------------------------------------------------------小诀窍-----------------------------------------------------------------------

最后推荐一个小方法,将代码设置启动功能,直接运行保存到文件中:

新建一个文本文档,将后缀改为bat,然后编辑,输入:python biaoqingbao.py

然后点击run.bat,就开始下载了

就可以看到文件里多了一个文件夹,里面全是表情包:

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值