python爬虫入门教程之四——Requests库的高级用法 – Python量化投资
0°

python爬虫入门教程之四——Requests库的高级用法

1Headers(定制请求头)

什么是Headers请求头呢?请求头就是访问网页时的各种简单的证明信息,里面包含了很多内容,比如你要获取信息的格式、访问的时间、是否用了代理(使用透明代理时浏览器依旧会发送你的真实IP,只有高匿代理才不会)、浏览器标识(User-Agent)等。

提示:给大家举一个非常直白的例子,浏览器就像是你的专属外卖配送员,各网站就像外卖商家,配送员到商家取餐时,需要提供订单号、我是谁的配送员、要取什么餐等等信息。

这里以chrome浏览器为例,首先F12打开调试模式,然后访问一个网站,将会在NetWork下看到对目标网页的请求信息,如下图:

 

通过设置header可以跳过一些简单的反爬或者防盗链措施。对付防盗链,服务器会识别headers中的referer是不是它自己,如果不是,有的服务器不会响应,所以我们还可以在headers中加入referer

提示:某些网站很有意思,它们会采取关门打狗的方式来反爬。当你一开始爬取数据时,他不会做任何反爬措施,当你窃喜时突然就发现被ban了。那么恭喜你,你触发了反爬。所以,反爬措施一开始就要做的妥当,才能保护好自己的IP

1)一个响应内容的小例子

这里以上海证券交易所为例,比如我要获取整个市场当日的基金成交信息,地址:http://www.sse.com.cn/market/funddata/overview/day/

经过分析,其数据所在网址为http://query.sse.com.cn/marketdata/tradedata/queryTradingByProdTypeData.do?jsonCallBack=jsonpCallback21071&searchDate=&prodType=jj&_=1555408071445

最后的参数_=1555408071445很明显是时间戳,如果需要定时访问时,还是要构造一个url的。

使用time库的time方法即可。

时间戳的长度跟url中有差别,是因为精度问题,只需要乘以1000然后取整即可。

构造好url后,直接访问以下试试:

import requests
import time
timestamp = int(time.time()*1000)
url = 'http://query.sse.com.cn/marketdata/tradedata/queryTradingByProdTypeData.do?jsonCallBack=jsonpCallback21071&searchDate=&prodType=jj&_={}'.format(timestamp)
res = requests.get(url)
html = res.content.decode()
print(html)

得到结果:

jsonpCallback21071({“jsonCallBack”:”jsonpCallback21071″,”success”:”false”,”error”:”系统繁忙…”,”errorType”:”ExceptionInterceptor”})

虽然有一些信息,但明显是出错了。

我们通过浏览器来查看这个链接的请求头到底是什么:

ok,复制过来,构造一个dict类型的header字典,再次访问试试:

import requests
import time

myheaders = {
        'Referer': 'http://www.sse.com.cn/market/funddata/overview/day/', 
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'
             }
timestamp = int(time.time()*1000)
url = 'http://query.sse.com.cn/marketdata/tradedata/queryTradingByProdTypeData.do?jsonCallBack=jsonpCallback21071&searchDate=&prodType=jj&_={}'.format(timestamp)
res = requests.get(url, headers=myheaders)
html = res.content.decode()
print(html)

完全没毛病了:

2Headers各主要字段的解释

Requests Headers中各主要字段的解释如下:

  • User-Agent : 有些服务器或 Proxy 会通过该值来判断是否是浏览器发出的请求
  • Content-Type : 在使用 REST 接口时,服务器会检查该值,用来确定 HTTP Body 中的内容该怎样解析。
  • application/xml XML RPC,如 RESTful/SOAP 调用时使用
  • application/json JSON RPC 调用时使用
  • application/x-www-form-urlencoded 浏览器提交 Web 表单时使用
  • 注意:在使用服务器提供的 RESTful SOAP 服务时, Content-Type 设置错误会导致服务器拒绝服务

3)其他响应方式

二进制响应内容res.content,解码前,是byte格式。

JSON 响应内容Requests 中也有一个内置的 JSON 解码器,助你处理 JSON 数据——res.json()如果 JSON 解码失败, r.json() 就会抛出一个异常。例如,响应内容是 401 (Unauthorized),尝试访问 r.json() 将会抛出 ValueError: No JSON object could be decoded 异常。

原始响应内容在罕见的情况下,你可能想获取来自服务器的原始套接字响应,那么你可以访问 r.raw。 如果你确实想这么干,那请你确保在初始请求中设置了 stream=True

2、构造Url

前文中目标url有很多参数,一方面很不美观,也容易出错,我们完全可以把参数全部摘出来放到一个dict字典中,然后在请求网页数据时将这个字典数据传递给params参数,如下:

pp = {
        'jsonCallBack':'jsonpCallback21071',
        'searchDate':'',
        'prodType':'jj',
        '_':timestamp        
        }
url = 'http://query.sse.com.cn/marketdata/tradedata/queryTradingByProdTypeData.do'
res = requests.get(url, headers=myheaders, params=pp)
html = res.content.decode()

3Timeout(超时设置)

连接超时指的是在你的客户端实现到远端机器端口的连接时(对应的是`connect()`_),Request 会等待的秒数。一个很好的实践方法是把连接超时设为比 3 的倍数略大的一个数值,因为 TCP 数据包重传窗口 (TCP packet retransmission window) 的默认大小是 3。

有时候,我们访问的网页可能挂了、或者网络不稳定,或者网速太差等等原因导致整个程序卡在某个页面上了,这就非常耽误事,毕竟爬虫需要批量抓很多内容的,有些内容我们可以临时放弃并做标记,将所有都爬完后再考虑是否重新爬之前超时的页面。为防止服务器不能及时响应,大部分发至外部服务器的请求都应该带着 timeout 参数。在默认情况下,除非显式指定了 timeout 值,requests 是不会自动进行超时处理的。如果没有 timeout,你的代码可能会挂起若干分钟甚至更长时间。

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

import requests

requests.get(‘http://www.lizenghai.com’, timeout=0.001)

注意

timeout 仅对连接过程有效,与响应体的下载无关。 timeout 并不是整个下载响应的时间限制,而是如果服务器在 timeout 秒内没有应答,将会引发一个异常(更精确地说,是在 timeout 秒内没有从基础套接字上接收到任何字节的数据时)If no timeout is specified explicitly, requests do not time out.

如果远端服务器很慢,你可以让 Request 永远等待,传入一个 None 作为 timeout 值,然后就冲咖啡去吧。

r = requests.get('http://www.lizenghai.com', timeout=None)

 

「点点赞赏,手留余香」

    还没有人赞赏,快来当第一个赞赏的人吧!
6 条回复 A 作者 M 管理员
  1. 怎么分析的数据的来源呀?

    • 具体是指?
      最好具体问题具体分析

    • 就是这个教程里基金成交数据所在的网址是怎么找到的呢

    • Fiddler抓包查找、浏览器开发者工具抓包查找等等。
      后续教程有相关内容。

    • Fiddler抓包查找、浏览器开发者工具抓包查找等等。
      后续教程有相关内容的。可以关注。

    • 嗯嗯感谢!

欢迎您,新朋友,感谢参与互动!欢迎您 {{author}},您在本站有{{commentsCount}}条评论