一、GET、POST请求方法的原理
1. HTTP工作原理
HTTP协议定义Web客户端如何从Web服务器请求Web页面,以及服务器如何把Web页面传送给客户端。HTTP协议采用了请求/响应模型。客户端向服务器发送一个请求报文,请求报文包含请求的方法、URL、协议版本、请求头部和请求数据。服务器以一个状态行作为响应,响应的内容包括协议的版本、成功或者错误代码、服务器信息、响应头部和响应数据。
以下是 HTTP 请求/响应的步骤:
(1)客户端连接Web服务器
一个HTTP客户端,通常是浏览器,与Web服务器的HTTP端口(默认为80)建立一个TCP套接字连接.
(2)发送HTTP请求
通过TCP套接字,客户端向Web服务器发送一个文本的请求报文,一个请求报文由请求行、首部行、空行和实体体4部分组成。
(3)服务器接受请求并返回HTTP响应
Web服务器解析请求,定位请求资源。服务器将资源副本写到TCP套接字,由客户端读取。一个响应由状态行、首部行、空行和实体体4部分组成。
(4)释放TCP连接
若connection 模式为close,则服务器主动关闭TCP连接,客户端被动关闭连接,释放TCP连接;若connection 模式为keepalive,则该连接会保持一段时间,在该时间内可以继续接收请求;
(5)客户端浏览器解析服务器返回的HTML内容
客户端浏览器首先解析状态行,查看表明请求是否成功的状态代码。然后解析每一个响应头,响应头告知以下为若干字节的HTML文档和文档的字符集。客户端浏览器读取响应数据HTML,根据HTML的语法对其进行格式化,并在浏览器窗口中显示。
2. GET方法和POST方法的区别
GET和POST本质上就是TCP连接,并无差别。但是由于HTTP的规定和浏览器/服务器的限制,导致他们在应用过程中体现出一些不同。
(1)使用时最直观的区别
最直观的区别就是GET把参数包含在URL中,POST通过request body传递参数。
(2)为什么get比post更快
a. post请求包含更多的请求头
因为post需要在请求的body部分包含数据,所以会多了几个数据描述部分的首部字段(如:content-type),这其实是微乎其微的。
b. 最重要的一条,post在真正接收数据之前会先将请求头发送给服务器进行确认,然后才真正发送数据
在这里插入图片描述
3. 面试一般是怎么回答GET和POST的区别的
参考资料:
《计算机网络自顶向下方法》
二、分别通过GET、POST方法获取页面内容
1. python3 requests模块学习
requests库是一个常用的用于 http请求的模块,它使用 python语言编写,基于urllib,可以方便的对网页进行爬取,相较于urllib更加简洁高效,是学习python 爬虫的较好的http请求模块。
(1)发送简单的请求
import requests
r = requests.get('https://github.com/Ranxf')
r1 = requests.get(url='http://dict.baidu.com/s', params={'wd': 'python'})
使用该方式使用以下方法
requests.get(‘https://github.com/timeline.json’)
requests.post(“http://httpbin.org/post”)
requests.put(“http://httpbin.org/put”)
requests.delete(“http://httpbin.org/delete”)
requests.head(“http://httpbin.org/get”)
requests.options(“http://httpbin.org/get” )
(2)为url传递参数
import requests
url_params={'key':'value'}
res=requests.get("http://www.xazlsec.com",params=url_params)
print(res.url)
>>>https://www.xazlsec.com/?key=value
(3)响应的内容
print(res.encoding)
print(res.text)
print(res.content)
print(res.headers)
print(res.status_code)
(4)自定义请求头和cookie信息
url="http://www.xazlsec.com"
header = {'user-agent': 'my-app/0.0.1'}
cookie = {'key':'value'}
res=requests.get(url,headers=header,cookies=cookie)
url="http://www.xazlsec.com"
data = {'some': 'data'}
headers = {'content-type': 'application/json',
'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:22.0) Gecko/20100101 Firefox/22.0'}
res=requests.post(url,data=data,headers=headers)
print(res.text)
(5)响应
r.headers
r.requests.headers
r.cookies
r.history
(6)设置超时
r = requests.get('url',timeout=1)
(7)会话对象,能够跨请求保持某些参数
s = requests.Session()
s.auth = ('auth','passwd')
s.headers = {'key':'value'}
r = s.get('url')
r1 = s.get('url1')
(8)设置代理
proxies = {'http':'ip1','https':'ip2' }
requests.get('url',proxies=proxies)
汇总:
r = requests.get('https://github.com/timeline.json')
r = requests.post("http://m.ctrip.com/post")
r = requests.put("http://m.ctrip.com/put")
r = requests.delete("http://m.ctrip.com/delete")
r = requests.head("http://m.ctrip.com/head")
r = requests.options("http://m.ctrip.com/get")
print(r.content)
print(r.text)
payload = {'keyword': '香港', 'salecityid': '2'}
r = requests.get("http://m.ctrip.com/webapp/tourvisa/visa_list", params=payload)
print(r.url)
r = requests.get('https://github.com/timeline.json')
print (r.encoding)
r = requests.get('https://github.com/timeline.json')
print(r.json())
url = 'http://m.ctrip.com'
headers = {'User-Agent' : 'Mozilla/5.0 (Linux; Android 4.2.1; en-us; Nexus 4 Build/JOP40D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19'}
r = requests.post(url, headers=headers)
print (r.request.headers)
url = 'http://m.ctrip.com'
payload = {'some': 'data'}
r = requests.post(url, data=json.dumps(payload))
url = 'http://m.ctrip.com'
files = {'file': open('report.xls', 'rb')}
r = requests.post(url, files=files)
r = requests.get('http://m.ctrip.com')
print(r.status_code)
r = requests.get('http://m.ctrip.com')
print (r.headers)
print (r.headers['Content-Type'])
print (r.headers.get('content-type'))
url = 'http://example.com/some/cookie/setting/url'
r = requests.get(url)
r.cookies['example_cookie_name']
url = 'http://m.ctrip.com/cookies'
cookies = dict(cookies_are='working')
r = requests.get(url, cookies=cookies)
r = requests.get('http://m.ctrip.com', timeout=0.001)
proxies = {
"http": "http://10.10.1.10:3128",
"https": "http://10.10.1.100:4444",
}
r = requests.get('http://m.ctrip.com', proxies=proxies)
proxies = {
"http": "http://user:pass@10.10.1.10:3128/",
}
参考资料:
[https://www.cnblogs.com/ranxf/p/7808537.html]:
2. 获取www.xazlsec.com网页内容
(1)GET方法
import requests
url="http://www.xazlsec.com"
headers = {'content-type': 'application/json',
'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:22.0) Gecko/20100101 Firefox/22.0'}
res=requests.get(url,headers=headers)
print(res.text)
结果:
(2)POST方法
import requests
url="http://www.xazlsec.com"
data = {'some': 'data'}
headers = {'content-type': 'application/json',
'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:22.0) Gecko/20100101 Firefox/22.0'}
res=requests.post(url,data=data,headers=headers)
print(res.text)
结果:
三、使用正则表达式获取页面关键信息
使用正则将页面中的域名、邮箱等关键信息匹配出来,并进行输出
1. python 正则表达式学习
()和[]有本质的区别 ()内的内容表示的是一个子表达式,()本身不匹配任何东西,也不限制匹配任何东西,只是把括号内的内容作为同一个表达式来处理,例如(ab){1,3},就表示ab一起连续出现最少1次,最多3次。如果没有括号的话,ab{1,3},就表示a,后面紧跟的b出现最少1次,最多3次。另外,括号在匹配模式中也很重要。这个就不延伸了,LZ有兴趣可以自己查查 []表示匹配的字符在[]中,并且只能出现一次,并且特殊字符写在[]会被当成普通字符来匹配。例如[(a)],会匹配(、a、)、这三个字符。 所以() [] 无论是作用还是表示的含义,都有天壤之别,没什么联系
2. 获取页面关键信息
以http://home.baidu.com/contact.html为例,提取百度邮箱和联系电话
import requests
import re
mail_pattern=r"\S.+:+[\w]+@[\w\.]+"
phone_pattern=r"\S.+:+[\d]+-[\d]+-[\d]+"
url="http://home.baidu.com/contact.html"
res=requests.get(url)
text=res.text
email=re.findall(mail_pattern,text)
phone=re.findall(phone_pattern,text)
email=set(email)
phone=set(phone)
print(email)
print(phone)
获取结果如下:
|