学习Python还是得跟着老师学习,请参考老师博文
Python 内置了 requests 模块,该模块主要用来发 送 HTTP 请求,requests 模块比 urllib 模块更简洁。requests是使用Apache2 licensed 许可证的HTTP库。Request支持HTTP连接保持和连接池,支持使用cookie保持会话,支持文件上传,支持自动响应内容的编码,支持国际化的URL和POST数据自动编码。在python内置模块的基础上进行了高度的封装,从而使得python进行网络请求时,变得人性化,使用Requests可以轻而易举的完成浏览器可有的任何操作。当然,requests模块国际化,友好。requests会自动实现持久连接keep-alive。
上面写了一大堆,简单总结来说,如下:
从以前学习的,可以知道这个库很容易安装,在Mac下,打开终端,如下:
# 查看已经安装的库
Aion.Liu $ pip list
Package Version
---------- -------
meson 0.63.0
pip 22.2.2
protobuf 4.21.4
pymongo 4.2.0
PyMySQL 1.0.2
pypi 2.1
setuptools 63.2.0
xlrd 2.0.1
xlwt 1.3.0
xmltodict 0.13.0
# 安装requests库
Aion.Liu $ pip install requests
Collecting requests
Using cached requests-2.28.1-py3-none-any.whl (62 kB)
Collecting certifi>=2017.4.17
Downloading certifi-2022.6.15-py3-none-any.whl (160 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 160.2/160.2 kB 360.7 kB/s eta 0:00:00
Collecting idna<4,>=2.5
Downloading idna-3.3-py3-none-any.whl (61 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 61.2/61.2 kB 160.3 kB/s eta 0:00:00
Collecting charset-normalizer<3,>=2
Downloading charset_normalizer-2.1.0-py3-none-any.whl (39 kB)
Collecting urllib3<1.27,>=1.21.1
Downloading urllib3-1.26.11-py2.py3-none-any.whl (139 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 139.9/139.9 kB 69.9 kB/s eta 0:00:00
Installing collected packages: urllib3, idna, charset-normalizer, certifi, requests
Successfully installed certifi-2022.6.15 charset-normalizer-2.1.0 idna-3.3 requests-2.28.1 urllib3-1.26.11
现在,我们已经安装了requests模块,下面开始更详细的了解他。
属性和方法 | 备注 |
---|---|
delete(url, args) | 发送 DELETE 请求到指定 url |
get(url, params, args) | 发送 GET 请求到指定 url |
head(url, args) | 发送 HEAD 请求到指定 url |
patch(url, data, args) | 发送 PATCH 请求到指定 url |
post(url, data, json, args) | 发送 POST 请求到指定 url |
put(url, data, args) | 发送 PUT 请求到指定 url |
request(method, url, args) | 向指定的 url 发送指定的请求方法 |
属性和方法 | 备注 |
---|---|
apparent_encoding | 编码方式 |
close() | 关闭与服务器的连接 |
response.content | 返回响应的内容,字节(byte)为单位的数据 |
response.text | 返回响应的内容,字符串unicode 类型数据 |
response.content.decode | 解决中文乱码,默认utf-8,其他的编码类型gbk、gb2312、asci、iso-8859-1、 |
cookies | 返回一个 CookieJar 对象,包含了从服务器发回的 cookie |
elapsed | 返回一个 timedelta 对象,包含了从发送请求到响应到达之间经过的时间量,可以用于测试响应速度。比如 r.elapsed.microseconds 表示响应到达需要多少微秒。 |
encoding | 解码 r.text 的编码方式 |
headers | 返回响应头,字典格式 |
history | 返回包含请求历史的响应对象列表(url) |
is_permanent_redirect | 如果响应是永久重定向的 url,则返回 True,否则返回 False |
is_redirect | 如果响应被重定向,则返回 True,否则返回 False |
iter_content() | 迭代响应 |
iter_lines() | 迭代响应的行 |
json() | 返回结果的 JSON 对象 (结果需要以 JSON 格式编写的,否则会引发错误) |
links | 返回响应的解析头链接 |
next | 返回重定向链中下一个请求的 PreparedRequest 对象 |
ok | 检查 “status_code” 的值,如果小于400,则返回 True,如果不小于 400,则返回 False |
raise_for_status() | 如果发生错误,方法返回一个 HTTPError 对象 |
reason | 响应状态的描述,比如 “Not Found” 或 “OK” |
request | 返回请求此响应的请求对象 |
status_code | 返回 http 的状态码,比如 404 和 200(200 是 OK,404 是 Not Found) |
url | 返回响应的 URL |
简单实验下,如下:
# 导入库,引入依赖
>>> import requests
>>>
>>> url = "http://www.baidu.com"
>>>
>>> response = requests.get(url)
# 获取请求
>>> print(response)
<Response [200]>
# 请求返回值的类型
>>> print(type(response))
<class 'requests.models.Response'>
# 请求返回值的响应编码
>>> print(response.status_code)
200
# 请求返回值内容类型
>>> print(type(response.text))
<class 'str'>
# 请求返回值的cookies
>>> print(response.cookies)
<RequestsCookieJar[<Cookie BDORZ=27315 for .baidu.com/>]>
# 请求返回值的文本内容
>>> print(response.text)
<!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>
>>>> print(response.content)
b'<!DOCTYPE html>\r\n<!--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>\xe7\x99\xbe\xe5\xba\xa6\xe4\xb8\x80\xe4\xb8\x8b\xef\xbc\x8c\xe4\xbd\xa0\xe5\xb0\xb1\xe7\x9f\xa5\xe9\x81\x93</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=\xe7\x99\xbe\xe5\xba\xa6\xe4\xb8\x80\xe4\xb8\x8b class="bg s_btn"></span> </form> </div> </div> <div id=u1> <a href=http://news.baidu.com name=tj_trnews class=mnav>\xe6\x96\xb0\xe9\x97\xbb</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>\xe5\x9c\xb0\xe5\x9b\xbe</a> <a href=http://v.baidu.com name=tj_trvideo class=mnav>\xe8\xa7\x86\xe9\xa2\x91</a> <a href=http://tieba.baidu.com name=tj_trtieba class=mnav>\xe8\xb4\xb4\xe5\x90\xa7</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>\xe7\x99\xbb\xe5\xbd\x95</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">\xe7\x99\xbb\xe5\xbd\x95</a>\');</script> <a href=//www.baidu.com/more/ name=tj_briicon class=bri style="display: block;">\xe6\x9b\xb4\xe5\xa4\x9a\xe4\xba\xa7\xe5\x93\x81</a> </div> </div> </div> <div id=ftCon> <div id=ftConw> <p id=lh> <a href=http://home.baidu.com>\xe5\x85\xb3\xe4\xba\x8e\xe7\x99\xbe\xe5\xba\xa6</a> <a href=http://ir.baidu.com>About Baidu</a> </p> <p id=cp>©2017 Baidu <a href=http://www.baidu.com/duty/>\xe4\xbd\xbf\xe7\x94\xa8\xe7\x99\xbe\xe5\xba\xa6\xe5\x89\x8d\xe5\xbf\x85\xe8\xaf\xbb</a> <a href=http://jianyi.baidu.com/ class=cp-feedback>\xe6\x84\x8f\xe8\xa7\x81\xe5\x8f\x8d\xe9\xa6\x88</a> \xe4\xba\xacICP\xe8\xaf\x81030173\xe5\x8f\xb7 <img src=//www.baidu.com/img/gs.gif> </p> </div> </div> </div> </body> </html>\r\n'
有些属性没有罗列出来,可以实验性的测试下。
打开百度,然后使用快捷键F12
打开,或者任意一个网页任意处右键打开检查。
可以看到这里的User-Agent
:
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36
headers接收字典类型的参数作为请求头,请求头部字段作为key,字段对应的值作为value。具体的实验代码如下:
>>> import requests
# 目标网址
>>> url = "http://www.baidu.com/"
# 构建请求头字典,最重要的就是User-Agent
# 如果需要其他请求头,就在headers字典中加上
>>> headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36'}
# 发送请求获取响应
>>> response = requests.get(url,headers=headers)
>>> print(response.text)
首先按照老师博文 查看百度的搜索内容。实验图片就不发了,可以按照博文操作一遍就可以。我们想要搜索关键字python
,最终看到的结果差不多。两个搜索url
如下:
第一个URL:https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=python&fenlei=256&rsv_pq=89208a3e00138578&rsv_t=b2celG4Qr%2BQGonWg7J8W9l4SEpOAyY08gnYSr7klPqQ1ykbhQ3%2FYUwVccyfC&rqlang=en&rsv_enter=1&rsv_dl=tb&rsv_sug3=7&rsv_sug1=5&rsv_sug7=101&rsv_sug2=0&rsv_btype=i&prefixsug=python&rsp=5&inputT=1230&rsv_sug4=1817&rsv_sug=1
第二个URL:https://www.baidu.com/s?word=python
>>> import requests
# 目标网址
>>> url = "https://www.baidu.com/s?wd=python"
>>> headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36'}
# 发送请求获取响应
>>> response = requests.get(url,headers=headers)
>>> print(response.text)
params
构造参数字典>>> import requests
# 目标网址
>>> url = "https://www.baidu.com/s?"
>>> headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36'}
# 请求参数是一个字典
>>> kw = {'wd': 'python'}
# 发送请求的时候设置参数字典,获取响应
>>> response = requests.get(url, headers=headers, params=kw)
>>> print(response.text)
首先找到cookie,找到cookie的步骤如下,网络 ==> 名称 ==> 请求标头,找到Cookie,这个便是要找到的值。
题外,我在这里发现一个问题,就是在载荷中,查询字符串参数的hisdata中的fq的值是3,其实前面我请求了2次了,这里可以猜测下,是请求的历史数据或缓存数据,应该从搜索引擎优化这个角度来解析。
实验代码如下:
>>> headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36',
'Cookie': 'PSTM=1652800193; BD_UPN=123253; BIDUPSID=B6DECB8DEA9B7780AD0CAF744C59CD0E; BAIDUID=52BD4BA13A939B8909AF3868433505C8:SL=0:NR=10:FG=1; BD_HOME=1; H_PS_PSSID=36560_36755_36641_37107_36413_36955_36917_36569_36779_37078_37134_37055_26350_22157_37022; BA_HECTOR=2l2k2l2004ak052k84a5qgrs1hfh9bv17; BAIDUID_BFESS=52BD4BA13A939B8909AF3868433505C8:SL=0:NR=10:FG=1; ZFY=yBSQpVTPoIjIZS2wQABxq9vbmOlwhxBgoIv2mTEnodI:C; delPer=0; BD_CK_SAM=1; PSINO=7; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; B64_BOT=1; baikeVisitId=9de7055f-ca35-464f-95a4-28c2e347e2eb; COOKIE_SESSION=99_0_5_5_2_6_0_0_5_5_1_0_198_0_0_0_1660462670_0_1660466598%7C7%230_0_1660466598%7C1; H_PS_645EC=62ebmN0nyfgetgvl2QP%2FN153uwXQAO3OlMRWkXOhpJKCGjt4Ug9FtOTOGzg'
}
背景: 请求很久没有结果,网页一直在Loading,在爬虫中,这个就降低了我们的效率。这个时候我们需要对请求进行强制要求,让请求在特定的时间内返回结果,否则报错。
import requests
# 目标网址
>>> url = "https://www.baidu.com/"
>>> headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36'
}
>>> try:
# 超时设置为10秒
>>> response = requests.get(url, headers=headers, timeout=10)
>>> except:
>>> for i in range(4): # 循环去请求网站
>>> response = requests.get(url, headers=headers, timeout=20)
>>> if response.status_code == 200:
>>> break
>>> html_str = response.text
备注:r = requests.get('url',timeout=1)
#设置秒数超时,仅对于连接有效。
首先看下具体的请求链路图,大体先理解下,根据老师博文整理如下图所示:
实验代码如下:
>>> proxies = {
"http": "http://12.34.5679:9527",
"https": "https://12.34.5679:9527",
……
}
>>> requests.get('url', proxies=proxies)
语法:requests.post(url, data={key: value}, json={key: value}, args)
url
请求 url。data
参数为要发送到指定 url 的字典、元组列表、字节或文件对象。json
参数为要发送到指定 url 的 JSON 对象。args
为其他参数,比如 cookies、headers、verify等。实验代码如下:
# 1、基本POST实例
>>> import requests
>>> payload = {'key1': 'value1', 'key2': 'value2'}
>>> ret =requests.post("http://mobile.weather.com.cn/data/forecast/101010100.html", data=payload)
>>> print(ret.text)
# 2、发送请求头和数据实例
>>> import requests
>>> import json
>>> url = 'http://mobile.weather.com.cn/data/forecast/101010100.html'
>>> payload = {'some': 'data'}
>>> headers = {'content-type': 'application/json'}
>>> ret = requests.post(url, data=json.dumps(payload), headers=headers)
>>> print(ret.text)
>>> print(ret.cookies)
常用的身份认证有很多,今日我打算补充下这个身份认证——基础身份认证(HTTP Basic Auth)。
实验代码:
>>> import requests
>>> from requests.auth import HTTPBasicAuth
>>> r = requests.get('https://httpbin.org/hidden-basic->>> auth/user/passwd', auth=HTTPBasicAuth('user', 'passwd'))
# r = requests.get('https://httpbin.org/hidden-basic-auth/user/passwd', >>> auth=('user', 'passwd')) # 简写
>>> print(r.json())
另一种非常流行的HTTP身份认证形式是摘要式身份认证,Requests对它的支持也是开箱即可用的:
>>> requests.get(URL, auth=HTTPDigestAuth('user', 'pass')