大家好,我是小白菜,从现在开始为大家带来爬虫教程的分享。今天的主题是requests库的学习与使用。觉得写的还不错的朋友们可以点点赞支持,谢谢。
这里在前面补充说明一点,有一个网站,在我们测试代码的时候比较常用,因为这个网站返回的信息可以让我们清楚的意识到自己的爬虫加了什么参数,返回了什么内容。这个网站就是:http://httpbin.org/
以下为个人理解,requests库是第三方库,需要大家自行安装。而requests库相比于python自带的请求库urllib方便了许多,许多复杂的方式都被简化了。好的,下面开始我们的真正的学习。
1>GET请求:
>>> import requests
>>> requests.get('http://www.baidu.com')
# 返回结果: , 200代表请求成功
参数讲解:
get方式有以下几个常用参数:
url : 即网址
headers : 请求头,当我们为了模拟的更像一个真实浏览器时需要指定这个参数
params : 有时候get请求方式需要加入一些参数,比如请求百度搜索时输入的搜索内容就 是待添加的参数。
返回值:
所有的请求都会返回一个对象,我们称之为response,即响应对象。下面对这个对象的常用方法进行讲解:
# 属性一 : 返回请求状态码
response.status_code
# 属性二 : 返回响应的内容,即网页html代码,requests库会采取自己的解码方式去解码
response.text
# 属性三 : 返回响应的内容,以最原始的状态返回
response.content
# 属性四 : 返回cookie
response.cookies
# 属性五 : 返回url
response.url
# 方法一 : 返回json格式的响应内容,如果服务器返回的内容是json格式的话,以这种方式获取的内容更方便处理
response.json()
示例:
不添加headers和params参数:
import requests
#下面的网页是专门用于测试用的,可以方便的查看是否请求成功
response = requests.get('http://httpbin.org/get')
print(response.status_code)
print(response.url)
print(response.content) #这里打印的为butes类型
print(response.text) #这里为str类型
#结果如下:
'''
200
http://httpbin.org/get
b'{\n "args": {}, \n "headers": {\n "Accept": "*/*", \n "Accept-Encoding": "gzip, deflate", \n "Host": "httpbin.org", \n "User-Agent": "python-requests/2.24.0", \n "X-Amzn-Trace-Id": "Root=1-5fb8aa07-5cfe678714dfd2992acd04c1"\n }, \n "origin": "125.33.163.108", \n "url": "http://httpbin.org/get"\n}\n'
{
"args": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.24.0",
"X-Amzn-Trace-Id": "Root=1-5fb8aa07-5cfe678714dfd2992acd04c1"
},
"origin": "125.33.163.108",
"url": "http://httpbin.org/get"
}
'''
添加headers参数于params参数
import requests
response = requests.get('http://httpbin.org/get',params={
'hello':'hi'},headers={
'User-Agent':'hello'})
print(response.text)
'''
{
"args": { #这里是传入的参数
"hello": "hi"
},
"headers": { #这个是headers
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Host": "httpbin.org",
"User-Agent": "hello",
"X-Amzn-Trace-Id": "Root=1-5fb8ab11-52500a56124ac09650847c13"
},
"origin": "125.33.163.108",
"url": "http://httpbin.org/get?hello=hi"
}
'''
2>post请求方式:
post请求方式的使用方法同get,唯一不同之处在于get中增加参数为params,而post中为data,具体的可以体验下面的示例:
不增加任何参数
import requests
response = requests.post('http://httpbin.org/post')
print(response.text)
'''
{
"args": {},
"data": "",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Content-Length": "0",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.24.0",
"X-Amzn-Trace-Id": "Root=1-5fb8ab63-4d86988126bf9052699f81f3"
},
"json": null,
"origin": "125.33.163.108",
"url": "http://httpbin.org/post"
}
'''
增加相应参数:
import requests
response = requests.post('http://httpbin.org/post',headers={
'User-Agent':'hello'},data={
'name':'baicai'})
print(response.text)
'''
{
"args": {},
"data": "",
"files": {},
"form": { #这里为提交的表单
"name": "baicai"
},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Content-Length": "11",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "httpbin.org",
"User-Agent": "hello",
"X-Amzn-Trace-Id": "Root=1-5fb8abae-400b44e547027b991028fbce"
},
"json": null,
"origin": "125.33.163.188",
"url": "http://httpbin.org/post"
}
'''
3>其他请求方式:
requests库还支持其他的请求方式,当然这些请求方式我们一般都不用,需要用的时候查查官方文档即可。毕竟万变不离其宗,掌握 一个方法,其余的方法都是类似的。
requests库还支持文件上传,我们知道向服务器发送一些东西,比如说文件或者密码等,用的是post请求,所以实现文件上传功能,也是使用post请求方式。如下:
import requests
respones = requests.post('http://httpbin.org/post',files={
'file':open('test.txt','rb')})
print(respones.text)
'''
{
"args": {},
"data": "",
"files": {
"file": "sdaf" #这个即为文件的内容
},
"form": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Content-Length": "148",
"Content-Type": "multipart/form-data; boundary=54348eccce4fbb7ba96e38b6d6f28e21",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.24.0",
"X-Amzn-Trace-Id": "Root=1-5fb8aeb8-3f9154804719eee64f6eb218"
},
"json": null,
"origin": "125.33.162.161",
"url": "http://httpbin.org/post"
}
'''
requests库还支持cookie操作。如下:
import requests
response = requests.get('http://www.baidu.com')
print(response.cookies) #返回的是一个cookie对象,可以采用下面的方式获取内容
for key,value in response.cookies.items():
print(key,value)
'''
]>
BDORZ 27315
'''
1>我们有时候遇见一些网站会强制你登录才能去获取数据。此时你知道想要登录网站需要去使用post方式请求,但是当你请求成功后再用get方式去访问网站,你会发现你被拒绝了,这意味着你的get请求是一个新的请求,而不是在post请求成功后以post为基础的请求。如果你无法理解上面的话,你可以这样理解,一个get就是打开一个浏览器,两个浏览器之间是无法通信的,所以你第二次请求相当于打开一个新的浏览器,自然无法获取内容。
2>如何解决上面的问题呢?requests提供了一个会话对象,即session,只要你使用session去访问,就可以连续访问了。示例如下:
#下面给出的是思路,不是具体的代码,具体的代码还是根据实际案例来讲
import requests
#创建session对象
session = requests.session()
#使用session对象去发送post请求
session.post(.....) #这里post的用法和requests.post()用法一致
#请求成功后再用session对象去请求只有登录才能访问的页面
response = session.get(....) #这里post的用法和requests.get()用法一致
#接下来再去操作即可
想必大家观察url,会发现,有的url为http,有的为https,这两者的区别就是https在http的基础上加入了ssl协议,使得信息的传输更加的安全。我们访问一些网站的时候,如果自身电脑爬虫需要检验ssl而导致爬虫失败,这时候就需要在请求的方法里面添加一个verify参数。
如下:(以get方法为例,其他都类似)
import requests
response = requests.get('https://www.baidu.com',verify=False)
print(response.status_code)
当我们需要追求效率时,除了可以采用多任务的方式,还有一个方式就是使用代理。比如我们需要下载图片,为了不被网站检测出我们是爬虫,我们不得不牺牲效率,比如说每爬取一张图片就休息一秒钟,这样的效率显然很低。但是一旦我们一秒钟爬取个几百张图片,非常容易被网站检测出这个用户不是一个人,因为真正的人不可能一秒钟下载几百张图片,于是网站便会短时间封禁我们的ip,导致我们无法继续访问,以至于爬虫失效。
这时我们需要代理,这样我们就可以在爬取的时候使用不同的ip地址了。
方法如下:
#下面的代码只给出了格式,并没有给出具体的实现
import requests
proxies = {
'http/https':'http/https:ip:port',
'http/https':'http/https:ip:port',
'http/https':'http/https:ip:port',
'http/https':'http/https:ip:port'
}
requests.get(url,proxies=proxies)
这里只分析使用requests库去请求,而不解析页面,因为解析页面需要使用xpath或者re或者pyquery或者selenium等等,而这并不是这篇文章的重点。
这张图展示的网页就是我们需要请求的网页,网址为:https://www.qiushibaike.com/text/page/1/
好的,一般来说,我们无论请求什么网站,都需要添加headers参数中最为基本的User-Agent参数,但是这里为了给大家演示,先尝试不添加headers参数能否请求成功。
import requests
def main():
url = 'https://www.qiushibaike.com/text/page/1/'
#使用get方式请求
response = requests.get(url)
if response.status_code == 200:
print(response.text)
else:
print('请求失败')
if __name__ == '__main__':
main()
'''
主要错误信息为:
requests.exceptions.ConnectionError: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))
'''
显然,一个正常的网站对于这种爬虫都是拒绝的,因为过多的爬虫只会给服务器带来压力。因此对于我们不添加任何参数的爬虫,一下就被识别了。现在我们添加最为基本的headers参数,如下:
import requests
def main():
url = 'https://www.qiushibaike.com/text/page/1/'
headers ={
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36'
}
response = requests.get(url,headers=headers)
if response.status_code == 200:
print(response.text)
else:
print('请求失败')![在这里插入图片描述](https://img-blog.csdnimg.cn/20210208123120596.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NjY3NjgzNQ==,size_16,color_FFFFFF,t_70#pic_center)
if __name__ == '__main__':
main()
'''
#主要结果如下:
UnicodeEncodeError: 'gbk' codec can't encode character '\u200b' in position 7201: illegal multibyte sequence
'''
1>这里先说明下,如何寻找headers参数,首先我们打开浏览器(谷歌或者火狐),点击F12或者点击鼠标右键选择检查,得到下图所示:
接下来按下图操作:
2>其次,分析下为什么会代码中的错误:
上面添加了headers参数请求后打印结果时,报错:
UnicodeEncodeError: 'gbk' codec can't encode character '\u200b' in position 7201: illegal multibyte sequence
上面代码的意思是:gbk编码无法输出\u200b这样的编码文字。在上面我说到以text的方式解码的话,requests会自己采取一定的方式解码,但是这样的解码可能并不符合真正的编码格式,或者网页中本来就有一些特殊的编码是无法打印的。因此,当我们遇见这样的错误的时候,我们可以采取content方式输出内容,因为content本身并不会解码,而是将最原始的内容返回给我们。如下:
import requests
def main():
url = 'https://www.qiushibaike.com/text/page/1/'
headers ={
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36'
}
response = requests.get(url,headers=headers)
if response.status_code == 200:
print(response.content)
else:
print('请求失败')
if __name__ == '__main__':
main()
'''
由于长度原因,显示部分结果如下:
b'\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\xe5\xb9\xbd\xe9\xbb\x98\xe7\xac\x91\xe8\xaf\x9d\xe5\xa4\xa7\xe5\x85\xa8_\xe7\x88\x86\xe7\xac\x91\xe7\xac\x91\xe8\xaf\x9d_\xe7\xac\x91\xe7\xa0\xb4\xe4\xbd\xa0\xe7\x9、
'''
这里大家不必担心这些返回内容看不懂,因为我们解析时,对于内容的编码并不是很看重,照样可以处理。当然除了以content方式处理外,还可以替换内容中所有的错误编码,即将无法打印的编码都替换为空格或者其他,替换的方法可以使用replace或者正则。
好的,今天的分享就到此为止了,希望看了这篇文章,你能够写出最为基本的请求代码,并且知道如何获取网页返回的内容,以及遇见编码错误时如何处理(以content输出)。谢谢大家!