甄嬛传rmvb下载,崔胜景,美元指数走势
因特网联系的是世界各地的计算机(通过电缆),万维网联系的是网上的各种各样资源(通过文本超链接),如静态的html文件,动态的软件程序······。由于万维网的存在,处于因特网中的每台计算机可以很方便地进行消息交流、文件资源交流······。基于因特网的帮助,我们可以在web客户端(如浏览器等)通过http访问或者下载web服务端(如网站服务器)上面的web资源。
因特网由tcp/ip统筹,在tcp/ip的基础上进行http活动。http位于tcp/ip的应用层。了解http是为了让爬虫程序模拟客户端的行为去请求服务器数据和反爬虫。
通过在开发者工具里查看分析网页客户端(浏览器)http的请求报文,获得网页http的请求url、请求方法、请求头、cookie······,爬虫程序可以完备的模拟浏览器去爬取网站的资源;通过查看分析服务器(网站)返回的http响应报文,了解响应状态,响应主体······,爬虫程序就可以根据这些响应内容去实现程序逻辑、处理响应内容、提取目标信息······
通常我们说的网址就是一个url,url是uri的一个子集,urn也是uri的一个子集,url和urn存在交集,大概率的情况都是uri=url,关系如下:
当我们在web客户端浏览器输入网址(url)的时候,如果网址无误,通过http就能得到web服务端的响应。url语法如下:
了解这些是有用的,其中的一个用途就是在爬虫中构建自己的url请求参数。例如书上所说的如果要爬取作者新的浪微博,由于微博是是ajax的方式加载,需要在开发者工具才能看到ajax请求和服务器的响应,所以请求url需要在开发者工具里查找,经过查找分析,发现xhr(可以查看ajax的请求和响应信息)中的请求url传入了4个参数(问号后面的即为查询传入的参数),前面三个是不变的,而变化的是最后一个,我们可以利用urllib模块中的urlencode模块来传递这些参数,链接如下:
https://m.weibo.cn/api/container/getindex?type=uid&value=2830678474&containerid=1076032830678474&page=2
代码如下:
import requests from urllib.parse import urlencode base_url = 'https://m.weibo.cn/api/container/getindex?' headers = { 'host': 'm.weibo.cn', 'referer': 'https://m.weibo.cn/u/2830678474', 'user-agent': 'mozilla/5.0 (macintosh; intel mac os x 10_12_3) applewebkit/537.36 (khtml, like gecko) chrome/58.0.3029.110 safari/537.36', 'x-requested-with': 'xmlhttprequest', } # 模拟请求头 def get_page(page): params = { 'type': 'uid', 'value': '2830678474', 'containerid': '1076032830678474', 'page': page } url = base_url + urlencode(params) response = requests.get(url, headers=headers) return response.json() # 由于内容是由ajax加载,响应的内容是json的形式 if __name__ == '__main__': for page in range(1,3): result = get_page(page) print(result)
再如要要抓取今日头条一些街拍的图片,在搜索框输入“街拍”二字之后回车便进入到街拍页面,看下网页的url是:https://www.toutiao.com/search/?keyword=%e8%a1%97%e6%8b%8d,但是直接拿这个去爬取图片是不成功的,因为这些数据是ajax加载,不存在网页源代码文件中,为之奈何?和前面的处理方法一样啊,其中可变参数是offset,这是构造的关键,其中链接的形式如下:
https://www.toutiao.com/search_content/?offset=20&format=json&keyword=%e8%a1%97%e6%8b%8d&autoload=true&count=20&curtab=1&from=search_tab
代码如下:
import requests from urllib.parse import urlencode def get_page(offset): headers = { 'user-agent': "mozilla/5.0 (compatible; msie 9.0; windows nt 6.1; win64; x64; trident/5.0;" " .net clr 3.5.30729; .net clr 3.0.30729; .net clr 2.0.50727; media center pc 6.0)", } params = { 'offset': offset, 'format': 'json', 'keyword': '街拍', 'autoload': 'true', 'count': '20', 'cur_tab': '1', 'from': 'search_tab', } base_url = 'https://www.toutiao.com/search_content/?' url = base_url + urlencode(params) try: response = requests.get(url, headers=headers) if response.status_code == 200: print(response.status_code) return response.json() except requests.connectionerror: return none if __name__ == '__main__': for offset in range(20, 60, 20): result = get_page(offset) print(result)
get方法和post方法是http中最常用的方法。它们能够访问和下载和访问网站服务器资源,这些网页就是我们要爬取并摘取数据的资源,爬虫程序模拟了浏览器实现这种http的get或者post等方法去获取资源。
get 方法用来请求访问已被 uri 识别的资源。指定的资源经服务器端解析后返回响应内容。也就是说,如果请求的资源是文本,那就保持原样返回;如果是像 cgi(common gateway interface,通用网关接口)那样的程序,则返回经过执行后的输出结果。如图:
post 方法用来传输实体的主体。
虽然用 get 方法也可以传输实体的主体,但一般不用 get 方法进行传输,而是用 post 方法。虽说 post 的功能与 get很相似,但post 的主要目的并不是获取响应的主体内容。如图:
http报文是指客户端和服务器用于http交互的的信息,客户端的http报文称为请求报文,服务器端的报文称为响应报文。需要爬虫某网页的时候,我们可以在开发者工具里面查找并分析这些报文以了解客户端的http请求及url等,从而模拟客户端去进行数据爬取。
http报文大致可以分为报文首部和主体,两者由最初出现的空行(cr+lf)来划分,如图:
请求首部由请求行(http请求方法、url、http协议版本)和首部字段(请求首部字段、通用首部字段、实体首部字段)及其他内容组成,以下是请求头部结构和请求实例,其中请求头user-agent是爬虫在模拟http方法请求网页资源时常常需要添加的一个参数。
响应首部则由状态行(http协议版本、响应状态码(数字和原因短语))和http首部字段(响应首部字段、通用首部字段、实体首部字段)组成,以下分别是响应头部结构和响应实例
通用首部字段
请求首部字段
http 是无状态协议,它不对之前发生过的请求和响应的状态进行管理。也就是说,无法根据之前的状态进行本次的请求处理。为解决此矛盾,cookie技术通过在请求和响应报文中写入cookie信息来控制客户端的状态。cookie会根据从服务端发送过来的报文内的一个叫set-cookie的首部字段信息,通知客户端保存cookie。当下次客户端再向此服务器发送请求时,客户端会自动在请求报文加入值后再发过去给服务端。服务端接收到客户端发送过来的cookie之后,会检查这个cookie究竟是从哪一个客户端发送过来,然后对比之前的服务记录,最后得到之前的状态信息。爬虫中也会模拟这种带cookie的http请求来实现反爬虫或使得抓取的数据更全面等,如图
因特网由tcp/ip统筹,所以万维网间接由它统筹。由于http位于tcp/ip协议簇的应用层,了解tcp/ip协议簇有助于我们更加了解http。cp/ip协议族里重要的一点就是分层,分层的好处在于,当互联网需要改动时,分层之后只需把变动对应的层替换掉即可,设计也变得相对简单。tcp/ip协议族按层次分别分为以下4层:应用层、传输层、网络层和数据链路层。如图:
tcp/ip协议族内预存了各类通用的应用服务。比如ftp(filetransfer protocol,文件传输协和dns(domain name system,域名系统)服务就是其中两类。http协议也处于该层。
在传输层有两个性质不同的协议:tcp(transmission controlprotocol,传输控制协议)和udp(user data protocol,用户数据报协议)。
网络层用来处理在网络上流动的数据包。数据包是网络传输的最小数据单位。该层规定了通过怎样的路径(所谓的传输路线)到达对方计算机,并把数据包传送给对方。与对方计算机之间通过多台计算机或网络设备进行传输时,网络层所起的作用就是在众多的选项内选择一条传输路线。
用来处理连接网络的硬件部分。包括控制操作系统、硬件的设备驱动、nic(network interface card,网络适配器,即网卡),及光纤等物理可见部分(还包括连接器等一切传输媒介)。硬件上的范畴均在链路层的作用范围之内。
利用 tcp/ip 协议族进行网络通信时,会通过分层顺序与对方进行通信。发送端从应用层往下走,接收端则往应用层往上走。如图:
首先,客户端在应用层(http协议)发出一个想看某个网页的http请求,接着为了传输方便,传输层(tcp协议)把从应用层接受到的数据(请求报文)进行分割,并在各个报文上打上标记序号和端口号发送给网络层,在网络层(ip协议),增加作为通信目的地的mac地址发送给链路层,至此,发往服务器的通信请求就准备齐全了
接着服务端在链路层接收到客户端发来的请求,然后按序一直往上发送到应用层,当请求传到应用层服务端才算真正接收到客户端发送过来的http请求。发送端在层与层之间传输数据时,每经过一层时必定会被打上一个该层所属的首部信息。反之,接收端在层与层传输数据时,每经过一层时会把对应的首部消去。这种把数据信息包装起来的做法称为封装(encapsulate)
tcp处于http协议的传输层,三次握手的目的在于保证请求信息的有效性,防止失效的连接请求报文段被服务端接收,从而产生错误。关于三次握手网上很多有趣的解释
本文叙述的是一些与python爬虫相关的http内容,主要参考自《http权威指南》、《图解http》和《python3网络爬虫开发实战》,仅仅是个人理解,望指正。
如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复
Python爬虫:Request Payload和Form Data的简单区别说明
浅谈Python中threading join和setDaemon用法及区别说明
Python3-异步进程回调函数(callback())介绍
python继承threading.Thread实现有返回值的子类实例
Python中使用threading.Event协调线程的运行详解
网友评论