爬虫基础库之Requests模块

发送GET请求

直接请求

import requests
response=requests.get("https://movie.douban.com/top250")
print(response.text)

发送参数  

你也许经常想为 URL 的查询字符串(query string)传递某种数据。如果你是手工构建 URL,那么数据会以键/值对的形式置于 URL 中,跟在一个问号的后面。

import requests
r = requests.get('https://www.baidu.com/s?wd=%E8%80%81%E7%94%B7%E5%AD%A9',
                 headers={
                     "User-Agent":"..."
                 } )


print(r.text)

Requests 允许你使用 params 关键字参数,以一个字符串字典来提供这些参数。

import requests
r = requests.get('https://www.baidu.com/s',params={"wd":"老男孩"},

                 headers={
                     "User-Agent":"..."
                 }

                 )

响应Response

import requests
respone=requests.get('https://github.com')
# respone属性

print(respone.text) print(respone.content) print(respone.status_code) print(respone.headers) print(respone.cookies) print(respone.cookies.get_dict()) print(respone.cookies.items()) print(respone.url) print(respone.history) print(respone.encoding)

定制请求头

如果你想为请求添加 HTTP 头部,只要简单地传递一个 dict 给 headers 参数就可以了。

#通常我们在发送请求时都需要带上请求头,请求头是将自身伪装成浏览器的关键,常见的有用的请求头如下
Host
Referer #大型网站通常都会根据该参数判断请求的来源
User-Agent #客户端
Cookie #Cookie信息虽然包含在请求头里,但requests模块有单独的参数来处理他,headers={}内就不要放它了
#添加headers(浏览器会识别请求头,不加可能会被拒绝访问,比如访问https://www.zhihu.com/explore)
import requests
response=requests.get('https://www.zhihu.com/explore')
print(response.status_code) #500


#自己定制headers
headers={
    'User-Agent':'......',

}
respone=requests.get('https://www.zhihu.com/explore',
                     headers=headers)
print(respone.status_code) #200

设置cookies

要想发送你的cookies到服务器,可以使用 cookies 参数:

import requests

url = 'http://httpbin.org/cookies'
cookies = dict(cookies_are='working on')

r = requests.get(url, cookies=cookies)
print(r.text)

重定向与请求历史

默认情况下,除了 HEAD, Requests 会自动处理所有重定向。可以使用响应对象的 history 方法来追踪重定向。

Response.history 是一个 Response 对象的列表,为了完成请求而创建了这些对象。这个对象列表按照从最老到最近的请求进行排序。

>>> r = requests.get('http://github.com')

>>> r.url
'https://github.com/'

>>> r.status_code
200

>>> r.history
[<Response [301]>]

另外,还可以通过 allow_redirects 参数禁用重定向处理:

>>> r = requests.get('http://github.com', allow_redirects=False)
>>> r.status_code
301
>>> r.history
[]

超时

你可以告诉 requests 在经过以 timeout 参数设定的秒数时间之后停止等待响应。基本上所有的生产代码都应该使用这一参数。如果不使用,你的程序可能会永远失去响应:

requests.get('http://github.com', timeout=0.001)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
requests.exceptions.Timeout: HTTPConnectionPool(host='github.com', port=80): Request timed out. (timeout=0.001) 
注意
timeout 仅对连接过程有效,与响应体的下载无关。 timeout 并不是整个下载响应的时间限制,而是如果服务器在 timeout 秒内没有应答,
将会引发一个异常(更精确地说,是在 timeout 秒内没有从基础套接字上接收到任何字节的数据时)
If no timeout
is specified explicitly, requests do not time out.

错误与异常

'''

遇到网络问题(如:DNS 查询失败、拒绝连接等)时,Requests 会抛出一个 ConnectionError 异常。

如果 HTTP 请求返回了不成功的状态码, Response.raise_for_status() 会抛出一个 HTTPError 异常。

若请求超时,则抛出一个 Timeout 异常。

若请求超过了设定的最大重定向次数,则会抛出一个 TooManyRedirects 异常。

所有Requests显式抛出的异常都继承自 requests.exceptions.RequestException 。


'''

发送POST请求

通常,你想要发送一些编码为表单形式的数据——非常像一个 HTML 表单。要实现这个,只需简单地传递一个字典给 data 参数。

你的数据字典在发出请求时会自动编码为表单形式:

payload = {'key1': 'value1', 'key2': 'value2'}
response = requests.post("http://httpbin.org/post", data=payload)

print(response.text)

你还可以为 data 参数传入一个元组列表。在表单中多个元素使用同一 key 的时候,这种方式尤其有效:

>>> payload = (('key1', 'value1'), ('key1', 'value2'))
>>> r = requests.post('http://httpbin.org/post', data=payload)
>>> print(r.text)
{
  ...
  "form": {
    "key1": [
      "value1",
      "value2"
    ]
  },
  ...
}

很多时候你想要发送的数据并非编码为表单形式的。如果你传递一个 string 而不是一个 dict,那么数据会被直接发布出去。

例如,Github API v3 接受编码为 JSON 的 POST/PATCH 数据:

>>> import json

>>> url = 'https://api.github.com/some/endpoint'
>>> payload = {'some': 'data'}

>>> r = requests.post(url, data=json.dumps(payload))

此处除了可以自行对 dict 进行编码,你还可以使用 json 参数直接传递,然后它就会被自动编码。这是 2.4.2 版的新加功能:

>>> url = 'https://api.github.com/some/endpoint'
>>> payload = {'some': 'data'}

>>> r = requests.post(url, json=payload)

 提到json数据,如果响应的数据是json数据,直接可以如下解析:

import requests
response=requests.get('http://httpbin.org/get')

res=response.json() #不需要 json.loads(response.text)

post请求其他设置参照get请求。

应用

模拟GitHub登录:

 

import requests
import re

#请求1:
r1=requests.get('https://github.com/login')
r1_cookie=r1.cookies.get_dict() #拿到初始cookie(未被授权)
authenticity_token=re.findall(r'name="authenticity_token".*?value="(.*?)"',r1.text)[0] #从页面中拿到CSRF TOKEN
print("authenticity_token",authenticity_token)
#第二次请求:带着初始cookie和TOKEN发送POST请求给登录页面,带上账号密码
data={
    'commit':'Sign in',
    'utf8':'',
    'authenticity_token':authenticity_token,
    'login':'yuanchenqi0316@163.com',
    'password':'yuanchenqi0316'
}

#请求2:
r2=requests.post('https://github.com/session',
             data=data,
             cookies=r1_cookie,
             # allow_redirects=False
             )
print(r2.status_code)      #200
print(r2.url)              #看到的是跳转后的页面:https://github.com/
print(r2.history)          #看到的是跳转前的response:[<Response [302]>]
print(r2.history[0].text)  #看到的是跳转前的response.text

with open("y.html","wb") as f:

    f.write(r2.content)

 

 

 

 

 

posted @ 2017-12-04 20:18  Yuan先生  阅读(761)  评论(1编辑  收藏  举报