1. Requests库入门
1.1 安装Requests库
用管理员权限启动cmd控制台,执行下列代码
# 安装Requests库
pip install requests
在Python环境下运行下列代码,验证requests库被安装
# 载入requests库
import requests
# 访问百度主页
r = requests.get('http://www.baidu.com')
# 查看状态码
r.status_code # 200(状态码200,表示访问成功)
# 更改编码
r.encoding = 'utf-8'
# 打印网络内容
r.text # 【结果很多,省略】
requests库方法 | 说明 |
---|---|
requests.request() |
构造一个请求,支撑以下各方法的基础方法 |
requests.get() |
获取HTML网页的主要方法,对应HTTP的GET |
requests.head() |
获取HTML网页头信息的方法,对应HTTP的HEAD |
requests.post() |
向HTML网页提交POST请求的方法,对应HTTP的POST |
requests.put() |
向HTML网页提交PUT请求的方法,对应HTTP的PUT |
requests.patch() |
向HTML网页提交局部修改请求,对应HTTP的PATCH |
requests.delete() |
向HTML网页提交删除请求,对应HTTP的PDELETE |
1.2 get()
方法
# 获得一个网页最简单的代码
r = requests.get('url')
# 完整的requests.get()函数的完整的使用方法有3个参数
r = requests.get('url', params=None, **kwargs)
url:拟获取页面的url链接
params
:url中的格外参数、字典、字节流格式,可选
**kwargs
:12个控制访问的参数,可选
构造一个向服务器请求资源的Request对象,这个对象是Requests内部生成的
返回一个包含服务器资源的Response对象
Requests库的2个重要对象:Request对象、Response对象
Response对象:包含爬虫返回的内容(包含服务器返回的所有信息,同时包含Request对象)
import requests
r = requests.get('http://www.baidu.com')
print(r.status_code)
# 检测r的类型
type(r)
print(type(r)) # 【结果表示返回的r是一个class(类),class的名是requests】
# 返回get请求,获得页面的头部信息
r.headers
Response对象属性 | 说明 |
---|---|
r.status_code | HTTP请求的返回状态,200表示链接成功,404表示失败 |
r.text | HTTP响应内容的字符串形式,即url对应的内容页面 |
r.encoding | 从HTTP header中猜测的响应内容编码方式 |
r.apparent_encoding | 从内容中分析出的响应内容编码方式 |
r.content | HTTP响应内容的二进制形式 |
使用get()方法获取网上资源流程
r.status_code检测返回的Response对象状态
如果是200,可用r.text、r.encoding、r.apparent_encoding、r.content等去解析返回的内容
如果404或者其他,说明这次url的访问出现异常
import requests
r = requests.get('http://www.baidu.com')
print(r.status_code)
# 查看内容
r.text # (内容中有些地方有乱码)
# 查看编码
r.encoding # 'ISO-8859-1'
# 查看编码
r.apparent_encoding # 'utf-8'
# 更改编码后,答应内容
r.encoding = 'utf-8'
r.text # 内容中出现中文字符
r.encoding:如果header中不存在charset,则认为编码为ISO-8859-1(ISO-8859-1编码不能识别中文)
r.apparent_encoding:根据网页内容分析出的编码方式(原则上比r.encoding更加准确)
1.3 通用代码框架
理解Requests库的异常 | 说明 |
---|---|
requests.ConnectionError | 网络连接错误异常,如DNS查询失败、决绝连接等 |
requests.HTTPError | HTTP错误异常 |
requests.URLRequired | URL缺失异常 |
requests.TooManyRedirects | 超过最大重定向次数,产生重定向异常 |
requests.ConnectTimeout | 连接远程服务器超时异常 |
requests.Timeout | 请求URL超时,产出超时异常 |
# 下面方法专门与异常打交道,能够判断返回的Response状态是不是200,是200将表示返回内容正确,不是200就会产生一个requests.HTTPError
r.raise_for_status()
import requests
def getHTMLText(url):
'''
爬取网页通用代码框架
'''
# 涉及异常处理,用try-except语句
try:
# get方法请求url连接
r = requests.get(url, timeout = 30)
# 判断返回内容是不是正常。如果状态码不是200就会产生一个requests.HTTPError
r.raise_for_status()
# 用apparent_encoding替代encoding使得返回内容解码是正确的
r.encoding = r.apparent_encoding
# 返回网页的内容
return r.text
except:
return '产生异常'
if __name__ == '__main__':
url = 'https://www.baidu.com'
print(getHTMLText(url))
1.4 HTTP协议
HTTP(Hypertext Transfer Protocol, 超文本传输协议)
HTTP基于“请求与相应”模式的、无状态的应用层协议
“请求与相应”模式:用户发起请求,服务器做相关相应
无状态:第一次请求与第二次请求之间并没有相关的关联
应用层协议:指该协议工作在THP协议之上
HTTP协议采用URL作为定位网络资源的标识
URL格式:http://host [:port] [path]
host:合法的Internet主机域名或IP地址
:post:端口号,省略端口为80
path:资源在主机或IP地址的服务器上的内部路径
URL是通过HTTP协议存取资源的Internet路径
方法 | HTTP协议对资源的操作 |
---|---|
GET | 请求获取URL位置的资源 |
HEAD | 请求获取URL位置资源的相应消息报告,即获得该资源的头部信息 |
POST | 请求向URL位置的资源后附加新的数据 |
PUT | 请求向URL位置存储一个资源,覆盖原URL位置的资源 |
PATCH | 请求局部更新URL位置的资源,即改变该处资源的部分内容 |
DELETE | 请求删除URL位置存储的资源 |
假设URL位置有一组数据UserInfo,包括UserID、UserName等
需求:用户修改UserName,其他不变
采用PATCH:仅向URL提交UserName的局部更新请求(节省网络带宽)
采用PUT:必须将所有UserInfo一并提交到URL,未提交字段被删除
HTTP协议与Requests库方法(见1.1)是一一对应的
import requests
# head方法向服务器获得头部信息
r = requests.head('http://httpbin.org/get_ipython')
r.headers #{'Access-Control-Allow-Credentials': 'true', 'Access-Control-Allow-Origin': '*', 'Content-Encoding': 'gzip', 'Content-Type': 'text/html', 'Date': 'Thu, 07 Nov 2019 08:44:16 GMT', 'Referrer-Policy': 'no-referrer-when-downgrade', 'Server': 'nginx', 'X-Content-Type-Options': 'nosniff', 'X-Frame-Options': 'DENY', 'X-XSS-Protection': '1; mode=block', 'Connection': 'keep-alive'}
r.text # ''[内容为空,故head方法用很少的流量获得网络资源的概要信息]
import requests
# 用post方法向服务器提交新增数据(字典数据自动编码为form(表单)格式)
payload = {'key1': 'value1', 'key2': 'value2'}
r = requests.post('http://httpbin.org/post', data = payload)
print(r.text) # (一些内容) "form": {"key1": "value1", "key2": "value2"(其他内容)
# 用post方法向服务器提交新增数据(字符串数据自动编码为data)
r = requests.post('http://httpbin.org/post', data = 'ABC')
print(r.text) # (一些内容) "data": "ABC","files": {},"form": {},(其他内容)
put方法与post类似,只是会把原有数据覆盖掉
1.5 Requests库主要方法解析
1.5.1 request函数:requests.request(method, url, **kwargs)
method:请求方式
对应GET、PUT、POST、HEAD、PATCH、delete、OPTIONS(向服务器获取一些跟客户端能够打交道的参数,与获取资源不直接相关)等7种,例如r = requests.request('OPTIONS', url, **kwargs)
url:拟获取页面的url连接
**kwargs:13个控制访问参数
import requests
payload = {'key1': 'value1', 'key2': 'value2'}
'''
1. params:字典或字节序列,作为参数增加到url中
使得再访问时不止访问资源,同时带入了一些参数,服务器可以接受这些参数,并根据参数筛选部分资源返回回来
'''
# 用get方法向某个连接请求同时提供字典作为params相关参数
# 因为参数是可选的,所以要用赋值的方式调用具体参数
r = requests.request('GET', 'http://httpbin.org/post', params = payload)
# 打印url连接
print(r.url) # http://httpbin.org/post?key1=value1&key2=value2
'''
2. data:字典、字节序列或文件对象,作为Request的内容,向服务器提交资源时使用(见1.4)
'''
'''
3. json:JSON格式的数据,作为Request的内容想服务器提交
'''
r = requests.request('POST', 'heep://python123.io/wa', json = payload)
'''
4. headers:字典,定义了向url 访问时所发起的HTTP的头字段
'''
# 定义一个字典,用于修改HTTP协议中的user-agent字段,把user-agent变为Chrome/10(Chrome/10:Chrome浏览器的第10个版本)
hd = {'user-agent': 'Chrome/10'}
# 把hd赋给header,此时再去向服务器访问时服务器看到的user-agent变为Chrome/10。即我们可以模拟任何我们想模拟的浏览器向服务器发起访问
r = requests.request('POST', 'heep://python123.io/wa', header = hd)
'''
5. cookies:字典或者CookiesJar,从HTTP协议中解析cookies
6. auth:元组,支持HTTP认证功能
'''
'''
7. files:字典类型,向服务器传输文件
'''
# 定义一个字典,以file和对应文件作为键值对,用open方式打开这个文件
fs = {'file': open('data.xls', 'rb')}
# 文件与files做关联,同时对应到相关url上
r = requests.request('POST', 'heep://python123.io/wa', files = fs)
'''
8. timeout:设定超时时间,以秒为单位
'''
# 向服务器发起一个GET请求,如果在timeout时间内请求未返回,将产生一个timeout异常
r = requests.request('GET', 'heep://python123.io/wa', timeout = 10)
'''
9. proxies:字典类型,爬取网页设定访问代理服务器,可以增加登录认证。防止对爬虫的逆追踪
'''
# 增加2个代理,一是http访问时使用的代理,可以增加用户名和密码;二是增加https的访问时使用的代理服务器
pxs = {'http': 'http://user:pass@10.10.10.1:1234'
'heeps': 'https://10.10.10.1:4321'}
# 这样我们访问服务器时使用的IP地址就是代理服务器的IP地址
r = requests.request('GET', 'heep://www.baidu.com', proxies = pxs)
'''
10. allow_redirects:True/False,默认为True,重定向开关,表示允不允许对url进行重定向
11. stream:True/False,默认为True,获取内容立即下载开关,表示是否对获取内容进行立即下载
12. verify:True/False,默认为True,认证SSL证书开关
13. cert:本地的SSL证书路径
'''
1.5.2 另外6种方法方法
requests.get(url, params = None, **kwargs)
**kwargs:12个控制访问参数(就是request里面除了params以外对应的参数)
下列如果设定参数了,那 **kwargs只表示剩下的参数
requests.head(url, **kwargs)
requests.post(url, data = None, json = None, **kwargs)
requests.put(url, data = None, **kwargs)
requests.patch(url, data = None, **kwargs)
requests.delete(url, **kwargs)
HTTP协议中,向服务器提交资源的功能在服务器上是严格控制
1.6 单元小结
1.6.1 requests库7种方法
requests.request():基础方法
requests.get()、requests.head():最常使用的就是get;对于特别大的网络连接用head获取资源概要(重点掌握)
requests.post()、requests.put()、requests.patch()、requests.delete():由于网络安全的限制,很难向url去发起请求
1.6.2 爬取网页的通用代码框架
try:
r = requests.get(url, timeout = 30)
r.raise_for_status()
r.encoding = r.apparent_encoding
return r.text
except:
return '产生异常'
2. 网络爬虫的“盗亦有道”
目的 | 爬虫尺度 | 应用库 |
---|---|---|
爬取网页 | 小规模,数据量小,爬取速度不敏感 | Requests库 |
爬取网站 | 中规模,数据量大,爬取速度敏感 | Scrapy库 |
爬取全网 | 大规模,搜索引擎,爬取速度关键 | 定制开发 |
2.1 网络爬虫引发的问题
1)“骚扰”问题:受限于编写水平和目的,爬虫将会给web服务器带来巨大的资源开销
2)法律风险:服务器上的数据有产权归属,获得数据用于牟利将带来法律风险
3)泄露隐私:具备突破简单访问控制的能力,获得被保护数据从而泄露个人隐私
网络爬虫限制
1)来源审查:判断User-Agent进行限制。检查来访HTTP协议头的User-Agent域,只响应浏览器或友好爬虫的访问
2)发布公告:Robots协议。告知所有爬虫,网址的爬取策略,要求爬虫遵守
检查来访HTTP协议头的User-Agent域,只响应浏览器或友好爬虫的访问
2.2 Robots协议
Robots协议(Robots Exclusion Standard):网络爬虫排除标准
作用:告知爬虫哪些页面可以爬取,哪些不行
形式:网址根目录下的robots.txt文件
# 网址https://www.jd.com/robots.txt(京东的Robots协议)
User-agent: * # 表示所有的网络爬虫
Disallow: /?* # 不允许访问以?开头的路径
Disallow: /pop/*.html
Disallow: /pinpai/*.html?*
User-agent: EtaoSpider # 这个爬虫的协议头不允许爬取京东的任何资源
Disallow: /
User-agent: HuihuiSpider
Disallow: /
User-agent: GwdangSpider
Disallow: /
User-agent: WochachaSpider
Disallow: /
# Robots协议基本语法,*代表所有,/代表根目录
User-agent: *
Disallow: /
Robots协议规定,如果一个网址不提robots.txt文件,说明这个网址允许所有爬虫无限制的爬取其内容
目录
Python网络爬虫与信息提取
一、Requests库
二、Beautiful Soup库
三、Re库
四、Scrapy框架
汇总