python爬虫实战——爬点美图给你做壁纸

应朋友要求,给他写一篇关于爬虫的博客,翻翻找找,找到了以前写的爬虫里表现得比较好的,拿出来给大家讲讲。

什么是爬虫

先从百度百科上对爬虫的定义开始吧:

网络爬虫是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本

这篇博客,我们就做个简单的定向爬虫,先来看看爬虫工作的流程:
在这里插入图片描述
首先是计算机通过要爬取的网页的url对网页发送请求,网页接收到请求后在没有问题的情况下会接受请求并返回响应,返回的响应会携带网页的html源码。获取到html文本后就是我们这篇博客编写的爬虫需要做的最主要的任务——解析网页并将它保存。
想要看更详细的,可以参考大佬的博客爬虫系列(一) 网络爬虫简介

编写爬虫要用的库

接下来我们介绍编写爬虫要用到的库,我这里就简单介绍一下requests库和我比较喜欢的re库:

requests库

原文:
requests库
安装requests库可以命令行输入:

pip install requests

request对象常用的请求方法:

  1. request 其他六个方法,底层调用该方法
  2. get 从服务器获取资源
  3. post 将资源提交到服务(不可覆盖)
  4. put 修改服务器资源(可覆盖)
  5. head 获取服务器资源的部分信息
  6. patch 修改服务器资源(可部分覆盖)
  7. delete 删除服务器资源
    当然我们后面用到的只有get()方法

然后是请求常用的几个可选参数:

  1. timeout 设置超时(单位:秒)imeout = 30
  2. params get请求携带的参数
  3. data post请求携带的参数
  4. headers 请求头参数 headers = {“User-Agent”: “Mozilla/5.0”}
  5. files 上传文件files= {“files”:open(“git.jpeg”,“rb”)}
  6. proxies 服务器代理,模拟真实的主机proxies={“http”:“http://user:[email protected]:9999”,“https”:“http://127.0.0.1:8888”}
  7. auth 认证auth=(“user”,“123”)
    当然,我写代码并没有用到这些,但并不代表他们不重要。

最后是request常用的几个属性:

import requests
def common_attributes():
    url = "https://www.baidu.com/"
    r = requests.get(url)
    print(r.raise_for_status)       # 状态码
    print(r.encoding)               # 字符编码吗,header中content-type中的值
    print(r.apparent_encoding)      # 实际文档编码,更具文档分析出来的编码
    print(r.headers)                # response头
    print(r.text)                   # 服务器返回的文本
    print(r.content)                # 返回的内容的二进制
    print(r.cookies)                # 返回的cookies
    print(r.request.headers)        # 请求头
    print(r.request.url)            # 请求url

r.text中包含的就是我们要进行解析的html文本。

re库

这里介绍re库并不是说它是最简单的,只是我自己在用的过程中实在是没有很理解beautifulsoup的使用,经常出错,所以我写爬虫的时候常用re。并且如果要深入爬虫的话,re库是必须要学会用的。
re库,即正则表达式库,熟悉正则表达式的同学肯定能很快上手,不熟悉的就得好好补补了,毕竟这是比较重要的无论是在python还是一些其他的编程语言。
原文:Python的Re库(正则表达式)基本用法
介绍常用的几个功能函数:
在这里插入图片描述
这些功能函数的参数有需要的可以自己去查询,我说说下面要用的:
1、re.search(pattern,string,flags=0)

在一个字符串中搜索匹配正则表达式的第一个位置,返回match对象

pattern:正则表达式的字符串或原生字符串表示

string:待匹配的字符串

flags:正则表达式使用时的控制标记
2、re.findall(pattern,string,flags=0)

搜索字符串,以列表类型返回全部能匹配的字串

pattern:正则表达式的字符串或原生字符串表示

string:待匹配的字符串

flags:正则表达式使用时的控制标记
什么是flags控制标记呢:
在这里插入图片描述
这里先不解释,因为我们下面用不到,但你要爬小说的话,一定会用到的!

开始做爬虫吧

那么接下来我们开始吧。
我下面要爬的是一个桌面壁纸网站的壁纸,先看看这个网站:
在这里插入图片描述
url网址:

http://www.netbian.com/sitemap/index.htm

我们要爬取的就是资源列表里的这些,我选的这个网站是文字的,点击后才会看到壁纸图片,方便爬取。我们可以先自己试试点击壁纸,然后下载等等等等。其实爬虫也就是模仿我们使用浏览器点击、阅读的过程,自己走了一遍流程,就能够明白爬虫该怎么编写了!!!
接下来上代码:

爬虫代码

# -*- coding: utf-8 -*-
"""
Created time: 2020/2/6 14:20

  爬取桌面壁纸(图片)
  
@author: 沧海云帆
"""

import requests
import os
import re

def geturl(url):
	'''
	获取主网页上各个图片所在网页
	'''
    a = 'http://www.netbian.com'#获取图片的尾地址后添加前缀
    try:
        r = requests.get(url)
        r.raise_for_status()
        r.encoding = r.apparent_encoding
    except:
        print('error')
    list0 = []
    list0 = re.findall(r'<a href="/desk/\d{5}.htm" target="_blank">',r.text)
    list1 = []
    for i in list0:
        list1.append(a + i[9:24])#切片获取地址
    return list1#返回带有图片地址的列表

def getpurl(url):
	'''
	获得图片的下载链接
	'''
    try:
        r = requests.get(url)
        r.raise_for_status()
        r.encoding = r.apparent_encoding
    except:
        print('error')
    match = re.search('<img src="http://img.netbian.com/file/.*?\.jpg" alt',r.text)#搜索下载链接
    picurl = match.group(0)
    picurl = picurl.split('"')[1]
    
    return picurl#返回下载链接

def writetojpg(url):
	'''
	保存图片
	'''
    root = "D:/pic/"#存储目录
    path = root + url.split('/')[-1]
    try:
        if not os.path.exists(root):
            os.mkdir(root)
        if not os.path.exists(path):
            r = requests.get(url)
            with open(path,'wb') as f:
                f.write(r.content)#写入文件,即下载
                f.close()
        else:
            print("文件已经存在!")
    except:
        print("爬取失败!")

def main():
	'''
	主程序
	'''
    print("开始")
    url_1 = "http://www.netbian.com/sitemap/index.htm"
    list1 = geturl(url_1)
    for j in list1:
        picurl = getpurl(j)
        writetojpg(picurl)
        
    print("1/10 成功")
    for i in range(2,10):
        try:
            list2 = geturl("http://www.netbian.com/sitemap/index_%s.htm" % str(i))
            for j in list2:
                picurl = getpurl(j)
                writetojpg(picurl)
            print("%s/10 成功" % str(i))
        except:
            print("失败")
            continue
        
    print("结束")
   
if __name__ == "__main__":
    main()

这是我蛮早之前写的代码,今天重新翻出来封装了一下,没有什么注释,看起来不太舒适,接下来我来慢慢讲。
首先我们直接看主函数main()来理解流程:

def main():
	'''
	主程序
	'''
    print("开始")
    url_1 = "http://www.netbian.com/sitemap/index.htm"
    list1 = geturl(url_1)
    for j in list1:
        picurl = getpurl(j)
        writetojpg(picurl)
        
    print("1/10 成功")
    for i in range(2,10):
        try:
            list2 = geturl("http://www.netbian.com/sitemap/index_%s.htm" % str(i))
            for j in list2:
                picurl = getpurl(j)
                writetojpg(picurl)
            print("%s/10 成功" % str(i))
        except:
            print("失败")
            continue
        
    print("结束")

url_1 就是我们要爬取的那个网站的网址,因为首页的url的index后没有后缀,所以需要把首页爬取过程放到循环外面,而其他的页面都有index_2,index_3样的就可以直接做个循环来爬取。
循环里做的任务就比较容易理解了:geturl()获取到各个网页上的壁纸的url链接;getpurl()获取到壁纸的下载链接;writetojpg()将图片保存。
接下来我们看看这几个函数是怎么实现的:

def geturl(url):
	'''
	获取主网页上各个图片所在网页
	'''
    a = 'http://www.netbian.com'#获取图片的尾地址后添加前缀
    try:
        r = requests.get(url)
        r.raise_for_status()
        r.encoding = r.apparent_encoding
    except:
        print('error')
    list0 = []
    list0 = re.findall(r'<a href="/desk/\d{5}.htm" target="_blank">',r.text)
    list1 = []
    for i in list0:
        list1.append(a + i[9:24])#切片获取地址
    return list1#返回带有图片地址的列表

r.raise_for_status()在这里并没有发挥多大的作用,只是在测试的时候需要用到,我就懒得删了,如果得到响应,它的返回值应该是200;
r.encoding = r.apparent_encoding这行代码只要是为了统一编码,有时候,爬虫识别的编码不正确会导致得到的是乱码;
re.findall()会返回一个列表,代码里的第一个参数就是正则表达式字符串,其实实际发挥作用的只有\d{5}表示五个数字,然后就是切片获取图片地址了,没啥好说的。

def getpurl(url):
	'''
	获得图片的下载链接
	'''
    try:
        r = requests.get(url)
        r.raise_for_status()
        r.encoding = r.apparent_encoding
    except:
        print('error')
    match = re.search('<img src="http://img.netbian.com/file/.*?\.jpg" alt',r.text)#搜索下载链接
    picurl = match.group(0)
    picurl = picurl.split('"')[1]
    
    return picurl#返回下载链接

和上面一样的开头,但是这里并没有用re.findall(),而是使用了re.search(),它将匹配正则字符串并返回第一个匹配成功的(以match对象的方式),实际起作用的是正则字符串中实际起作用的是(.*?),匹配任意字符串;
match.group(0)返回的就是匹配到的字符串;下面那行是拆分并获取下载地址。

def writetojpg(url):
	'''
	保存图片
	'''
    root = "D:/pic/"#存储目录
    path = root + url.split('/')[-1]
    try:
        if not os.path.exists(root):
            os.mkdir(root)
        if not os.path.exists(path):
            r = requests.get(url)
            with open(path,'wb') as f:
                f.write(r.content)#写入文件,即下载
                f.close()
        else:
            print("文件已经存在!")
    except:
        print("爬取失败!")

这个函数就没有什么好讲的了,就是通过获取到的下载链接,访问下载,我这里是写入到了D盘下的pic文件夹。
运行截图:
在这里插入图片描述
在这里插入图片描述

整个爬虫会爬取十个页面大概一百七十多张壁纸。

爬虫是我在慕课上跟着嵩天老师的慕课学的,有兴趣多学一些的可以去看看。

猜你喜欢

转载自blog.csdn.net/qq_44725872/article/details/108950317