一个基本URL包含以下内容:
模式(或称协议)、服务器名称(或IP地址)、路径和文件名,如“协议://授权/路径?查询”。完整的、带有授权部分的统一资源标志符语法看上去如下:协议://用户名:密码@子域名。域名。顶级域名:端口号/目录/文件名.文件后缀?参数=值#标志。
eg:
eg:
from urllib import request,parse
url = "http://httpbin.org/post"
headers = {
"user-agent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:73.0) Gecko/20100101 Firefox/73.0'
"host":"httpbin.org"
}
dict = {
"name":"Hackdata"
}
data = bytes(parse.urlencode(dict),encoding = "utf8")
req = request.Request(url=url,data =data,headers=headers,method="POST")
response = request.urlopen(req)
print(response.read().decode("utf-8"))
几乎可以做到任何HTTP请求中所有的事情:
OpenerDirector:
import http.cookiejar,urllib.request
cookie = http.cookiejar.CookieJar()
handler = urllib.request.HTTPCookieProcessor(cookie)
opener = urllib.request.build_opener(handler)
response = opener.open("http://www.hao123.com")
for item in cookie:
print(item.name+"="+item.value)
requests库的特点:
import requests
import json
# 用requests发起简单的GET请求
url_get = 'http://httpbin.org/get'
response = requests.get(url_get,timeout = 5)
print(json.loads(response.text)['args'])
# 用requests发起带参数的GET请求
kvs = {'k1':'v1','k2':'v2'}
response = requests.get(url_get,params=kvs,timeout = 5)
print(json.loads(response.text)['args'])
# 用requests 发起POST 请求
url_post = 'http://httpbin.org/post'
kvs = {'k1':'v1','k2':'v2'}
response = requests.post(url_post,data=kvs,timeout = 5)
print(response.json()['form'])
上图我们可以看出,方法名把发起的请求表达的很清晰,get就是GET,post就是POST。不仅如此,我们或得的response
非常强大,可以直接得到很多信息,并且response
中的内容不是一次性的,requests
自动将响应的内容read
出来,保存在text
变量中,你想读取多少次就读多少次,我们看下response
中都有哪些有用的信息:
print(response.url)
print(response.status_code)
print(response.headers)
print(response.cookies)
print(response.encoding) # requests会自动猜测响应内容的编码
import json
print(response.json() == json.loads(response.text)) # response.text 是响应内容,可以读取任意次,并且requests可以自动转换json
requests = response.request # 可以直接获取response对应的request
print(response.url)
print(response.headers) # 我们发起的request 是什么样子的一目了然
Session():会话保持
我们先看下面一段代码:
import requests
url_cookies = 'http://httpbin.org/cookies'
url_set_cookies = 'http://httpbin.org/cookies/set?k1=v1&k2=v2'
print(requests.get(url_cookies,timeout = 5).json())
print(requests.get(url_set_cookies,timeout = 5).json())
print(requests.get(url_cookies,timeout = 5).json())
我们可以看到,调用url_set_cookies
设置cookie前后发送的GET请求得到的cookie都是空的。这说明不同的请求之间是没有关系的。这是为什么呢?因为urllib2
默认对所有的请求都是忽略cookie的,哪怕是重定向的请求。而requests
会在一个请求之内保存cookie(url_set_cookies请求包含了一个重定向请求)。
下面我们可以加上重定向看下:
session = requests.Session()
print(requests.get(url_cookies,timeout = 5).json())
print(requests.get(url_set_cookies,timeout = 5).json())
print(requests.get(url_cookies,timeout = 5).json())
import requests
url = 'http://httpbin.org/cookies/set?k1=v1&k2=v2'
proxies = {'http':'http://username:password@host:port','http://username:password@host:port'}
print(requests.get(url,proxies = proxies,timeout = 5).json()['args'])
# 上面的方法要给每个请求都要加上proxies参数,比较繁琐,可以为每个session设置一个默认的proxies
session = requests.Session()
session.proxies = proxies # 一个session中的所有请求都使用同一套代理
print(session.get(url,timeout = 5).json()['args'])
上述的代码不能运行,因为代理的格式是不正确的,等到我们需要时可以直接估值代码。
需要注意的是:
response
中的内容是用unicode
编码的,为了便于阅读我们需将其转换成中文,直接打印是不行的,因为Python
将一个dict
转换成字符串时保留了unicide
编码,所以直接打印出来的不是中文。
这里我们采用另一种转换的方法:先将得到的form dict
转换为 unicode
字符串(注意其中的ensure_ascii=False
参数,它的含义是不对unicode
字符转义),然后将得到的unicode
字符串编码成UTF-8
字符串,最后再转换成dict
,方便输出。
Chrome
中提供了检查网页元素的功能,叫做Chrome Inspect
。在网页中通过点击右键可以查看该功能,如下图所示:
在本页调出Chrome Inspect
,我们可以看到类似于下面的界面:
通常我们最常用的功能就是查看一个元素的源码,点击左上角的元素定位器,就可以选择网页中的不同元素,HTML
源码区就会自动显示指定元素的源码,通常CSS
显示区也会显示这个元素应用的样式。Chrome Inspect
更加常用的功能是监控网络交互过程,选择功能栏中的Network
,即可看到下面的界面:
Chrome Network
的交互区显示了一个网页加载过程,浏览器发起的所有请求。选择一个请求,右侧就会显示该请求的详情,包括请求头、响应头、响应内容等。Chrome Network
是我们研究网页交互流程的重要工具。Cookie
和Session
是重要的网络技术,在Chrome Inspect
中也可以查看网页Cookie
,选择功能栏中的Application
,即可看到下面的界面:
从Chrome Application
的左侧选择Cookies
,即可看到以K-V
形式保存的Cookie
。这个功能在我们研究网页的登录过程时非常有用。需要注意的是,在研究一个完整的网络交互过程前,要记得在Cookies
上点击右键,然后点击Clear
清空所有旧的Cookies
。
HTTP Response
的第一行,即Status Line
中包含了状态码。状态码由三位数字组成,标志着服务器对客户端请求处理结果。状态码分为以下几类:
下面是一些常见的状态码及其描述:
实际应用中,大多数网站都有反爬虫策略,响应状态码代表了服务器的处理结果,是我们调整爬虫抓取状态(如频率、ip)的重要参考。比如说我们一直正常运行的爬虫突然获取了403响应,这很可能是服务器识别了我们的爬虫,并拒绝了我们的请求。这时,我们就要减慢爬取频率,或者重启Session,甚至更换IP。