[python爬虫]requests库 2

解码请求内容

我们以Github的网址再来举例子,我们可以读取服务器下传给我们的内容:

>>> import requests

>>> r = requests.get('https://api.github.com/events')
>>> r.text

u'[{“repository”:{“open_issues”:0,”url”:”https://github.com/…
我们的函数一般会自动解码从服务器上下载的内容,
通过调用r.encoding参数也可以自行更改解码格式:

>>> r.encoding
'utf-8'
>>> r.encoding = 'ISO-8859-1'

当然,我们也可以通过二进制来解码内容:

>>> from PIL import Image
>>> from io import BytesIO

>>> i = Image.open(BytesIO(r.content))

通过json解码也同样可行:

>>> import requests

>>> r = requests.get('https://api.github.com/events')
>>> r.json()
[{u'repository': {u'open_issues': 0, u'url': 'https://github.com/...

这里要注意,我们成功获得json文件并不代表我解码成功,因为一些网站返回给你的可能就是错误的信息

自定义http头字段(headers)

:
我们可以将头字段的一些参数放到一个字典当中,那样再通过get调用就十分便利,那么我们为什么要自定义头字段呢?因为一些网站有反爬虫机制,会禁止默认的用户代理访问,这一点我们可以在网站中的robots.txt文件中看到:

#section 1
User-agent: BadCrawler
Disallow: /[….]

所以往往我们在header中自定义用户代理的话将会绕过这一关卡

>>> url = 'https://api.github.com/some/endpoint'
>>> headers = {'user-agent': 'my-app/0.0.1'}

>>> r = requests.get(url, headers=headers)

但是我们仍然需要注意到我们自定义的头字段在其他如果已经定义了相关内容的时候会被覆盖,同时我们也要注意头字段的格式必须是字符串类型的

更加复杂的POST请求

如果你想要上传一些参与解码的数据,类似于HTML,我们仅仅需要将相应的字典传入data参数就可以了

>>> payload = {'key1': 'value1', 'key2': 'value2'}

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

当我们的一个key对应很多个参数时,我们可以通过tuples的形式传输:

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

返回错误检查

我们可以通过r.status_code来检查我们的请求是否成功,如果成功,那么

>>> r.status_code == requests.codes.ok
True

但是如果返回值4开头或者5开头,那么就说明出问题了,如果是5开头,那么就是服务器端有问题,我们可以通过。raise_for_status()来发现它:

>>> bad_r = requests.get('http://httpbin.org/status/404')
>>> bad_r.status_code
404

>>> bad_r.raise_for_status()
Traceback (most recent call last):
  File "requests/models.py", line 832, in raise_for_status
    raise http_error
requests.exceptions.HTTPError: 404 Client Error

当然,如果没有问题的话,它就会返回None:

>>> r.raise_for_status()
None

查看网站的回应头字段

我们可以查看网站回应的头字段:

>>> r.headers
{
    'content-encoding': 'gzip',
    'transfer-encoding': 'chunked',
    'connection': 'close',
    'server': 'nginx/1.0.4',
    'x-runtime': '148ms',
    'etag': '"e1ca502697e5c9317743dc078f67693f"',
    'content-type': 'application/json'
}

这儿有一点需要注意的是它只能够用于http协议,另外,他模糊大小写,所以通过以下两种方式都可以获得网站的头字段:

>>> r.headers['Content-Type']
'application/json'

>>> r.headers.get('content-type')
'application/json'

Cookies

当我们访问需要用户名密码的网站时,我们时常需要用到Cookies,我们在访问网站时可以把我们自己的用户名密码写到Cookies中,再放到头字段中上传,如此便可通行无阻,但是我们首先要学会如何获得获得Cookies:

>>> url = 'http://example.com/some/cookie/setting/url'
>>> r = requests.get(url)

>>> r.cookies['example_cookie_name']
'example_cookie_value'

我们可以将我们自己的COOKIES上传到服务器中:

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

>>> r = requests.get(url, cookies=cookies)
>>> r.text
'{"cookies": {"cookies_are": "working"}}'

我们也可以通过RequestsCookieJar()来更改相应的Cookie,免得我们上传cookies的时候还要重新写一遍。。。

>>> jar = requests.cookies.RequestsCookieJar()
>>> jar.set('tasty_cookie', 'yum', domain='httpbin.org', path='/cookies')
>>> jar.set('gross_cookie', 'blech', domain='httpbin.org', path='/elsewhere')
>>> url = 'http://httpbin.org/cookies'
>>> r = requests.get(url, cookies=jar)
>>> r.text
'{"cookies": {"tasty_cookie": "yum"}}'

网址重定向

什么是网址重定向?网址重定向(URL redirection,或称网域名称转址或URL重定向),是指当使用者浏览某个网址时,将其导向到另一个网址的技术。
那么遇到这个怎么办,在初始条件下,Requests将会自动追踪,但是HEAD除外,我们可以通过Response.history来看一下网站是否有重定向
你看在下面这个例子中,我们的网址就将 http://github.com 重新定向到 https://github.com/中去了

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

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

>>> r.status_code
200

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

当然我们也可以设置参数来控制允不允许重定向:

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

>>> r.status_code
301

>>> r.history
[]

再比如由于HEAD默认是不允许重定向的,所以我们可以改一下:

>>> r = requests.head('http://github.com', allow_redirects=True)

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

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

设置响应时间

为了防止程序无限制的在没有响应的状态下运行下去,我们应该给它一个响应时间:

>>> requests.get('http://github.com', timeout=0.001)

Leave a Reply

Your email address will not be published. Required fields are marked *