Python爬虫(一)——urllib库的请求发送request模块

一、urllib库简介

1.urlib为内置HTTP请求库,无需要额外安装。
2.python2中有urllib与urllib2 两个库完成请求发送,但在python3中二者统一为urllib。
3.包含四个模块:
request:最基本的HTTP请求模块,模拟发送请求。只需要传入URL及额外参数即可。
error:异常处理模块,如果出现请求错误,可以捕获异常,不会出现意外终止。
parse:一个工具模块,提供许多URL处理方法。
robotparse:主要用于识别网站的robots.txt文件,判断哪些网站可以爬,哪些网站不可以(使用较少)。

二、使用urllib

1.urlopen( )

两行代码的简单爬虫爬取CSDN首页:

import urllib.request
response = urllib.request.urlopen('https://www.csdn.net/')
print(response.read().decode('utf-8'))

结果如下:这就是爬取CSDN首页的部分结果
decode(‘utf-8’)设置了读取数据时的编码形式,如果不调用方法decode( ),中文将无法显示。
对于urlopen( )返回的对象:

方法名作用
read( )得到返回的网页内容
status( )查看返回结果的状态码(如:200代表请求成功,404代表网页未找到)
getheaders( )得到返回的响应头信息
getheaders(‘传递参数’)得到指定条目的信息

urlopen( )一般接受三个参数,urlopen(url,data,timeout)

1.url:即链接,统一资源定位符

2.data:参数可选,若添加该参数,需使用bytes( )函数将参数转化为字节流编码格式,即bytes类型。
(传参后请求方式不再是GET,而是POST方式。关于两者区别:https://www.zhihu.com/question/28586791

实例:

import urllib.request
import urllib.parse
data=bytes(urllib.parse.urlencode({'word':'hello'}),encoding='utf-8')response = urllib.request.urlopen('https://httpbin.org/post',data=data)
print(response.read())

bytes( )方法第一个参数需要字符串,需要用urllib.parse中的unlencode( )方法将参数字典转换为字符串,第二个参数指定编码类型(测试站点httpbin.org提供HTTP测试)

测试结果:

{ “args”: { },
“data”: “”,
“files”: {},
“form”: {
"word": "hello"
},
“headers”: {
“Accept-Encoding”: “identity”,
“Content-Length”: “10”,
“Content-Type”: “application/x-www-form-urlencoded”,
“Host”: “httpbin.org”,
“User-Agent”: “Python-urllib/3.8”,
“X-Amzn-Trace-Id”: “Root=1-5e61cbb1-2c82aac0aa060b50127cffe0”
},
“json”: null,
“origin”: “125.70.49.90”,
“url”: “https://httpbin.org/post”
}’

3.timeout参数
用于设置超时时间,单位为秒,超出时间,抛出异常,不指

定,则使用全局默认时间

2.Requst( )
urlopen( )可以实现最基本请求,但不够完整。如果要加入Headers等信息,可以利用更强大的Request类构建,一般采取的参数:

Request(url = url,data = data,headers = headers,method = None)

1.url:必传参数
2.date:同urlopen( )
3.headers:请求头,可通过参数直接构建或者用方法add_header( )添加
4.method:一个字符串,用来请求使用的方法,比如POST、GET、PUT等

import urllib.request
import urllib.parse

url = 'https://httpbin.org/post'
headers = {   
 'User-Agent':'Mozilla/4.0(compatible;MSIE 5.5;Windos NT)'  #添加请求头最常用用法即修改User-Agent来伪装浏览器
 'Host':'httpbin.org'
 }
dict = { 
   'name' : 'Germey'
 }
data=bytes(urllib.parse.urlencode(dict),encoding='utf8')
req=urllib.request.Request(url=url,data=data,headers=headers,method='POST')
response=urllib.request.urlopen(req)

print(response.read().decode('utf-8'))

结果为:

{
“args”: {},
“data”: “”,
“files”: {},
“form”: {
“name”: “Germey”
},
“headers”: {
“Accept-Encoding”: “identity”,
“Content-Length”: “11”,
“Content-Type”: “application/x-www-form-urlencoded”,
“Host”: “httpbin.org”,
“User-Agent”: “Mozilla/4.0(compatible;MSIE 5.5;Windos NT)”,
“X-Amzn-Trace-Id”: “Root=1-5e61dc96-d1296828b42668602814ac10”
},
“json”: null,
“origin”: “125.70.49.90”,
“url”: “https://httpbin.org/post”
}

还可采用add_header( )方法:

req=urllib.request.Request(url=url,data=data,method='POST')
req.add_header('User-Agent','Mozilla/4.0(compatible;MSIE 5.5;Windows NT)')

可以发现依然用了urlopen( )方法来发送请求,但参数不再是一个URL而是Request( ),一方面请求独立成了一个对象,另一方面灵活配置了参数。

3.高级用法

更强大的工具Handler,可以理解为各种处理器,如:专门处理登录验证的,处理Cookies的,有代理设置的。urllib。request模块内的BaseHandler类是所有其他Handler的父类,提供最基本的方法

Handler子类用途
HTTPDefaultErrorHandler用于处理HTTP响应错误,错误都会抛出HTTPError类型的异常
HTTPRedirectionHandler用于处理重定向
HTTPCookieProcessor用于处理Cookies
ProxyHandler用于设置代理,默认代理为空
HTTPPasswordMgr用于管理密码,维护用户名和密码的表
HTTPBasicAuthHandler用于管理认证,若链接打开需要认证,则处理认证问题

另一个比较重要的类为OpenerDirector,可称之为Opener。

引入Opener主要为实现更高级的功能。之前使用的Request和urlopen( )其实是预先封装了常用的请求方法,当时先更高级功能,需要深入配置,使用更底层的实例完成操作。Opener可以使用open( )方法,返回类型与urlopen一致。

Opener与Handler的联系:利用Handler来构建Opener!(奥义!!!)

情况一:验证
当遇到需要填充用户名与密码的网站时,借助HTTPBasicAuthHandler完成:

from urllib.request import HTTPPasswordMgrWithDefaultRealm,HTTPBasicAuthHandler,build_opener
from urllib.error import URLError

username = 'username'
password = 'password'      #填入自己的
url = 'https://localhost:5000/'

p = HTTPPasswordMgrWithDefaultRealm()
p.add_password(None,url,username,password)
auth_handler = HTTPBasicAuthHandler(p)
opener = build_opener(auth_handler)         #用Handler构建Opener
try:    
	result = opener.open(url)    
	html = result.read().decode('utf-8')    
	print(html)
except URLError as e:    
	print(e.reason)

情况二:代理

from urllib.request import URLError
from urllib.request import ProxyHandler,build_opener

proxy_handler = ProxyHandler({            #构建handler
      'http' : 'http://127.0.0:9743',
      'https' : 'https://127.0.0.1:9743'
  })
opener = build_opener(proxy_handler)
try:
	response = opener.open('https://www.baidu.com')
	print(response.read().decode('utf-8'))
except URLError as e:    
	print(e.reason)

情况三:Cookies

1.首先获取Cookie:

import http.cookiejar,urllib.request
cookie = http.cookiejar.CookieJar()    #声明CookieJar对象实例来保存
cookiehandler = urllib.request.HTTPCookieProcessor(cookie) #利用urlib.request库的HTTPCookieProcessor对象来创建cookie处理器

opener = urllib.request.build_opener(handler)response = opener.open('https://www.baidu.com')
for item in cookie:    
	print(item.name + "=" +item.value)

结果为:
输出了每条Cookie的名称和值
另外,如尝试爬豆瓣:‘https://www.douban.com/ ’ 会发现返回418这是触发了反爬的结果。
2.如何保存Cookies

filename = 'cookies.txt'
cookie = http.cookiejar.MozillaCookieJar(filename)    
#声明一个MozillaCookieJar对象实例(cookie)来保存cookie,后面写入文件
#可该换为cookie = http.cookiejar.LWPCookieJar(fliename)来将其储存为一个LWP格式文件
handler = urllib.request.HTTPCookieProcessor(cookie)
opener = urllib.request.build_opener(handler)
response = opener.open('https://www.baidu.com')cookie.save(ignore_discard=True,ignore_expires=True)
#ignore_discard表示即使cookie将被丢弃也将保存下来,ignore_expires表示如果该文件中cookie已经存在,则覆盖原文件写入

由代码可见,此时CookieJar需要换成MozillaCookieJar,它在生成文件时会用到,是CookieJar的子类,可用于处理Cookies和文件相关事件,比如读取与保存。
可将其保存为Mozilla浏览器的Cookies格式。
3.读取本地Cookies文件(以Mzilla格式为例)

cookie=http.cookiejar.MozillaCookieJar()   #声明CookieJar对象实例来保存
cookie.load('cookie.txt',ignore_discard=True,ignore_expires=True)#从文件中读取内容到cookie变量中

handler=urllib.request.HTTPCookieProcessor(cookie)	#处理器
opener=urllib.request.build_opener(handler)
response =  opener.open('http://www.baidu.com')
print(response.read().decode('utf-8'))

采用load( )方法读取本地文件。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值