案例1:熟悉HTTP工作流程
案例2:爬取网页
案例3:爬取图片
案例4:处理下载错误
1 案例1:熟悉HTTP工作流程
1.1 问题
为Firefox安装firebug插件
打开Firefox的firebug或Chrome开发者工具
访问http://www.tedu.cn
在开发者工具的“网络”选项卡中查看请求和响应
1.2 步骤
实现此案例需要按照如下步骤进行。
步骤一:为Firefox安装firebug插件
1)打开Firefox浏览器,点击右上角打开菜单按钮/,打开附加组件,如图-1所示:
图-1
2)右上角搜索框搜索firebug插件,如图-2所示:
图-2
3)选定搜索结果安装,如图-3所示:
图-3
4)安装成功,如图-4所示:
图-4
步骤二:访问http://www.tedu.cn
访问http://www.tedu.cn,按“F12”打开Firefox的firebug,如图-5所示:
图-5
步骤二:在开发者工具的“网络”选项卡中查看请求和响应
如图-6所示:
图-6
注意:
常用的请求报头:
METHOD 请求资源的方法,这个是必须的
Host 被请求资源的名子,这个是必须的
Accept 请求报头域用于指定客户端接受哪些类型的信息
Accept-Encoding 它是用于指定可接受的内容编码
User-Agent 客户端信息
Connection 是否关闭连接
GET应响消息:
HTTP/1.1 200 协议、版本和状态码
Date 日期时间
Server 服务器信息
Content-Type 响应内容类型
Content-Length 响应数据长度
Last-Modified 资源最后更改时间
Connection 连接方式
2 案例2:爬取网页
2.1 问题
编写一个get_web.py脚本,实现以下功能:
爬取的网页为http://www.tedu.cn
保存的文件名为/tmp/tedu.html
2.2 方案
导入sys模块,用sys.argv方法获取get_web函数实参,让用户在命令行上提供http://www.tedu.cn和/tmp/tedu.html两个参数,调用get_web函数实现如下功能:
1)导入urllib模块,使用urllib模块的urlopen函数打开url(即网址),赋值给html
2)以写方式打开/tmp/tedu.html文件
3)以循环方式:
读html获取的数据,保存到data
将data写入/tmp/tedu.html
4)关闭html
2.3 步骤
实现此案例需要按照如下步骤进行。
步骤一:编写脚本
[root@localhost day11]# vim get_web.py
#!/usr/bin/env python3
import sys
from urllib.request import urlopen
def get_web(url, fname):
html = urlopen(url) #使用urllib模块的urlopen函数打开url,赋值给html
with open(fname, 'wb') as fobj:
while True:
data = html.read(4096)
if not data:
break
fobj.write(data)
html.close()
if __name__ == '__main__':
get_web(sys.argv[1], sys.argv[2]) #让用户在命令行上提供网址和下载数据保存位置
步骤二:测试脚本执行
[root@localhost day11]# python3 get_web.py http://www.tedu.cn /tmp/tedu.html
[root@localhost day11]# cat /tmp/tedu.html
执行cat命令可以看到/tmp/tedu.html文件中爬取到的内容
3 案例3:爬取图片
3.1 问题
将http://www.tedu.cn所有的图片下载到本地
本地的目录为/tmp/images
图片名与网站上图片名保持一致
3.2 步骤
实现此案例需要按照如下步骤进行。
步骤一:编写脚本
1)爬取网页内容放入指定fname(即/tmp/tedu.html)文件中
创建get_web.py文件,编写代码如下:
[root@localhost day11]# vim get_web.py
#!/usr/bin/env python3
import sys
from urllib.request import urlopen #导入urllib
def get_web(url, fname): #url为爬取目标网址(www.tedu.cn)
#fname为爬取内容存储文件名
html = urlopen(url) #使用urllib模块的urlopen函数打开url,赋值给html
with open(fname, 'wb') as fobj: #以写方式打开文件
while True:
data = html.read(4096) #读html获取的数据,保存到data
if not data:
break
fobj.write(data) # 将data写入文件中
html.close()
2)利用正则匹配,将爬取到的fname文件内容中所有图片网址放入result列表
创建get_url.py文件,编写代码如下:
[root@localhost day11]# vim get_url.py
#!/usr/bin/env python3
import sys
import re
def get_url(patt, fname): #patt可匹配图片网址正则表达式,
#fname为1)中爬取到内容的文件
cpatt = re.compile(patt) #将正则表达式字符串形式编译为cpatt实例
result = [] #存放匹配正则表达式的图片网址
with open(fname) as fobj: #打开爬取到网站(www.tedu.cn)内容的文件
for line in fobj: #遍历fname文件
m = cpatt.search(line) #使用cpatt实例查找匹配规则的网址
if m:
result.append(m.group()) #将匹配到的图片网址最加到result列表
return result #函数最终返回result列表
if __name__ == '__main__':
url = r'http://[.\w/-]+\.(jpg|png|jpeg|gif)' #符合图片网址规则的正则表达式
print(get_url(url, sys.argv[1]))
3)遍历图片列表result,将图片网址对应内容爬取下来存入指定文件
创建download.py文件,编写代码如下:
[root@localhost day11]# vim download.py
#!/usr/bin/env python3
import os
from get_url import get_url #导入get_url函数
from get_web import get_web #导入get_web函数
#调用get_web函数爬取/http://www.tedu.cn网站内容,存入/tmp/tedu.html文件中
get_web('http://www.tedu.cn/', '/tmp/tedu.html')
#符合图片网址正则表达式
img_url = r'http://[.\w/-]+\.(jpg|png|jpeg|gif)'
#调用get_url函数,从/tmp/tedu.html文件中获取符合匹配规则的图片网址,
#存入result列表中,将列表结果赋值给urls变量
urls = get_url(img_url, '/tmp/tedu.html')
#爬取到的图片存储目录
img_dir = '/tmp/images'
#判断目录是否存在,如果不存在则创建该目录
if not os.path.exists(img_dir):
os.mkdir(img_dir)
#遍历图片网址列表,每次循环遍历出一个图片网址
for url in urls:
# url.split('/')[-1]:将网址切片,取最后一个字符命名图片
#将图片存储目录与图片名拼接,举例:fname=/tmp/images/XXX.png
fname = os.path.join(img_dir, url.split('/')[-1])
#调用get_web函数,爬取图片网址内容,存入fname文件中
get_web(url, fname)
步骤二:测试脚本执行
[root@localhost day11]# python3 download.py
[root@localhost day11]# nautilus /tmp/images
执行以上命令即可看到爬取的图片,且图片命名与网站上图片命名一致
4 案例4:处理下载错误
4.1 问题
起动一个web服务
在web服务器的文档目录下创建目录ban,权限设置为700
编写python程序访问不存在的路径和ban目录,处理404和403错误
404错误打印“无此页面”,403错误打印“无权访问”
4.2 步骤
实现此案例需要按照如下步骤进行。
步骤一:启动一个web服务
[root@localhost ~]# systemctl restart httpd
步骤二:在web服务器的文档目录下创建目录ban,权限设置为700
[root@localhost ~]# mkdir -m 700 /var/www/html/ban
步骤三:如果访问的页面不存在或拒绝访问,程序将抛出异常
执行案例2中get_web.py文件,访问不存在页面,抛出404异常如下:
[root@localhost day11]# python3 get_web.py http://127.0.0.1/abc/ /tmp/abc.html
Traceback (most recent call last):
...
...
raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 404: Not Found
执行案例2中get_web.py文件,访问存在页面ban目录,抛出403权限异常如下:
[root@localhost day11]# python3 get_web.py http://127.0.0.1/ban/ /tmp/abc.html
Traceback (most recent call last):
...
...
raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 403: Forbidden
步骤三:编写python程序捕获异常
创建get_web3.py文件,实现访问不存在的路径和ban目录时,捕获404和403错误
,同时404错误打印“无此页面”,403错误打印“无权访问”,代码如下:
import sys
from urllib.request import urlopen
from urllib.error import HTTPError #导入urllib.error模块,用HTTPError捕获异常信息
def get_web(url, fname):
try:
html = urlopen(url) #打开网址时即可知道是否有异常,所以将本语句放入try语句
except HTTPError as e: #捕获返回HTTPError类的实例e
print(e)
if e.code == 403: #捕获异常状态码如果等于403
print('权限不足') #输出'权限不足'
elif e.code == 404: #捕获异常状态码如果等于404
print('没有那个地址') #输出'没有那个地址'
return #return后面代码均不执行
with open(fname, 'wb') as fobj:
while True:
data = html.read(4096)
if not data:
break
fobj.write(data)
html.close()
if __name__ == '__main__':
get_web(sys.argv[1], sys.argv[2])
测试脚本执行:
访问不存在页面:
[root@localhost day11]# python3 get_web.py http://127.0.0.1/abc/ /tmp/abc.html
HTTP Error 404: Not Found
没有那个地址
访问ban目录:
[root@localhost day11]# python3 get_web.py http://127.0.0.1/ban/ /tmp/abc.html
HTTP Error 403: Forbidden
权限不足