python爬虫(二)网络请求
urllib
urllib是python自带标准库中用于网络请求的库,无需安装,直接引用即可
urllib通常用于爬虫开发、API(应用程序编程接口)数据获取和测试
urllib库的四大模块:
- urllib.request:用于打开和读取url
- urllib.error: 包含抛出的异常
- urllib.parse:用于解析URL
- urllib.robotparser:用于解析robots
# urllib.parse 用于解析url
import urllib.parse
kw = {'wd':'王者荣耀'}
# 编写
result = urllib.parse.urlencode(kw)
print(result) # wd=%E7%8E%8B%E8%80%85%E8%8D%A3%E8%80%80
# 解码
res = urllib.parse.unquote(result)
print(res) # wd=王者荣耀
发送请求
urllib.request库
模拟浏览器发起一个HTTP请求,并获取请求响应结果
urllib.request.urlopen的语法格式
urlopen(url,data=None)
url : url参数是str类型的地址,也就是要访问的url
data:默认值为None,如果data为默认值,则请求方式为get,否则为post。data以字典形式存储数据,并将参数data由字典类型转换成字节类型才能完成post请求
urlopen 返回的结果是一个HTTPResponse对象
import urllib.request
url = 'https://www.lingdianshuwu.com/'
# 发送请求
resp = urllib.request.urlopen(url)
html = resp.read().decode('gbk') # decode将bytes类型转换成str类型
print(html)
import urllib.request
import urllib.parse
url = 'https://www.xslou.com/login.php'
data={'username':'123','password':'123456','action':'login'}
# 发送请求
resp = urllib.request.urlopen(url,data=bytes(urllib.parse.urlencode(data),encoding='utf-8'))
html = resp.read().decode('gbk') # 解码的时候是GBK
print(html)
import urllib.request
url = 'https://movie.douban.com/'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3823.400 QQBrowser/10.7.4307.400'}
# 构建请求对象
req = urllib.request.Request(url,headers=headers)
# 使用URLopen打开请求.
res = urllib.request.urlopen(req)
# 从响应结果读取数据
html = res.read().decode('utf-8')
print(html)
import urllib.request
url = 'http://www.baidu.com'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3823.400 QQBrowser/10.7.4307.400'}
# 构建请求对象
req = urllib.request.Request(url,headers=headers)
# 获取opener对象
opener = urllib.request.build_opener()
resp = opener.open(req)
print(resp.read().decode())
IP代理
使用代理的原因
有的网站会检测某一时间段某个IP的访问次数,如果访问次数过多,它就会禁止你的访问,所以需要每隔一段时间换一个IP,就需要设置代理服务器
ip代理的分类
- 透明代理:目标网站知道你使用了代理,并且知道你的源地址
- 匿名代理:网站知道你使用了代理,但是不知道你的源地址
- 高匿代理:网站不知道你使用了代理。也不知道你的源地址
ip代理的使用
from urllib.request import build_opener
from urllib.request import ProxyHandler
proxy = ProxyHandler({'http':'27.220.164.8:9000'})
opener = build_opener(proxy)
url = 'https://apps.game.qq.com/cgi-bin/ams/module/ishow/V1.0/query/workList_inc.cgi?activityId=2735&sVerifyCode=ABCD&sDataType=JSON&iListNum=20&totalpage=0&page=0&iOrder=0&iSortNumClose=1&iAMSActivityId=51991&_everyRead=true&iTypeId=2&iFlowId=267733&iActId=2735&iModuleId=2735&_=1604812746139'
resp = opener.open(url)
print(resp.read().decode('gbk'))
使用cookie
使用cookie的原因:解决http协议的无状态性
使用步骤
- 实例化MozillaCookieJar(保存cookie)
- 创建handler对象(cookie 的处理器)
- 创建opener对象
- 打开网页
- 保存cookie文件
import urllib.request
from http import cookiejar
filename = 'cookie.txt'
# 获取cookie
def get_cookie():
# (1)实例化一个MozillaCookieJar(用于保存cookie)
cookie = cookiejar.MozillaCookieJar(filename)
# 2.创建handler对象
handler = urllib.request.HTTPCookieProcessor(cookie)
# 3.创建opener对象
opener = urllib.request.build_opener(handler)
# 4.请求网址
url = 'https://tieba.baidu.com/'
resp = opener.open(url)
# 5.保存cookie文件
cookie.save()
# 读cookie
def use_cookie():
# 实例化MozillaCookieJar()
cookie = cookiejar.MozillaCookieJar()
# 加载cookie文件
cookie.load(filename)
print(cookie)
if __name__ == '__main__':
get_cookie()
# use_cookie()
错误解析
异常处理主要用到两大类
- urllib.error.URLError:用于捕获由urllib.request产生的异常,使用reason属性返回错误原因
import urllib.request
import urllib.error
url = 'http://www.google.com' # 错误的网址
# url = 'http://www.google.cn' # 正确的网址
try:
resp = urllib.request.urlopen(url)
except urllib.error.URLError as e:
print(e.reason) # [WinError 10060] 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。
- urllib.error.HTTPError:用户处理HTTP与HTTPS请求的错误,它有三个属性
code:请求返回的状态码
reason:返回错误的原因
headers:请求返回的响应头信息
import urllib.request
import urllib.error
url = 'https://movie.douban.com/'
try:
resp = urllib.request.urlopen(url)
except urllib.error.HTTPError as e:
print("原因:",e.reason)
print("状态码:",e.code)
print('请求头:',e.headers)
'''
原因:
状态码: 418
请求头: Date: Sun, 15 Nov 2020 09:01:03 GMT
Content-Length: 0
Connection: close
Server: dae
X-Content-Type-Options: nosniff
'''
Requests库
Requests库是python一个很实用的HTTP客户端,完全满足如今网络爬虫的需求
Requests库常用的方法
序号 | 方法 | 描述 |
---|---|---|
1 | requests.request(url) | 构造一个请求,支持以下各种方法 |
2 | requests.get() | 发送Get请求 |
3 | requests.post() | 发送Post请求 |
4 | requests.head() | 获取html的头部信息 |
5 | requests.put() | 发送Put请求 |
6 | requests.patch() | 提交局部修改的请求 |
7 | requests.delete() | 提交删除请求 |
最常用的是get()和post()方法
Requests库的使用
语法结构:requests.get(url,params=None)
url:需要爬取的网站的网址
params:请求参数
该方法的结果为Response对象,包含服务器的响应信息
response对象的常用属性
序号 | 属性或方法 | 描述 |
---|---|---|
1 | response.status_code | 相应状态码 |
2 | response.content | 把response对象转换为二进制对象 |
3 | response.text | 把response对象转换成字符串对象 |
4 | response.encoding | 定义response对象的编码 |
5 | response.cookies | 获取请求后的cookie |
6 | response.url | 获取请求网址 |
7 | response.JSON() | 内置的json解码器 |
8 | Response.headers | 以字典对象存储服务器响应头,字典键不区分大小写 |
发送不带参数的get请求
# 发送不带参数的get请求
import requests
url = 'http://www.baidu.com'
resp = requests.get(url)
# 设置响应的编码格式
resp.encoding = 'utf-8'
cookie = resp.cookies # 获取请求后的cookie信息
header = resp.headers
print('响应状态码:',resp.status_code)
print('请求后的cookie',cookie)
print('获取请求的网址:',resp.url)
print('响应头:',header)
print('响应内容:',resp.text)
带参数的get请求
import requests
url = 'https://www.sogou.com/tx'
params = {'query':'python'}
resp = requests.get(url,params=params)
resp.encoding = 'UTF-8'
print('内容:',resp.text)
获取json数据
import requests
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3823.400 QQBrowser/10.7.4307.400'}
url = 'https://image.baidu.com/search/acjson?tn=resultjson_com&logid=6451819271703560556&ipn=rj&ct=201326592&is=&fp=result&queryWord=%E7%BE%8E%E5%A5%B3&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=-1&z=&ic=&hd=&latest=©right=&word=%E7%BE%8E%E5%A5%B3&s=&se=&tab=&width=&height=&face=0&istype=2&qc=&nc=1&fr=&expermode=&force=&cg=girl&pn=30&rn=30&gsm=1e&1604568666331='
resp = requests.get(url,headers=headers)
json_data = resp.json()
print(json_data)
获取二进制数据
import requests
url = 'https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png'
resp = requests.get(url)
# 存储
with open('logo.png','wb') as f:
f.write(resp.content)
post请求
import requests
url = 'https://www.xslou.com/login.php'
data = {'username': 'y11',
'password': 'a18',
'action': 'login'}
resp = requests.post(url,data)
resp.encoding='gb2312'
print(resp.status_code)
print(resp.text)
session发请求
import requests
url = 'https://www.xslou.com/login.php'
data = {'username': 'y11',
'password': 'a18',
'action': 'login'}
# 使用session发送请求
session = requests.session()
resp = session.post(url,data=data)
resp.encoding = 'gb2312'
# print(resp.text)
# 推荐小说
hot_url = 'https://www.xslou.com/modules/article/uservote.php?id=89732'
resp2 = session.get(hot_url)
resp2.encoding='gb2312'
print(resp2.text)