应朋友要求,给他写一篇关于爬虫的博客,翻翻找找,找到了以前写的爬虫里表现得比较好的,拿出来给大家讲讲。
先从百度百科上对爬虫的定义开始吧:
网络爬虫是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本
这篇博客,我们就做个简单的定向爬虫,先来看看爬虫工作的流程: 首先是计算机通过要爬取的网页的url对网页发送请求,网页接收到请求后在没有问题的情况下会接受请求并返回响应,返回的响应会携带网页的html源码。获取到html文本后就是我们这篇博客编写的爬虫需要做的最主要的任务——解析网页并将它保存。 想要看更详细的,可以参考大佬的博客爬虫系列(一) 网络爬虫简介
接下来我们介绍编写爬虫要用到的库,我这里就简单介绍一下requests库和我比较喜欢的re库:
原文: requests库 安装requests库可以命令行输入:
pip install requestsrequest对象常用的请求方法:
request 其他六个方法,底层调用该方法get 从服务器获取资源post 将资源提交到服务(不可覆盖)put 修改服务器资源(可覆盖)head 获取服务器资源的部分信息patch 修改服务器资源(可部分覆盖)delete 删除服务器资源 当然我们后面用到的只有get()方法然后是请求常用的几个可选参数:
timeout 设置超时(单位:秒)imeout = 30params get请求携带的参数data post请求携带的参数headers 请求头参数 headers = {“User-Agent”: “Mozilla/5.0”}files 上传文件files= {“files”:open(“git.jpeg”,“rb”)}proxies 服务器代理,模拟真实的主机proxies={“http”:“http://user:password@127.0.0.1:9999”,“https”:“http://127.0.0.1:8888”}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) # 请求urlr.text中包含的就是我们要进行解析的html文本。
这里介绍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我们要爬取的就是资源列表里的这些,我选的这个网站是文字的,点击后才会看到壁纸图片,方便爬取。我们可以先自己试试点击壁纸,然后下载等等等等。其实爬虫也就是模仿我们使用浏览器点击、阅读的过程,自己走了一遍流程,就能够明白爬虫该怎么编写了!!! 接下来上代码:
这是我蛮早之前写的代码,今天重新翻出来封装了一下,没有什么注释,看起来不太舒适,接下来我来慢慢讲。 首先我们直接看主函数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文件夹。 运行截图:
整个爬虫会爬取十个页面大概一百七十多张壁纸。
爬虫是我在慕课上跟着嵩天老师的慕课学的,有兴趣多学一些的可以去看看。