请求网页和解析HTML是爬虫两大最基础的步骤,requests和BeautifulSoup则分别是这两个步骤中最常用的Python模块。
爬虫必经之路!必备技能!
本文记录一些自己学习requests模块的心得和Notes,欢迎讨论!骚扰!指教!收藏!一键三连!
什么是Requests库?
Requests是一个Python HTTP库,在Apache许可证2.0下发行。这个项目的目标是使得HTTP请求更加简单和更对常人友好。Requests是没有包含在Python内的最流行的Python库,它曾经被提议缺省的随Python一起发行。主要用于实现我们爬虫的第一大基础步骤,网络请求。当然,他的诞生主要是因为Python自带的urllib2实在太难用了。
如果你还没有在你的机器上安装这个模块的话,请立刻马上!
- 通过pip安装
pip install requests
- 下载代码后安装:
$ git clone git://github.com/kennethreitz/requests.git
$ cd requests
$ python setup.py install
Example
先上hello world有一个直观感受:
import requests
r = requests.get(url='http://www.google.com') # 最基本的get请求
print(r.status_code) # 获取返回状态
r = requests.get(url='http://dict.baidu.com/s', params={'wd':'python'}) #带参数的get请求
print(r.url) #打印url
print(r.text) #打印html数据
下面开始:
发送请求
使用 Requests 发送网络请求非常简单。
- 一开始要导入 Requests 模块:
import requests
- 常用案例:尝试获取某个网页:
r = requests.get('https://www.github.com')
现在,我们有一个名为 r 的 Response 对象。我们可以从这个对象中获取所有我们想要的信息。后续的爬虫操作都是基于这个对象来进行。
- 其实Requests 所有的功能都可以通过以下 7 个方法访问。它们全部都会返回一个 Response 对象的实例。
>> requests.request(method, url, **kwargs)
>> requests.head(url, **kwargs)
>> requests.get(url, params=None, **kwargs)
>> requests.post(url, data=None, json=None, **kwargs)
>> requests.put(url, data=None, **kwargs)
>> requests.patch(url, data=None, **kwargs)
>> requests.delete(url, **kwargs)
传递 URL 参数
如果你是手工构建 URL,那么数据会以键值对的形式置于 URL 中,跟在一个问号的后面。例如, https://google.com/get?key=val。 Requests 允许你使用 params 关键字参数,以一个字符串字典来提供这些参数。举例来说,如果你想传递 key1=value1 和 key2=value2 到 https://google.com/get ,那么你可以使用如下代码:
>>> payload = {'key1': 'value1', 'key2': 'value2'}
>>> r = requests.get("https://google.com/get ", params=payload)
>>> print(r.url)
https://google.com/get?key2=value2&key1=value1
定制请求头
如果你想为请求添加 HTTP头部,只要简单地传递一个 dict 给 headers 参数就可以了。例如:
url = 'https://api.github.com/some/endpoint'
headers = {'user-agent': 'my-app/0.0.1'}
r = requests.get(url, headers=headers)
[Tips]: 所有的 header 值必须是 string、bytestring 或者 unicode。尽管传递 unicode header 也是允许的,但不建议这样做。
Get回来的内容
主要有以下几种,最常见的还是text的文本格式
r = requests.get('https://api.github.com/events')
r.text #文本格式
r.content #二进制
r.json() #内置的JSON解码器,助你处理JSON数据, 如果解码失败会抛出一个异常
超时
你可以告诉 requests 在经过以 timeout 参数设定的秒数时间之后停止等待响应。基本上所有的生产代码都应该使用这一参数。如果不使用,你的程序可能会永远失去响应:
requests.get('http://github.com', timeout=0.1)
[Tips]: timeout 仅对连接过程有效,与响应体的下载无关。 timeout 并不是整个下载响应的时间限制,而是如果服务器在 timeout 秒内没有应答,将会引发一个异常(更精确地说,是在 timeout 秒内没有从基础套接字上接收到任何字节的数据时)
错误与异常
- 遇到网络问题(如:DNS 查询失败、拒绝连接等)时,Requests 会抛出一个 ConnectionError 异常。
- 如果 HTTP 请求返回了不成功的状态码, Response.raise_for_status() 会抛出一个 HTTPError 异常。
- 若请求超时,则抛出一个 Timeout 异常。
- 若请求超过了设定的最大重定向次数,则会抛出一个 TooManyRedirects 异常。
- 所有Requests显式抛出的异常都继承自 requests.exceptions.RequestException 。
显然我们通常都需要对异常进行处理,否则程序经常会由于一些网页访问的错误而卡死。最常用的对访问异常写法如下:
try:
r.raise_for_status()
except Exception as exc:
print('There was a problem need to be solved: %s' % (exc))