第一讲 Requests库
一、requests库基础
1.requests库中的7种方法、13个控制访问参数、5种属性
requests库中共有7种方法,其余6种方法都是基于request方法封装的,实际只有一种方法。
-
requests库的7种方法:
requests.request() 构造一个请求,支撑以下各方法
requests.request(method, url, **kwargs) # method : 请求方式,对应get/put/post等7种 # url : 拟获取页面的url链接 # **kwargs: 控制访问的参数,共13个
-
request方法的13个访问控制参数
params 字典或字节序列,作为参数增加到url中
>>>kv = {'key1': 'value1', 'key2': 'value2'} >>>r = requests.request('GET', 'http://python123.io/ws', params=kv) >>>print(r.url) http://python123.io/ws?key1=value1&key2=value2
data 字典、字节序列或文件对象,作为Request的内容
kv = {'key1': 'value1', 'key2': 'value2'} r = requests.request('POST', 'http://python123.io/ws', data=kv) body = '主体内容' r = requests.request('POST', 'http://python123.io/ws', data=body)
json JSON格式的数据,作为Request的内容
kv={'k':'v'} r=requests.request('post',url,json=kv)
headers 字典,HTTP定制头,可以模仿身份
hd={'user-agent':'Chrome/10'} r=requests.request('post',url,headers=hd)#模拟Chrome10浏览器
cookies 字典或CookieJar,Request中的cookie
auth 元组,支持HTTP认证功能
files 字典类型,传输文件
timeout 设定超时时间,秒为单位
r=requests.request('GET',url,timeout=30)
proxies 字典类型,设定访问代理服务器,可以增加登录认证,防止爬虫逆追踪
proxy={'https':'https://10.10.10.10:1234','http':'http://10.10.10.10:1234'}#代理商 r=requests.request('GET',url,proxies=proxy)#使用代理服务器访问url
allow_redirects True/False,默认为True,重定向开关
stream True/False,默认为True,获取内容立即下载开关
verify True/False,默认为True,认证SSL证书开关
cert 本地SSL证书路径
requsets.get() 获取页面的主要方法
#get方法如下: requests.get(url,params=None,**kwargs) #url:拟获取页面的url链接 #params:url中的额外参数,字典或者字节流格式 #**kwargs:12个控制访问的参数
requests.head() 获取网页头信息的方法
request.head(url,**kwargs)
代码示例:>>> r = requests.head('http://httpbin.org/get') >>> r.headers {'Content‐Length': '238', 'Access‐Control‐Allow‐Origin': '*', 'Access‐ Control‐Allow‐Credentials': 'true', 'Content‐Type': 'application/json', 'Server': 'nginx', 'Connection': 'keep‐alive', 'Date': 'Sat, 18 Feb 2017 12:07:44 GMT'} >>> r.text ''
requests.post() 向网页提交POST请求的方法
requests.post(url,data=None,**kwargs)
post方法向html提交一个字典,会自动编码为表单form
>>> payload = {'key1': 'value1', 'key2': 'value2'} >>> r = requests.post('http://httpbin.org/post', data = payload) >>> print(r.text) { ... "form": { "key2": "value2", "key1": "value1" }, }
post方法向URL POST一个字符串,会自动编码为data
>>> r = requests.post('http://httpbin.org/post', data = 'ABC') >>> print(r.text) { ... "data": "ABC" "form": {}, }
requests.put() 提交PUT请求,新提交的内容会覆盖掉url对应位置的资源
requests.put(url,data=None,**kwargs)
>>> payload = {'key1': 'value1', 'key2': 'value2'} >>> r = requests.put('http://httpbin.org/put', data = payload) >>> print(r.text) { ... "form": { "key2": "value2", "key1": "value1" }, }
requsets.patch() 提交局部修改请求,只修改url相应部分的资源,比put方法更优
requests.patch(url,data=None,**kwargs)
requsets.delete() 提交删除请求
requests.delete(url,**kwargs)
-
requests库中有两个重要对象,分别是:
- Response (包含爬虫返回的内容),常用5种属性:
- r.status_code HTTP请求的返回状态,200表示连接成功,返回其它数字表示连接失败
- r.text HTTP响应内容的字符串形式,即url所对应的页面内容
- r.encoding 从HTTP header中猜测的响应内容编码方式
- r.apparent_encoding 从内容分析出的响应内容编码方式
- r.content HTTP响应内容的二进制形式
- Request
2.通用代码框架
import requests
def getHTMLText(url):
try:
r = requests.get(url,timeout=30)
r.raise_for_status() #如果状态不是200,则引发HTTPError异常(判断网络连接状态)
r.encoding = r.apparent_encoding
return r.text
except:
return "产生异常"
if _name_=="_main_":
url = "http://www.baidu.com"
print(getHTMLText(url))
'''r.raise_for_status()在方法内部判断r.status_code是否等于200,
不需要增加额外的if语句,该语句便于利用try‐except进行异常处理'''
3.HTTP协议
Hypertext Transfer Protocol,超文本传输协议。是一个基于“请求与响应”模式的、无状态的应用层协议。
HTTP协议采用URL作为定位网络资源的标识,URL格式如下:
http://host[:port][path]
host: 合法的Internet主机域名或IP地址
port: 端口号,缺省端口为80
path: 请求资源的路径
HTTP URL就是互联网上某个资源的位置,HTTP 协议对资源有六种操作,即对应requests库中的六种方法。
4.网络爬虫的限制
方法一:来源审查
方法二:Robots协议
- 在网站的根目录下放置robots.txt文件,规定哪些内容是可以爬取的,哪些是不能够爬取的。
- 类人行为可以不遵循robots协议,但不可用于商用
二、爬虫示例
- 注:大多实例仅供参考代码结构,实际运行需要调整代码
1.京东页面爬取
以爬取京东商场的华为手机销售页面为例
import requests
url = "https://item.jd.com/2967929.html"
try:
r = requests.get(url)
r.raise_for_status #返回值不是200时会返回错误类型
r.encoding = r.apparent_encoding
print(r.text[0:1000])
except:
print("爬取失败")
2.亚马逊商品页面的爬取
爬取亚马逊商城的《极简》图书为例,简单更换头部,改变访问身份
import requests
url = "https://www.amazon.cn/gp/product/B01M8L5Z3Y"
try:
kv = {"user-agent":"Mozilla/5.0"}
r = requests.get(url,headers = kv)
r.raise_for_status
r.encoding = r.apparent_encoding
print(r.text[:1000])
except:
print("爬取失败")
可以通过r.request.headers
来查看向服务器提交的request的头部信息。利用上述代码更换头部之后,将原来表明身份的键值对{'User-Agent': 'python-requests/2.27.1'}
替换成了{'user-agent': 'Mozilla/5.0'}
,使得服务器认为这次访问是浏览器引起的而非爬虫引起的。
#在更换头部之前:
>>>r.request.headers
{'User-Agent': 'python-requests/2.27.1', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'}
#利用键值对kv更换身份之后:
>>>r.request.headers
{'user-agent': 'Mozilla/5.0', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'}
3.百度/360搜索关键词的提交
-
一些搜索引擎提供了关键词提交的接口
百度的关键词接口:
http://www.baidu.com/s?wd=keyword
360的关键词接口:
http://www.so.com/s?q=keyword
-
因此只需要根据我们所需要的关键词,构造一个符合上式的url即可获取相关信息
-
利用
r.request.url
可以获取我们向服务器提交的request中的url是什么 -
利用控制访问参数params来向一个url中增加参数(键值对)
#爬取百度中包含python关键词的页面
import requests
keyword = "python"
try:
kv = {'wd':keyword}
r = requests.get("http://www.baidu.com/s?",params = kv)
print(r.request.url)
r.raise_for_status
print(len(r.text))
except:
print("爬取失败")
4.网络图片的爬取于存储
首先了解交互式操作:
>>>import requests
>>>path = 'D:/Documents/爬取图片1.jpg' #预先设置本地存储地址,并为图片命名
>>>url = 'http://img0.dili360.com/ga/M01/00/39/wKgBzFQ2SWiADcz2AAqcQ20qNd0842.jpg'
>>>r = requests.get(url)
>>>r.status_code
200
>>>with open(path,'wb') as f:
f.write(r.content) #这一步将爬取到的信息写入文件,
#其中f.write()为文件操作,r.content为响应内容的二进制形式
>>>f.close()
比较可靠和稳定的代码:
import requests
import os
url = 'http://img0.dili360.com/ga/M01/00/39/wKgBzFQ2SWiADcz2AAqcQ20qNd0842.jpg'
root = 'D:/Documents/爬取图片的文件夹/'
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)
r.raise_for_status()
with open(path,'wb') as f:
f.write(r.content)
f.close()
print('文件保存成功')
else:
print("文件已存在")
except:
print('爬取失败')
简单修改该代码可以用来爬取其它类型的文件,如:动画,视频……
5.ip归属地的自动查询
有网站提供了ip查询功能:http://m.ip138.com/ip.asp?ip=ipaddress
import requests
ip = '202.204.80.112' #要查询的ip地址
url = 'http://m.ip138.com/ip.asp?ip='#供ip查询的网站的接口
try:
r = requests.get(url+ip)
r.raise_for_status()
r.encoding = r.apparent_encoding
print(r.text[-500:])
except:
print('爬取失败')