爬虫日记-一键下载****张壁纸-基础版 彼岸 桌面壁纸 附源码 可执行


title: 爬虫日记-一键下载****张壁纸-基础版 彼岸 桌面壁纸 附源码 可执行
tags: ['python','爬虫','try except','正则表达式']
date: 2021-12-11
categories: "爬虫日志"



环境
window10

python3

re
requests
etree

源码地址

[TOC]

前言

这次来写一个基础版的获取网络上公开免费壁纸的爬虫,采集的网站为 彼岸桌面 ,网站打开是这个样子:

image-20211211154701084

红色框框中为我们这次的目标。

分析网站

以第一页面为例。

通过测试发现,访问网站不需要特殊的请求头或者加密字段,拿到网页源码应该会比较容易。

打开 彼岸桌面 ,第一页红色框框框住的地方总共有20个图片,每张图片又可以通向这张图片的详情页(大图页面),进入大图也可以拿到大图的url,通过目标图片的url,使用一定的方法下载图片下来就可以了。

继续分析并写出相应代码

1 获取网页源码

这个网站的请求不需要特殊的请求头,也没有什么加密,因此用最简单的方法去实现就可以,获取网页源码的方法代码为:

def get_source_code(url):
    """
    获取给定url的网页源码
    :param url: 要去访问的url
    :return:返回该url网页源码,字符串形式
    """
    # 构造一个普通的请求头
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36',
    }
    # 发送请求,拿到数据
    response = requests.request("GET", url, headers=headers)
    # 返回网页源码
    return response.text

2 获取图片 url

2.1 这里先做一定的分析,再尝试去写代码。

正常的思路是:

image-20211211160432265

相对应的几个数据

image-20211211160810914

通过这样的比对,我们可以发现,大图和小图的url貌似有一些联系,通过多找几张图片进行比对,发现他们之间大概是这样的关系:

image-20211211161508469

大图url所包含的数据信息,小图全都有,所以我们可以不进入详情页,通过对小图url进行一定的处理直接得到大图的url。

image-20211211161821413

okok,接下来开始写代码。

2.2 通过上次用到的etree解析网页,获取小图的url

def get_img_url(text):
    _ = etree.HTML(text)
    data_list = _.xpath("//div[@class='list']//a")
    for data in data_list:
        # 获取小图的url
        small_pic_url = data.xpath("./img/@src")[0]

2.3 获取这张图片独特的表示代码pic_id

def get_img_url(text):
    _ = etree.HTML(text)
    data_list = _.xpath("//div[@class='list']//a")
        small_pic_url = data.xpath("./img/@src")[0]
        pic_id = re.search(r"/small(.*?)\.jpg",small_pic_url).groups()[0][:-10]

关于正则表达式,这次就不展开说了,有机会单独整理归纳出来。

这次推荐一个网址 正则表达式 在线测试 ,有一些常用语法介绍,可以测试正则表达式是否正确,写之前去测一下,还有一些常用语言的代码生成,嗯,本菜猫觉得很赞。

image-20211211162504591

2.4 获取大图的url

def get_img_url(text):
    _ = etree.HTML(text)
    data_list = _.xpath("//div[@class='list']//a")
    for data in data_list:
        small_pic_url = data.xpath("./img/@src")[0]
        pic_id = re.search(r"/small(.*?)\.jpg",small_pic_url).groups()[0][:-10]
        pic_url = re.sub(re.findall("/(small.*?)\.jpg",small_pic_url)[0],pic_id,small_pic_url)
        print("小图地址\t",small_pic_url)
        print("大图地址\t",pic_url)

2.5 问题的出现与解决

上面的步骤是在网页给出的小图url满足下图的情况下测才能够正常运行的,但是测试发现,页面上会随机出现跳到主页的图片,它并没有详情页,url规则也不满足上面的正则,程序也就拿不到大图的url,并且因此会报错,程序无法继续下去,因此这个地方我们需要进行一定的处理。

小图规则
特例情况

解决办法

  • 可以在正则的时候对结果做一个校验,如果返回的是None,那么就放弃这张图片,继续下一张图片的操作,使用if去编写程序;

  • 也可以直接做一个异常处理,即pythontry ... except ...

这里给出异常处理的代码,如果需要if的版本,自己尝试一下,实在不行评论区留言一下,摸鱼时间会去看一下解决的。

def get_img_url(text):
    _ = etree.HTML(text)
    data_list = _.xpath("//div[@class='list']//a")
    for data in data_list:
        print("-" * 100)
        try:
            small_pic_url = data.xpath("./img/@src")[0]
            pic_id = re.search(r"/small(.*?)\.jpg", small_pic_url).groups()[0][:-10]
            pic_url = re.sub(re.findall("/(small.*?)\.jpg",small_pic_url)[0],pic_id,small_pic_url)
            print("小图地址\t",small_pic_url)
            print("大图地址\t",pic_url)
        except:
            print(data.xpath("./img/@src"),"出错")

当然,这里即便是出错了,也可以判断一下,这里如果是一张图片,即使分辨率不够,但是也可以凑活凑活直接就当作大图去下载就是了。这里大家随意就好。

下载图片

下载图片和下载网页源码其实是一个样子的,都是通过访问去吧网页的数据拿下来,只不过网页源码我们是拿到字符串姓氏的数据,方便后米看的处理,而下载图片我们是要写到本地,用字符串写的话那就不是图片应该有的格式了,直接体现就是写到本地的图片打不开。

下面是一个常规的用pythonrequest去拿数据,写图片的操作。

需要先在py文件同级目录建一个名为img的文件夹

def download_img(img_url):
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36',
    }
    resp = requests.get(img_url, headers=headers, stream=True)
    if resp.status_code == 200:
        open('img/' + str(time.time()) + '.jpg', 'wb').write(resp.content) # 将内容写入图片
        print("下载图片成功")

resp.status_code为网页访问的状态码,一般200为正常访问。这边做了一个判断,只有正常拿数据才会执行写入图片的操作。

存储壁纸的位置为同级目录下的img文件夹,文件名直接以时间戳为名。

完整源码

import re
import time
import requests
from lxml import etree


def get_source_code(url):
    """
    获取给定url的网页源码
    :param url: 要去访问的url
    :return:返回该url网页源码,字符串形式
    """
    # 构造一个普通的请求头
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36',
    }
    # 发送请求,拿到数据
    response = requests.request("GET", url, headers=headers)
    # 返回网页源码
    return response.text


def get_img_url(text):
    _ = etree.HTML(text)
    data_list = _.xpath("//div[@class='list']//a")
    for data in data_list:
        print("-" * 100)
        try:
            small_pic_url = data.xpath("./img/@src")[0]
            pic_id = re.search(r"/small(.*?)\.jpg", small_pic_url).groups()[0][:-10]
            pic_url = re.sub(re.findall("/(small.*?)\.jpg", small_pic_url)[0], pic_id, small_pic_url)
            print("小图地址\t", small_pic_url)
            print("大图地址\t", pic_url)
            # 下载图片
            download_img(pic_url)
        except:
            print(data.xpath("./img/@src"), "出错")


def download_img(img_url):
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36',
    }
    resp = requests.get(img_url, headers=headers, stream=True)
    if resp.status_code == 200:
        open('img/' + str(time.time()) + '.jpg', 'wb').write(resp.content)  # 将内容写入图片
        print("下载图片成功")


if __name__ == '__main__':
    url = "http://www.netbian.com/index.htm"
    source_code = get_source_code(url)
    get_img_url(source_code)

运行结果

image-20211211171427306
image-20211211171441371

写在最后

这个爬虫有很多不完善的地方,比如:

  • 暂时只写了第一页,后面没写。。。。。。

  • 图片名最好也采集到,不然看到的结果都是一串数字,很奇怪。而且把图片名那下来之后,可以进行一定的分类筛选,比如名称带美女两个字的可以单独放在另外一个文件夹,巴拉巴拉。。。。。。

  • 下载图片的地方需要手动先建一个img的文件夹,否则报错。。。虽然很简单,但是下次改。。。

  • 整个程序基本使用的是顺序结构,单线程运行,下载的速度有待提高(多线程);

  • 如果要访问100,1000页,那程序万一中间停止了,又要从头开始,那不坑爹嘛。加上一个历史功能也是挺有必要的;

  • 要是真的要采集比较多的数量,当网站发发现了我们的异常操作,经常会把我们的ip给拉黑,所以加一个代理也是很有必要的;(测试写了一页,没试过直接搞1000页)

  • 程序的鲁棒性。。。

爬虫仅做学习交流使用。

总之这个爬虫还有很大的优化空间,下次抽点时间完善一下。

实力有限,才疏学浅,如有错误,欢迎指正。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,542评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,822评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,912评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,449评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,500评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,370评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,193评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,074评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,505评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,722评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,841评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,569评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,168评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,783评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,918评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,962评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,781评论 2 354