1.requests库使用
(1)基本用法
r = requests.get(url)
# 返回一个包含服务器资源的Response对象
# 构造一个像服务器请求资源的Request对象request
r 其实就是请求网页资源返回来的Response类产生的对象r
1.1 response 对象的属性
# 五个属性 r.status_code # HTTP请求返回状态 200表示连接成功 404 表示失败 ## r.status_code 如果返回时200的话 那么可以获取response中的属性,即是下面的属性 r.text r.encoding r.apparent_encoding # 从内容中分析出响应内容的编码方式(备选编码方式) r.content#HTTP响应内容的二进制形式 ## 理解Response 的编码 r.encoding # 从HTTP header 中猜测的响应内容编码方式 r.apparent_encoding # 从内容中分析出的相应内容编码方式 注意:如果header中不存在charset 则认为编码为ISO-8859-1
1.2 基本用法
# 如下: >>> import requests >>> r = requests.get('http://www.baidu.com') >>> print(r.status_code) 200 >>> type(r) <class 'requests.models.Response'> >>> r.headers {'Cache-Control': 'private, no-cache,
no-store, proxy-revalidate, no-transform',
'Connection': 'Keep-Alive', 'Content-Encoding': 'gzip',
'Content-Type': 'text/html', 'Date': 'Fri, 07 Jun 2019 05:33:50 GMT',
'Last-Modified': 'Mon, 23 Jan 2017 13:27:43 GMT', 'Pragma': 'no-cache',
'Server': 'bfe/1.0.8.18', 'Set-Cookie': 'BDORZ=27315; max-age=86400;
domain=.baidu.com; path=/', 'Transfer-Encoding': 'chunked'} >>> r.encoding 'ISO-8859-1' >>> r.apparent_encoding 'utf-8'
小结:requests中的 get方法一般用于获取HtML网页的主要方法 对应HTTP的GET
## requests.get(url,params=None,**kwargs) url:拟获取页面的url链接 params: url中的额外参数 字典或者 字节流格式,可选 **kwargs: 12个控制访问的参数
1.3 requests库中常见的异常
r.raise_for_status() 如果不是200 产生异常 requests.HTTPError
## 理解Requests库的异常
requests.ConnectionError 网诺连接错误异常 如DNS查询失败 拒绝连接等
requests.HTTPError HTTP错误异常
requests.URLRequired URL缺失异常
requests.TooManyRedirects 超过最大重定向次数 产生重定向异常
requests.ConnectTimeout 连接远程服务器超时异常
requests.Timeout 请求URL超时 产生超时异常
1.4 爬虫基本框架带异常
def getHTMLText(url): try: r = requests.get(url,timeout=30) # 如果状态不是200 引发HTTPError异常 r.raise_for_status() r.encoding = r.apparent_encoding return r.text except: return "产生异常" if __name__ == '__main__': url = "http://www.baidu.com" print(getHTMLText(url)) # <!DOCTYPE html> # <!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8> # <meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer> # <link rel=stylesheet type=text/css href=http://s1.bdstatic.com/r/www/cache/bdorz/baidu.min.css> # <title>百度一下,你就知道</title></head> <body link=#0000cc> <div id=wrapper> <div id=head> # <div class=head_wrapper> <div class=s_form> <div class=s_form_wrapper> <div id=lg> # <img hidefocus=true src=//www.baidu.com/img/bd_logo1.png width=270 height=129> # </div> <form id=form name=f action=//www.baidu.com/s class=fm> # <input type=hidden name=bdorz_come value=1> <input type=hidden name=ie value=utf-8> # <input type=hidden name=f value=8> <input type=hidden name=rsv_bp value=1> # <input type=hidden name=rsv_idx value=1> <input type=hidden name=tn value=baidu> # <span class="bg s_ipt_wr"><input id=kw name=wd class=s_ipt value maxlength=255 autocomplete=off autofocus> # </span><span class="bg s_btn_wr"><input type=submit id=su value=百度一下 class="bg s_btn"></span> # </form> </div> </div> <div id=u1> <a href=http://news.baidu.com name=tj_trnews class=mnav>新闻 # </a> <a href=http://www.hao123.com name=tj_trhao123 class=mnav>hao123</a> <a href=http://map.baidu.com name=tj_trmap class=mnav> # 地图</a> <a href=http://v.baidu.com name=tj_trvideo class=mnav>视频</a> # <a href=http://tieba.baidu.com name=tj_trtieba class=mnav>贴吧</a> <noscript> # <a href=http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1 name=tj_login class=lb>登录</a> </noscript> <script>document.write('<a href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u='+ encodeURIComponent(window.location.href+ # (window.location.search === "" ? "?" : "&")+ "bdorz_come=1")+ '" name="tj_login" class="lb">登录</a>');</script> # <a href=//www.baidu.com/more/ name=tj_briicon class=bri style="display: block;">更多产品</a> </div> </div> # </div> <div id=ftCon> <div id=ftConw> <p id=lh> <a href=http://home.baidu.com>关于百度</a> # <a href=http://ir.baidu.com>About Baidu</a> </p> <p id=cp>©2017 Baidu # <a href=http://www.baidu.com/duty/>使用百度前必读</a> <a href=http://jianyi.baidu.com/ class=cp-feedback>意见反馈 # </a> 京ICP证030173号 <img src=//www.baidu.com/img/gs.gif> </p> </div> </div> </div> </body> </html> # 异常的 如果是异常的话就是 "产生异常"
#r.encoding #如果header中不存在charset 则认为编码为ISO-8859-1
#r.apparent_encoding # 从内容中分析出响应内容的编码方式(备选编码方式)
1.5 HTTP协议与Requests库
#Requests 库的7个主要方法
requests.request() #构造一个请求 支撑一下各方法的基础方法,母体方法,由于下面各个基础方法用的比较多,就独立出来了
requests.get() # 获取HtML网页的主要方法 对应HTTP的GET
request.head() # 获取HTML网页的头信息的方法 对应HTTP的HEAD
requests.post() # 获取HTML网页提交POST请求的方法 对应HTTP中的POST
requests.put() #获取HTML网页提交PUT请求的方法 对应HTTP的PUT
requests.patch() # 向HTML网页提交局部修改请求 对应于HTTTP的PATCH
requests.delete() # 向HTML页面提交删除请求 对应于HTTP的DELETE
1.6 HTTP协议中url的格式
# HTTP协议 超文本传输协议 HTTP是一个基于“请求与响应”模式的、无转态的应用层协议。
# URl 格式 htpp://host[:port][:path]
host:合法的Internet主机域名或IP地址
port:端口号,缺省端口为80
path:请求资源的路径
HTTP URL 实例: htpp://www.bit.edu.con htpp://220.181.111.188/duty
HTTP URL的理解:
URL是通过HTTP协议存取资源的Internet路径 一个对应的URL对应一个数据资源
HTTP 协议对资源的操作
GET 请求获取 URL位置的资源
HEAD 请求获取URL位置资源的响应消息报告,即获得该资源的头部信息
POST 请求向URL位置的资源后附加的新的数据
PUT 请求向URL位置存储一个资源,覆盖URL位置的资源
PATCH 请求局部更新URL位置的资源 即改变该处资源的部分内容
DELETE 请求删除URL位置存储的资源
注意:
#HTTP协议对资源的操作 #GET 和HEAD 请求获取URL位置的资源、和获取URL位置资源的头部信息,也就是服务器向客户端发送的数据 # PUT POST PATCH DELETE 相对于URL就行修改操作 理解PATCH 和PUT的区别 假设URL位置有一组数据Userinfo,包括UserID、UserName等20个字段 需求:用户修改了UserName 其他不变 采用PATCH 仅向URL提交UserName的局部更新请求 采用PUT 必须将所有20个字段一并提交到URL未提交字段被删除 PATCH的最主要的好处:节省网络带宽
HTTP协议与Requests库
GET HEAD POST PUT PATCH DELETE 和 Requests库中的方法功能完全一致
requests.get()
requests.head()
requests.post()
requests.put()
requests.patch()
requests.delete()
# 1 head
r = requests.head("http://httpbin.org/get") print(r.headers) #{'Access-Control-Allow-Credentials': 'true', # 'Access-Control-Allow-Origin': '*', # 'Content-Encoding': 'gzip', # 'Content-Type': 'application/json', # 'Date': 'Fri, 07 Jun 2019 07:07:31 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'} # requests.head() >>> r = requests.head('http://www.baidu.com') >>> r.headers
#2 post URL POST 一个字典自动编码为form(表单)
>>> payload = {'key1':'value1','key2':'value2'} # requests.post() # 向URL POST 一个字典自动编码为form(表单) >>> r = requests.post('http://httpbin.org/post',data = payload) >>> r.text # '{\n "args": {}, \n "data": "", \n "files": {}, # \n "form": {\n "key1": "value1", # \n "key2": "value2"\n }, # \n "headers": {\n "Accept": "*/*", # \n "Accept-Encoding": "gzip, deflate", # \n "Content-Length": "23", # \n "Content-Type": "application/x-www-form-urlencoded", # \n "Host": "httpbin.org", # \n "User-Agent": "python-requests/2.22.0"\n }, # \n "json": null, \n "origin": "112.97.63.241, # 112.97.63.241", \n "url": "https://httpbin.org/post"\n} # \n' >>> print(r.text) { "args": {}, "data": "", "files": {}, "form": { "key1": "value1", "key2": "value2" }, "headers": { "Accept": "*/*", "Accept-Encoding": "gzip, deflate", "Content-Length": "23", "Content-Type": "application/x-www-form-urlencoded", "Host": "httpbin.org", "User-Agent": "python-requests/2.22.0" }, "json": null, "origin": "112.97.63.241, 112.97.63.241", "url": "https://httpbin.org/post" }
# 3 POST 一个字符串自动编码为data
>> r = requests.post('http://httpbin.org/post',data = 'ABC') >>> print(r.text) { "args": {}, "data": "ABC", "files": {}, "form": {}, "headers": { "Accept": "*/*", "Accept-Encoding": "gzip, deflate", "Content-Length": "3", "Host": "httpbin.org", "User-Agent": "python-requests/2.22.0" }, "json": null, "origin": "112.97.63.241, 112.97.63.241", "url": "https://httpbin.org/post" }
1.7 requests中的request方法基类
requests.request(method,url,**kwargs)
method: 请求方式,对应get/put/post等7种
url:拟获取页面的url链接
**kwargs: 控制访问的参数共13个
requests.request(method,url,**kwargs)
method:请求方式
r = requests.request('GET',url,**kwargs)
r = requests.request('HEAD',url,**kwargs)
r = requests.request('POST',url,**kwargs)
r = requests.request('PATCH',url,**kwargs)
r = requests.request('PUT',url,**kwargs)
r = requests.request('delete',url,**kwargs)
r = requests.request('OPTIONS',url,**kwargs)
r = requests.request('GET',url,**kwargs)
r = requests.request('HEAD',url,**kwargs)
r = requests.request('POST',url,**kwargs)
r = requests.request('PATCH',url,**kwargs)
r = requests.request('PUT',url,**kwargs)
r = requests.request('delete',url,**kwargs)
r = requests.request('OPTIONS',url,**kwargs)
#1 requests.get()
>>> kv = {'key1':'value1','key2':'value2'} # params: 字典或字节序列,作为参数增加到url中 >>> r = requests.request('GET','http://python123.io/ws', params=kv) >>> print(r.url) https://python123.io/ws?key1=value1&key2=value2 requests.request(method,url,**kwargs) **kwargs: 控制访问的参数 均为可选项
#2 post方法
# (2) **kwargs 控制访问参数 均为可选项 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)
#(2)json:JSON格式的数据 作为Request的内容 >>> kv = {'key1': 'value1'} >>> r = requests.request('POST','http://python123.io/wss',json=kv)
#(4) requests.request(method,url,**kwargs) **kwargs: 控制访问的是参数 均为可选项 headers: 字典 HTTP定制头 #(5) requests.request(method,url,**kwargs) **kwargs: 控制访问的是参数 均为可选项 headers: 字典 HTTP定制头 >>> hd = {'user-agent':'Chrome/10'} >>> r = requests.request('POST','http://python123.io/ws',headers=hd) #(6) requests.request(method,url,**kwargs) **kwargs: 控制访问的参数 均为可选项 cookies: 字典或者CookieJar,Request中的cookie auth: 元祖 支持HTTP认证功能 requests.request(method,utr,**kwargs) **kwatgs: 控制访问的参数,均为可选项 files: 字典类型 传输文件 >>> fs = {'file':open('data.xls','rb')} >>> r = requests.request('POST','http://python123.io/ws',files=fs) # (7) requests.request(method,url,**kwargs) **kwargs:控制访问的参数 均为可选项 timeout: 设置超时时间 秒为单位 r = requests.request('GET','http://www.baidu.com',timeout=10) # (8) requests.request(method,url,**kwargs) **kwargs:控制访问的参数 均为可选项 proxies:字典类型 设置访问代码服务器 可以增加登录认证 pxs = {'http': 'http://user:pass@10.10.10.1:1234', 'http':'https://10.10.10.1.4321'} r = requests.request('GET','http://www.baidu.com',proxies=pxs) # (9) requests.request(method,url,**kwargs) **kwargs:控制访问的参数,均为可选项 allow_redirects: True/False 默认为True 重定性开关 stream:True/False 默认为True 获取内容立即下载开关 verify:True/False 默认为True 认证SSL证书开关 cert:本地SSL证书路径
1.8 requests中的方法
requests.request(method,url,**kwargs)
**kwargs:控制访问的参数 均为可选项
params cookies proxies
data auth allow_redirects
json files stream
headers timeout verify
1.8 requests.get/post/patch/...中的方法
1 requests.get(url,params=None,**kwargs) url:拟获取页面的url链接 params:url中的额外参数 字典或者字节流格式 可选 **kwargs 12个控制访问的参数 #2 requests.post(url,params=None,json=None,**kwargs) url:拟获取页面的url链接 params:url中的额外参数 字典或者字节流格式 可选 json:JSON格式的数据 Request的内容 **kwargs 11个控制访问的参数 #3 requests.put(url,data=None,**kwargs) url:拟获取页面的url链接 data:字典 字节序列或文件 Request的内容 **kwargs 12个控制访问的参数 #4 requests.patch(url,data=None,**kwargs) url:拟更新页面的url链接 data:字典 字节序列或文件 Request的内容 **kwargs 12个控制访问的参数 #5 requests.delete(url,**kwargs) url:拟删除页面的url链接 **kwargs:13控制访问的参数 #6 requests.head(url,**kwargs) Requests库入门
1.9 带超时的框架
try: r = requests.get(url,timeout=30) r.raise_for_status() r.encoding=r.apparent_encoding return r.text except: return "产生异常"
1.10 robots协议
## 网络爬虫的尺寸
# 小规模 数据量小爬取数据 不敏感 Requests库 爬取网页 玩转网页
# 中规模 数据规模较大 爬取速度敏感 Scrapy库 爬取网站 爬取系列网站
# 大规模 搜索引擎 爬取速度关键 爬取全网
# 网络爬虫的限制
# 来源审查: 判断User-Agent就行限制
检查 来访HTTP协议头的User-Agent域 只想响应浏览器或友好爬虫的访问
发布公告:Robbots协议
# 告知所有爬虫网站的爬取策略 要求爬虫遵守
发布公告:Robbots协议
Robots Exclusion Standard 网络爬虫排除标准
作用:网站告知网络爬虫哪些页面可以抓取 哪些不行
形式:在网站根目录下的robots.txt文件
案列:京东的Robots协议
http://www.jd.com/robots.txt
Robots协议基本语法
# 注释 *代表所有 /代表根目录
User-agent: *
Disallow: /
http://www.baidu.com/robots.txt
http://news.sina.com.cn/robots.txt
http://qq.com/robots.txt
http://www.moe.edu.cn/robots.txt(无robots协议)
Robots协议的使用
网诺爬虫:自动或人工识别robots.txt 再就行内容爬取
约束性:Robots协议是建议但非约束性 网络爬虫可以不遵守 但存在法律风险
爬取全网:必须遵守
1.11 5个爬取案列
实例1:京东商品页面的爬取
实例2:亚马孙商品页面的爬取
实例3:百度/360搜索关键字提交
实例4:网络图片的爬取和存储
实例5:IP地址归属地的自动查询
#1
# 京东商品案例爬取 import requests url = "http://item.jd.com/2967929.html" try: r = requests.get(url) r.raise_for_status r.encoding = r.apparent_encoding print(r.text[:1000]) except: print("爬取失败")
#2
## 爬取亚马逊的书 import requests url = http://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:2000]) except: print("爬取失败")
#3
# 百度360提交 搜索引擎关键词提交接口 百度的关键词接口 http://www.baidu.com/s?wd=keyword 360的关键字接口: http://www.baidu.so.com/s?q=keyword 百度搜索全代码: 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("爬取失败") # http://www.baidu.com/s?wd=python # 420650 # 360 搜索全代码 import requests keyword = "python" try: kv = {'k':keyword} r = requests.get('http://www.so.com/s',params=kv) print(r.request.url) r.raise_for_status() print(len(r.text)) print(r.text[::]) except: print('爬取失败')
#4
# 提取图片 网络图片的爬取 网络图片的链接的格式 http://www.example.com/picture.jpg 国家地理 http://www.nationalgeographic.com.cn/ 选择一个图片web也米娜 http://www.nationalgeographic.com.cn/photography/photo_of_the_day/3921.html import requests import os url = "http://image.nationalgeographic.com.cn/2017/0211/201711061910157.jpg" root = "D://pics//" 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) f.close() print('文件保存成功') else: print("文件已存在") except: print("爬取失败")
# 5
# 实例5 ip地址的实例查询 import requests url = "http://m.ip138.com/ip.asp?=" r = requests.get(url + '202.204.80.112') r.status_code # 代码 import requests url = "http://m.ip138.com/ip.asp?ip=" try: r = reqeusts.get(url+"202.204.80.112") r.raise_for_status() r.encoding = r.apparent_encoding print(r.text[-500]) except: print("爬取失败")