文章目录
前言
Python的强大之处除了简单还在于其提供了功能齐全、种类丰富的类库。如最基础的HTTP库Urllib、requests等。
一、Urllib库介绍
Urlib库他是Python内置的HTTP请求库,它包含如下四个模块:
- request:最基本的HTTP请求模块,用来模拟发送请求。同时它还带有处理授权验证、重定向、cookies等能力
- error:异常处理模块
- parse:提供了许多对URL处理的方法。如拆分
- robotparser:主要来识别网站的robots.txt文件
request部分
函数部分
1.urllib.request.urlopen(url,data=None,[timeout,],cafie=None,capath=None,context=None)
参数介绍:
url:略
data:可选参数,需要使用该参数时,一定要将数据转化为bytes类型。这里还要值得一提的是bytes()只支持对str进行转换。如果你的数据是字典形式而不是字符串形式【“hello=word”】需要将其转换成字符串形式,可以考虑用urllib.parse.urlencode(dict)函数进行转换。
timeout:设置超时时间单位为s,超时返回URLError。
其他参数:略,没什么用,用处很少。cafie=None,capath=None分别指定CA证书和它的路径。
2.
示例:
import urllib.request
import urllib.parse
from urllib.error import URLError
data1=bytes("hello=word",encoding="utf-8")
print(data1)
try:
response = urllib.request.urlopen("http://httpbin.org/post", data=data1,timeout=0.1)
print(response.read())
except URLError as e:
print(e)
说明:
- 注意导入模块方式。
错误的行为: 导入import urllib 然后在使用函数时urllib.request.urlopen。
正确行为: 导入import urllib.request - response返回的对象具有status属性返回状态码和read()方法。
- response.read()返回的是bytes类型。在使用他是需要值得注意的
Request类
urlopen该方法不仅仅通过参数发送请求,还能通过Request对象发送请求。做法是将需要将需要的参数封装在Request类中。然后通过urlopen(Request对象)的方式发送出去。这样做的好处:urlopen只能发送最基本的请求。无法构建完整的请求。使用Request类可以帮助构建。
urllib.request.Request(data=None, headers={ },
origin_req_host=None, unverifiable=False, method=None)
参数介绍:
headers:请求头字典
origin_req_host:请求方的host名称或IP地址
unverifiable:略,很少用到
method:请求方法,如幂等的get方法。
示例
import urllib.request
import urllib.parse
url='http://httpbin.org/post'
headers={
'User-Agent':"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 Edg/91.0.864.67"
,'Host':'httpbin.org'
}
dict_={
'name':'canglaoshi'
}
data=bytes(urllib.parse.urlencode(dict_),encoding='utf-8')#encoding参数不能少
req=urllib.request.Request(url=url,data=data,headers=headers,method='POST')
response = urllib.request.urlopen(req,timeout=1)
print(response.read().decode("utf-8"))
'''
{
"args": {},
"data": "",
"files": {},
"form": {
"name": "canglaoshi"
},
"headers": {
"Accept-Encoding": "identity",
"Content-Length": "15",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "httpbin.org",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 Edg/91.0.864.67",
"X-Amzn-Trace-Id": "Root=1-60f13813-44c50ab14d0e6cdb0be9c906"
},
"json": null,
"origin": "220.177.100.106",
"url": "http://httpbin.org/post"
}
'''
Handler
上面Request类依然无法解决cookie、代理等问题。工具Handler可以帮我们解决。
大致用法:
1. 将参数填入对应需求的Handler类中。
2.将此对象传入build_opener()构建Opener
3.调用其Opener的open(url)发送请求。
Handler类型:
ProxyHandler:用于设置代理参数是字典,键名是协议类型
HTTPPasswoedMgr用于管理密码
HTTPBasicAuthHandler:用于管理认证
HTTPCookieProcessor:cookies
from urllib.request import
HTTPBasicAuthHandler,HTTPPasswordMgrWithDefaultRealm,build_opener
from urllib.error import URLError
username='username'
password='password'
url='http://localhost:5000/'
p=HTTPPasswordMgrWithDefaultRealm()
p.add_password(None,url,username,password)
auth_handler=HTTPBasicAuthHandler(p)
opener=build_opener(auth_handler)
try:
response=opener.open(url)
html=response.read().encode('utf-8')
print(html)
except URLError as e:
print(e.reason)
error异常处理部分
URLError:url错误如打开不存在的网页。具有属性reason返回错误原因
HTTPError:URLError的子类处理HTTP请求错误,如认证请求失败。属性code返回状态码、reason返回错误原因、headers返回请求头。
parse解析链接部分
它定义了处理URL的标准接口,如实现URL的各部分抽取、合并以转换。
函数
- urlparse(url)实现对URL的识别和分段,返回一个ParseResult对象,包含六部分协议、域名、访问路径、参数及?后面的查询条件。
from urllib.parse import urlparse
result=urlparse("https:www.baidu.com//index.html;user?id=5")
print(result)#ParseResult(scheme='https', netloc='', path='www.baidu.com//index.html', params='user', query='id=5', fragment='')
- urlunparse(list)与1对应。参数序列必须为六个元素
- urlsplit()与1类似,结果将访问路径与参数和并。
- urlunsplit与3对应。
- urljoin(base_url,new_url)解析base_url的协议、域名、访问路径,为new_url缺少部分做补充
- urlencode:将字典元素构造成“key=value”的形式。
Robots协议部分
Robots也被称作爬虫协议、机器人协议。告诉爬虫和搜索引擎那些页面可以爬取。它通常是一个robots.txt的文件。
其用法使用:略
Requests库
urllib的用法很不方便,为了更加方便地操作可以使用requests库。
方法
1.requests.get (url, data=None, headers={ },proxies,
[,timeout])注意这里data不需要转换bytes类型,字典就可以。
其返回对象具有status_code、headers、cookies、url、history请求历史、text 、content等属性但值得注意地是两个属性text 、content 属性,
二者都是获得返回对象内容,前者为文本后者为bytes。[cookies写在headers中],注:这里并没有包含全部参数。
2.与之类似地还有post方法
3.requests对象还内置状态码查询对象request.codes。具体使用request.codes.ok==200.
示例:获取博客园图标
import requests
r=requests.get('https://www.cnblogs.com/images/logo.svg?v=R9M0WmLAIPVydmdzE2keuvnjl-bPR7_35oHqtiBzGsM')
with open("bokeyuan.svg", "wb") as f:
f.write(r.content)
使用示例
文件上传
import requests
files={"file":open('bokeyuan.svg','rb')}
r=requests.post('http://httpbin.org/post',files=files)
身份验证
import requests
r=requests.get("xxxx",auth=('username','password'))
Prepared [prɪˈpeəd] requests
from requests import Request,session
url='http://httpbin.org/post'
data={"name":"alex"}
headers={
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 Edg/91.0.864.67",
}
s=session()
req=Request('POST',url,data=data,headers=headers)
prepped=s.prepare_request(req)
r=s.send(prepped)
print(r.text)
正则
在线正则表达式测试 (oschina.net)匹配工具,但不建议常用。
Xpath解析库
字符串的匹配可以用正则,虽然网页也属于字符串,但是如果想要提取其中信息是很不容易的。而使用解析库则能很好的解决这个问题。解析库有Xpath、Beautiful Soup 、pyqurey
Xpath的选择功能非常强大,它提供了简洁明了的路径选择表达式。其表达式、函数可以匹配出所有节点。
Xpath的使用步骤
1.构造Xpath解析对象:
(1)导入lxml库的etree模块,然后声明一段HTML文本,
调用HTML类进行初始化【etree.HTML(html文本)】,
如果HTML文本不完整需要补全etree.tostring(html类)。
(2)直接读取文件etree.parse(htmlfilepath,etree.HTMLPareser())来构造解析对象。
2.解析对象.xpath(表达式)
示例
text='''<ul>
<li><a>this is a</a></li>
<li class='li2'></li>
</ul>'''
from lxml import etree
html=etree.HTML(text)
# result=etree.tostring(html)
s=html.xpath("//ul//a/text()")
print(s[0])# this is a
Xpath的常用规则
nodename 选取此节点的所有子节点
/ 从当前节点选取直接子节点
// 从当前子节点选取后代节点
@ 选取属性
text() 获取文本
* 匹配所有节点
.. 或者parent:: 父节点
对于规则的一些说明与示例:
关于写表达式时,一定要注意书写表达式和html文本结构是否匹配。如获得ul标签下的a标签。//ul/a是无法匹配到a标签的因为ul下的标签是li标签。
属性匹配:使用标签的属性进行匹配[@属性名=条件]如匹配ul下的满足class属性为classa的a标签。//ul//a[@class=’classa’]。但是如果满足classa条件的a标签class属性值不止一个如<a class=”classa classb”></a>。机会发现无法匹配到满足classa条件的a标签了,此时可以用[contains(@class,’classa’) )]。其实[ ]中还支持and or等运算符
获取属性:@属性
按序选择:[num]第num个、[last()]最后一个、[position()<num]位置小于num。使用:匹配最后一个li。//li[2]或者//li[last()]
知识补充
html属性
HTML 标签可以拥有属性。属性提供了有关 HTML 元素的更多的信息。
属性总是以名称/值对的形式出现,比如:name=“value”。
属性总是在 HTML 元素的开始标签中规定。
http://httpbin.org/xx是什么网站
Httpbin是一个免费提供HTTP请求和响应的测试网站。