1. urllib.request模块
1-1 常用方法
1-2 响应对象
2. urllib.parse模块
2-1 常用方法
3. 请求方式
4. requests模块
4-1 安装
4-2 request常用方法
4-3 响应对象response的方法
4-4 requests设置代理
4-5 requests模块发送 POST请求
4-7session
4-8 处理不信任的SSL证书
urllib.request模块是python的自带的模块,可能有些小伙伴习惯于使用python的第三方requests模块,的确,如果论书写简洁的话requests模块更具优势,但是urllib.request模块也是作为一名程序员需要掌握的基础。这里我们就来介绍一下这个爬虫的请求模块。
这里以我最喜欢的动漫人物哆啦a梦为例,网址为http://www.doraemon.com/
上代码:
import urllib.request
url='http://www.doraemon.com/'
req=urllib.request.urlopen(url)
res=req.read()
print(res)
运行后是这个样子:
这是网页的源代码:
为什么看起来不一样(*Φ皿Φ*)?
不要着急,这是因为我们爬取信息时拿到的是一个字节流(bytes)类型的数据,而浏览器的源码信息是字符串类型的数据,所以我们只需要将拿到的数据转换为字符串类型的数据即可:
import urllib.request
url='http://www.doraemon.com/'
req=urllib.request.urlopen(url)
res=req.read().decode('utf-8')
print(res)
我们再看此时爬取的信息:
完成!!*★,°*:.☆( ̄▽ ̄)/$:*.°★*
补充:encode() 字符串—>bytes数据类型
decode() bytes数据类型—>字符串
有些网站可能会设置一些反爬,此时我们就需要反反爬,即添加一个请求头来伪装成浏览器在浏览网页。这个时候就要先用urllib.request.Request("网址",headers="字典")来添加请求头,然后再用urllib.request.urlopen("网址")来获取响应对象。因为urlopen()不支持重构User-Agent,即无法直接向urllib.request.urlopen()中添加请求头。
以百度网站为例,“百度一下,你就知道”:https://www.baidu.com/
打开网址,右击鼠标,点击检查,在Network中找到第0个请求(一般)
点击这个请求,点击Headers,在Request Headers中找到User-Agent 然后复制
代码如下:
import urllib.request
url='http://www.baidu.com/'
headers={
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.129 Safari/537.36'
}
req=urllib.request.Request(url,headers=headers)
res=urllib.request.urlopen(req)
html=res.read().decode('utf-8')
print(html)
我们先看第一种方法,直接上代码:
import urllib.parse
name={'wd':'哆啦a梦'}
name=urllib.parse.urlencode(name)
print(name)
运行后得到16进制的编码:
第二种方法就是将字典换成字符串,直接给代码:
import urllib.parse
name='哆啦a梦'
name=urllib.parse.quote(name)
print(name)
pip3 install requests
,然后点击enter即可;Windows电脑里叫命令提示符(cmd),输入pip install requests
即可。# 引入requests库
import requests
# requests.get是在调用requests库中的get()方法,它向服务器发送了一个请求,括号里的参数是你需要的数据所在的网址,然后服务器对请求作出了响应。
# 我们把这个响应返回的结果赋值给变量res
res = requests.get('URL')
post和get都可以带着参数请求,不过get请求的参数会在url上显示出来。但post请求的参数就不会直接显示,而是隐藏起来。像账号密码这种私密的信息,就应该用post的请求。如果用get请求的话,账号密码全部会显示在网址上,这显然不科学!你可以这么理解,get是明文显示,post是非明文显示。
以有道翻译为例,网址为:http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule
打开开发者工具,在输入框中输入要翻译的内容,然后把Network
面板清空,再点击一下翻译,看看有没有多出来的新XHR
,多出来的那一个就是我们要找的,如下图的translate_o?... 然后点击Headers-Form Data,找到data数据。
完整的代码如下:
import urllib.request
import urllib.parse
import json
# 请输入你要翻译的内容
key = input('请输入您要翻译的内容:')
# 把提交的form表单的数据转换为bytes类型的数据
data = {
'i': key,
'from': 'AUTO',
'smartresult': 'dict',
'client': 'fanyideskweb',
'salt': '15880623642174',
'sign': 'c6c2e897040e6cbde00cd04589e71d4e',
'ts': '1588062364217',
'bv': '42160534cfa82a6884077598362bbc9d',
'doctype': 'json',
'version': '2.1',
'keyfrom':'fanyi.web',
'action': 'FY_BY_CLICKBUTTION'
}
data = urllib.parse.urlencode(data)
# 把data转换成自己
data = bytes(data,'utf-8')
# 发请求获取响应 注意 需要去掉_o
url = 'http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36'
}
req = urllib.request.Request(url,data=data,headers=headers)
res = urllib.request.urlopen(req)
html = res.read().decode('utf-8')
# 把json类型的字符串转换为字典
r_dict = json.loads(html)
# {"type":"EN2ZH_CN","errorCode":0,"elapsedTime":1,"translateResult":[[{"src":"name","tgt":"的名字"}]]}
r = r_dict['translateResult'] # [[{"src":"name","tgt":"的名字"}]]
result = r[0][0]['tgt'] # [{"src":"name","tgt":"的名字"}] -->{"src":"name","tgt":"的名字"}
print(result)
点击运行后输入想要翻译的内容,然后回车键,出现如下结果:
HTTP是⼀种⽆连接协议,客户端和服务器交互仅仅限于 请求/响应过程,结束后断开,下⼀次请求时,服务器会认为是⼀个新的客户端,为了维护他们之间的连接,让服务器知道这是前⼀个⽤户发起的请求,必须在⼀个地⽅保存客户端信息。
什么是SSL证书?
比如我们想要访问这个网站:https://inv-veri.chinatax.gov.cn/
如果我们直接爬取的话会显示这样的报错:
查看网页证书信息会显示:无法将这个证书验证到一个受信任的证书颁发机构,也就是我们之所以会发生报错是因为SSL证书不受信任,那么怎么解决这个问题呢?很简单,只要在requests.get()中加上verify=False就可以了,意思就是告诉浏览器我们只是想要尝试连接一下。
import requests
url = 'https://inv-veri.chinatax.gov.cn/'
resp = requests.get(url,verify = False)
print(resp.text)
运行结果: