用python爬取图片(四)

首先,值得庆幸的是,代码能完美运行了。但是我这个人不喜欢太开心的事情,有点强迫症(追求完美)。所以我没那么太开心,加上这个项目搞得我很烦,因为这个项目算是我零基础学习python加上我四年没碰过代码的生疏感,前前后后花了将近2个月的时间,累计实际学习时间不会超过10天,这中间肯定学学玩玩,到后面直接不想学了。

那么先说下这个项目,对于我来说是人生当中自己写的第一个项目。我来评价他的话就是,好比写作业,3小时能写完,但是别人只花10分钟写完了,效率不高。

废话不多说了,下面是代码

# time:2019.9.13
# author:小白之神111
# project:爬网页图片
import os
import time
import requests
import re

import random
from lxml import etree

# allow_redirects=False表示禁止重定向,这个东西在下面的代码中
# 如果有requests.get()的地方都加上了,如果要修改,就在这里面修改
# 然后重定向状态码:
# 301 redirect: 301 代表永久性转移(Permanently Moved)
# 302 redirect: 302 代表暂时性转移(Temporarily Moved)


shouye = "https://www.mm131.net"
dic = {"0": "/xinggan/", "1": "/qingchun/", "2": "/xiaohua/", "3": "/chemo/", "4": "/qipao/",
       "5": "/mingxing/"}  # 菜单栏 有6个

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36",
    "Referer": "https://www.mm131.net/"}
# 伪造浏览器访问


url_list = []
for i in range(6):
    url_list.append(shouye + dic[str(i)])  # 拿到网址

print("\n".join(url_list))

##url_list=[]的内容就是:
##https://www.mm131.net/xinggan/
##https://www.mm131.net/qingchun/
##https://www.mm131.net/xiaohua/
##https://www.mm131.net/chemo/
##https://www.mm131.net/qipao/
##https://www.mm131.net/mingxing/

os.chdir(os.getcwd())
if not os.path.exists(os.getcwd() + "/picture"):
    print("目录不存在,准备创建目录")
    os.mkdir("picture")
    os.chdir(os.getcwd() + "/picture")
else:
    print("目录已存在")
    os.chdir(os.getcwd() + "/picture")

# time.sleep(5)
localpath = os.getcwd()  # 原始目录
print("\n原始地址是:" + str(localpath))
# time.sleep(20)

# 进行分栏的切换
# ==========================第1层==========================
for j in range(len(url_list)):
    url = url_list[j]  # 每个分栏的地址www.xxxx/xxx/.com
    ##    url的内容就是:
    ##    https://www.mm131.net/xinggan/
    # print("\n"+url+"\n")

    res = requests.get(url=url, headers=headers, allow_redirects=False)  # 解析每个网址www.xxxx/xxx/.com
    # 这个是万能公式,解决网页解析下来乱码的问题
    res.encoding = res.apparent_encoding
    response = res.text  # 解析完成的网页
    html = etree.HTML(response)  # 格式化网页  总体的大纲
    # 准备提取每一栏的页数地址

    pages = html.xpath("/html/body/div[@class='main']/dl/dd[@class='page']/a/@href")  # 每个分栏里面的页数
    last = re.findall(r"\d+", str(pages[-1]))  # 每一栏最后的页数
    last_page = int(last[-1])  # 每一栏最后的页数
    # print("\n".join(pages))
    ##    pages的内容是:
    ##    list_6_2.html
    ##    list_6_3.html
    ##    list_6_4.html
    ##    list_6_5.html
    ##    list_6_6.html
    ##    list_6_7.html
    # print("最后的页数是:",last_page)

    # 下面开始拼接制作每一页的地址

    c = 0
    pic_page = re.sub(r"\d+\.", "{}", pages[-1])
    # pic_page就是做匹配 内容是:list_6_{}html

    picad = []  # 把每页的地址放在这个列表里面

    # 找到当前这一栏中所拥有的所有的页数
    # ==========================第2层==========================
    for ye in range(1, last_page + 1):

        if c == 0:
            picad.append(url)  # picad就是每个套图的地址
            c = 1
        else:
            m = str(ye) + "."

            picad.append(url + pic_page.format(str(m)))
            # picad就是这个https://www.mm131.net/qingchun/list_1_32.html

    # print("\n".join(picad))

    for page_eve in picad:  # 解析每一页的地址
        print("现在的页面地址是:" + page_eve + "\n")
        # time.sleep(1)

        # 解析流程走一下
        res_page = requests.get(url=page_eve, headers=headers, allow_redirects=False)  # 解析每个网址www.xxxx/xxx/.com
        res_page.encoding = res_page.apparent_encoding
        response_page = res_page.text  # 解析完成的网页
        html_page = etree.HTML(response_page)

        # 开始收集素材了
        allxpath = html_page.xpath("/html/body/div[4]")  # 每个界面的最大的div


        # 定位到这一页的所有套图,相当于锁定每一个套图
        # ==========================第3层==========================
        for div in allxpath:
            # 这边留个bug,就是我没有获取每一页的最后一页
            # 也就是说,当我把一个分栏的图片全部采集完之后他会不会自动跳转
            # 到下一栏,这是个问题,留一下这个bug,等下做下测试

            # 获取每一个套图的图片地址
            # pic=div.xpath("./dl/dd/a/img/@src")

            # 这个是我需要的每个套图的总地址,要通过这个地址获取每张图的地址
            # 结果是这样的:https://www.mm131.net/xinggan/5044.html
            pic_url = div.xpath("./dl/dd/a[@target='_blank']/@href")


            # print("\n".join(pic))
        ##            print("\n下面是这页的所有套图地址,正在加载:")
        ##            time.sleep(2)
        ##            print("\n"+"\n".join(pic_url))
        ##            time.sleep(1)

        ##        print("这页一共有:"+str(len(pic_url))+"套图"+"\n\n")#每一页套图的数量(除了最后一页都是20套)
        ##        time.sleep(2)
        ##        print("图片地址:"+"\n".join(pic))
        ##        time.sleep(7)

        for x in pic_url:

            print("当前套图地址是:" + x)
            # x就是这样的:https://www.mm131.net/xinggan/5115.html

            # 又是一波解析,这次直接搞图片的地址
            res_url = requests.get(url=x, headers=headers, allow_redirects=False)
            res_url.encoding = res_url.apparent_encoding
            response_url = res_url.text  # 解析完成的网页
            x_url = etree.HTML(response_url)

            # 这次的解析和之前的解析是不一样的界面
            y_url = x_url.xpath("/html/body/div[5]/div[4]/span[1]/text()")
            # 这边的xpath有几种写法,我现在的写法是直接复制网页里面的xpath
            # 问题就在于,如果目标网站做了微小的改动的话,就会报错了,
            # 因为获取不到正确的东西,那么就要锁定它本来的面目,下面给出写法
            # "/html/body/div[@class='content']/div[@class='contentpage']/span[@class='page-ch']/text()"
            # "//span[@class='page-ch'][1]/text()" 这种相比较上一种是简化版,直接找到
            # 对应的终极路径,但是上面那种比较稳定,在不出现重复变量的情况下比较好
            # 但是速度慢

            y_url = str(y_url)  # ['共12页']
            # print(y_url)

            # 找到每套图共有几页
            biggests = re.findall(r"\d+", y_url)

            biggest = ''.join([str(big) for big in biggests])
            # 上面这种比较官方,用于列表内容比较多的情况
            # 因为这边就只有一个数字所以也可以用这种写法,如下
            # biggest=''.join(str(biggests[-1]))
            biggest = int(biggest)
            # biggest就是这套图一共有biggest张图片
            print("这套图一共有" + str(biggest) + "页\n")
            # print(type(biggest))

            # 接下来重点,在x这个网页后面加上"xxx_x.html"样式  然后
            # 再循环xpath 就可以找到地址了  然后就可以下载
            # 只要在这个循环里面做就可以了不用跑到上个循环了

            ##           x: https://www.mm131.net/xinggan/5115.html
            ##            变成
            ##           change https://www.mm131.net/xinggan/5115_{}.html.foramt(2-最后一张)
            number = 0

            # 找到每张图片的解析地址
            change = re.sub(r"\.h", "_{}.h", x)

            # 找到每套图的唯一序号
            xuhao = re.findall(r"(\d+).*\/(\d+)\..*", x)
            pages_add = xuhao[-1][-1]

            # xxxxxxxxxxxxxxxxxxx进行路径切换xxxxxxxxxxxxxxxxxxx
            os.chdir(localpath)  # 目录重定位,不然会乱
            # 给定位,然后判断文件夹在不在,若不在则创建
            realpath = os.getcwd() + os.path.sep + str(pages_add)
            if not os.path.exists(realpath):
                os.mkdir(realpath)
                print('\n文件夹' + str(pages_add) + '不存在,创建完成')
            else:
                print('\n文件夹' + str(pages_add) + '已存在,无需创建')

            os.chdir(realpath)
            print("\n当前目录是:" + str(os.getcwd()) + "\n")
            # xxxxxxxxxxxxxxxxxxx进行路径切换xxxxxxxxxxxxxxxxxxx

            # 开始解析每张图片的地址
            # ==========================第4层==========================

            for kk in range(1, biggest + 1):
                if number == 0:
                    jiexi = x
                    number = 1

                else:
                    # print(kk)

                    jiexi = change.format(kk)
                # print("当前图片地址是:"+jiexi)

                mm_url = requests.get(url=jiexi, headers=headers, allow_redirects=False)
                mm_url.encoding = mm_url.apparent_encoding
                lookmm_url = mm_url.text  # 解析完成的网页
                last_url = etree.HTML(lookmm_url)
                # print(lookmm_url)

                # 进行图片地址解析
                fin = last_url.xpath("/html/body/div[5]/div[3]/a/img/@src")
                # 这边和上面差不多,给写法//div[@class='content-pic']//@src

                # 转换格式,转换成str格式,否则没办法解析
                fin_url = ''.join(str(fin[-1]))

                # allow_redirects=False禁止重定向
                pres = requests.get(url=fin_url, headers=headers, allow_redirects=False)
                with open(pages_add + "第" + str(kk) + "张" + ".jpg", "wb") as f:
                    print("开始下载第" + str(kk) + "张")
                    f.write(pres.content)
            print("结束")
            print("由于特殊原因,请等待5秒")
            time.sleep(5)










我要说明一下,其中有很多注释是没什么用的,也有很多是我用来验证结果的,也有些事为了方便看懂代码的,所以整体会有点乱。真心要学习的,自己看吧。

还有个重要的事情,我做这个项目路程坎坷,曾经一度想放弃,原因是因为网站的缘故,我一度以为只要找到一个页面进行解析就可以了,没想到后面图片根本出不来,它的页面和图片不在一起,也就是说你能定位到每个套图,但是你没办法只靠这个定位找到图片的地址,所以这个问题烦的我都快疯了。再有我当时想放弃的时候,想着直接定义函数做,因为只要调用就行了,又简洁又快,但是我tm都做了一大半了,同时也是处女作,想想不甘。心,所以硬着头皮搞定它。我在写这个项目的时候也学了很多东西。总之,多写写有好处的。

因为这个版本爬虫速度太慢了也没有使用线程(还没学),考虑到这个,没有在第二层循环再加上文件夹叠加,这种速度也没必要加了。如果跑,一定能把所有的图片全部跑完,没有问题,但是时间上过不去。另外有很多的变量名称没起好,后续会改进,然后后面准备出两个版本,一个是定义函数,一个是在函数的基础上加上线程。最后,本代码只是个人成果,拿出来分享。请勿用于商业违法用途,违者必究!

补充:2020年3月6日17:14:27 这里的代码稍微有点改动,跟之前的一样,也是做了xpath里面的修改。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值