欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

python爬虫基础之urllib的使用

程序员文章站 2022-08-17 21:47:23
一、urllib 和 urllib2的关系在python2中,主要使用urllib和urllib2,而python3对urllib和urllib2进行了重构,拆分成了urllib.request, u...

一、urllib 和 urllib2的关系

在python2中,主要使用urllib和urllib2,而python3对urllib和urllib2进行了重构,拆分成了urllib.request, urllib.parse, urllib.error,urllib.robotparser等几个子模块,这样的架构从逻辑和结构上说更加合理。urllib库无需安装,python3自带。python 3.x中将urllib库和urilib2库合并成了urllib库。

    urllib2.urlopen() 变成了 urllib.request.urlopen()
    urllib2.request() 变成了 urllib.request.request()
    python2中的 cookielib 改为 http.cookiejar.
    import http.cookiejar 代替  import cookielib
    urljoin 现在对应的函数是 urllib.parse.urljoin

二、python3下的urllib库

  • request,它是最基本的 http 请求模块,我们可以用它来模拟发送一请求,只需要给库方法传入 url 还有额外的参数,就可以模拟实现这个过程了。
  • error ,即异常处理模块,如果出现请求错误,我们可以捕获这些异常,然后进行重试或其他操作保证程序不会意外终止。
  • parse ,是一个工具模块,提供了许多 url 处理方法,比如拆分、解析、合并等等的方法。
  • robotparser,主要是用来识别网站的 robots.txt 文件,然后判断哪些网站可以爬,哪些网站不可以爬的,其实用的比较少。

三、request的基础类

(一)request.urlopen

urlopen方法最主要的参数就是目标网站的url地址,可以使str类型,也可以是一个request对象。

get方法请求如下:

from urllib import request,parse
respones = request.urlopen(http://www.baidu.com/)

post方法请求,需要添加data参数(字典格式),它要是字节流编码格式的内容,即 bytes 类型,通过 bytes() 方法可以进行转化,另外如果传递了这个 data 参数,不添加data参数就默认为 get 方式请求。

from urllib import request,parse
url = "http://www.baidu.com/"
wd = {'wd':'哇哈哈哈'}
data = bytes(parse.urlencode(wd),'utf-8')
respones = request.urlopen(url,data=data)

(二)request.request

由于单独使用urlopen() 方法的不能添加user-agent、cookie等headers信息,需要构建一个 request 类型的对象,通过构造这个这个数据结构,一方面我们可以将请求独立成一个对象,另一方面可配置参数更加丰富和灵活。主要参数有:

  • url 参数是请求 url,这个是必传参数,其他的都是可选参数。
  • data 参数如果要传必须传 bytes(字节流)类型的,如果是一个字典,可以先用 urllib.parse 模块里的 urlencode() 编码。
  • headers 参数是一个字典,这个就是 request headers 了,你可以在构造 request 时通过 headers 参数直接构造,也可以通过调用 request 实例的 add_header() 方法来添加, request headers 最常用的用法就是通过修改 user-agent 来伪装浏览器,默认的 user-agent 是 python-urllib,我们可以通过修改它来伪装浏览器。
  • origin_req_host 参数指的是请求方的 host 名称或者 ip 地址。
  • unverifiable 参数指的是这个请求是否是无法验证的,默认是false。意思就是说用户没有足够权限来选择接收这个请求的结果。例如我们请求一个 html 文档中的图片,但是我们没有自动抓取图像的权限,这时 unverifiable 的值就是 true。
  • method 参数是一个字符串,它用来指示请求使用的方法,比如get,post,put等等。

通过随机的方法,选择user-agent:

import randomua_list = [
  'mozilla/5.0 (compatible; u; abrowse 0.6; syllable) applewebkit/420+ (khtml, like gecko)',
  'mozilla/5.0 (compatible; msie 8.0; windows nt 6.0; trident/4.0; acoo browser 1.98.744; .net clr 3.5.30729)',
  'mozilla/5.0 (compatible; msie 8.0; windows nt 6.0; trident/4.0; acoo browser 1.98.744; .net clr 3.5.30729)',
  'mozilla/4.0 (compatible; msie 8.0; windows nt 6.0; trident/4.0; acoo browser; gtb5; mozilla/4.0 (compatible; msie 6.0; windows nt 5.1; sv1) ; infopath.1; .net clr 3.5.30729; .net clr 3.0.30618)',
  'mozilla/4.0 (compatible; msie 8.0; windows nt 5.1; trident/4.0; sv1; acoo browser; .net clr 2.0.50727; .net clr 3.0.4506.2152; .net clr 3.5.30729; avant browser)',
  'mozilla/4.0 (compatible; msie 7.0; windows nt 6.0; acoo browser; slcc1; .net clr 2.0.50727; media center pc 5.0; .net clr 3.0.04506)',
  'mozilla/4.0 (compatible; msie 7.0; windows nt 6.0; acoo browser; gtb5; mozilla/4.0 (compatible; msie 6.0; windows nt 5.1; sv1) ; maxthon; infopath.1; .net clr 3.5.30729; .net clr 3.0.30618)',
  'mozilla/4.0 (compatible; mozilla/5.0 (compatible; msie 8.0; windows nt 6.0; trident/4.0; acoo browser 1.98.744; .net clr 3.5.30729); windows nt 5.1; trident/4.0)',
  'mozilla/4.0 (compatible; mozilla/4.0 (compatible; msie 8.0; windows nt 5.1; trident/4.0; gtb6; acoo browser; .net clr 1.1.4322; .net clr 2.0.50727); windows nt 5.1; trident/4.0; maxthon; .net clr 2.0.50727; .net clr 1.1.4322; infopath.2)',
  'mozilla/4.0 (compatible; msie 8.0; windows nt 6.0; trident/4.0; acoo browser; gtb6; mozilla/4.0 (compatible; msie 6.0; windows nt 5.1; sv1) ; infopath.1; .net clr 3.5.30729; .net clr 3.0.30618)'
]

#随机获取一个user-agent
user_agent = random.choice(ua_list)

添加headers头部信息的方法1:

url='http://www.baidu.com/'user_agent = random.choice(ua_list)
headers = {
  'user-agent': user_agent
}
req = request.request(url=url,headers=headers)
respones = request.urlopen(req)

添加headers头部信息的方法2:

url='http://www.baidu.com'
headers = {
  'user-agent': user_agent
}
#添加user-agent的方法2
req = request.request(url)
#请求添加user-agent
req.add_header("user-agent",user_agent)
#获取请求的user-agent agent的a要小写
print(req.get_header("user-agent"))
response = request.urlopen(req)print(respones.read().decode('utf-8'))

三、request的高级类

在urllib.request模块里的basehandler类,他是所有其他handler的父类,他是一个处理器,比如用它来处理登录验证,处理cookies,代理设置,重定向等。它提供了直接使用和派生类使用的方法:

  • add_parent(director):添加director作为父类
  • close():关闭它的父类
  • parent():打开使用不同的协议或处理错误
  • defautl_open(req):捕获所有的url及子类,在协议打开之前调用

handler的子类包括:

httpdefaulterrorhandler:用来处理http响应错误,错误会抛出httperror类的异常
httpredirecthandler:用于处理重定向
httpcookieprocessor:用于处理cookies
proxyhandler:用于设置代理,默认代理为空
httppasswordmgr:永远管理密码,它维护用户名和密码表
httpbasicauthhandler:用户管理认证,如果一个链接打开时需要认证,可以使用它来实现验证功能

(一)proxyhandler

如果爬虫需要大量爬取网站数据,为了避免被封号,需要使用代理,通过request.build_opener()方法生成一个opener对象,添加代理的方法如下:

from urllib import request

#代理开关,表示是否开启代理
proxyswitch =true

#构建一个handler处理器对象,参数是一个字典类型,包括代理类型和代理服务器ip+port
proxyhandler = request.proxyhandler({"http":"191.96.42.80:3128"})
#如果是带用户名和密码的代理,格式为{"http":"username:passwd@191.96.42.80:3128"}

#不加代理的handler处理器对象
nullproxyhandler = request.proxyhandler()

if proxyswitch:
  opener = request.build_opener(proxyhandler)
else:
  opener = request.build_opener(nullproxyhandler)

req = request.request("http://www.baidu.com/")

response = opener.open(req)

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

(二)proxybasicauthhandler

通过密码管理器的方法实现代理服务器功能

from urllib import request
#代理密码管理,也可以管理服务器账户密码

#账户密码
user = "username"
passwd = "passwd"

#代理服务器
proxyserver = "1.1.1.1:9999"

#构建密码管理对象,保存需要处理的用户名和密码
passmgr = request.httppasswordmgrwithdefaultrealm()

#添加账户信息,第一个参数realm是与远程服务器相关的域信息
passmgr.add_password(none,proxyserver,user,passwd)

#构建基础proxybasicauthhandler处理器对象
proxyauth_handler = request.proxybasicauthhandler(passmgr)

opener = request.build_opener(proxyauth_handler)

req = request.request("http://www.baidu.com/")

response = opener.open(req)

(三)proxybasicauthhandler

通过密码管理器的方法实现web认证登陆功能

#web验证
from urllib import request

test = "test"
passwd = "123456"

webserver = "1.1.1.1"

#构建密码管理器handler
passwdmgr = request.httppasswordmgrwithdefaultrealm()
#添加密码信息
passwdmgr.add_password(none,webserver,test,passwd)

#http基础验证处理器类
http_authhandler = request.httpbasicauthhandler(passwdmgr)

opener = request.build_opener(http_authhandler)

req = request.request("http://"+webserver)

response = opener.open(req)

四、cookie处理

 通过http.cookiejar中的httpcookieprocessor构建cookie处理器对象,处理cookie信息

import http.cookiejar
from urllib import request,parse
#模拟登陆先post账户密码
#然后保存生成的cookie

#通过cookiejar类构件一个coociejar对象,从来保存cookie值
cookie = http.cookiejar.cookiejar()

#构件cookie处理器对象,用来处理cookie
cookie_handler = request.httpcookieprocessor(cookie)

#构件一个自定义的opener
opener = request.build_opener(cookie_handler)

#通过自定义的opener的addheaders参数,可以添加http报头参数
opener.addheaders = [("user-agent","mozilla/5.0 (compatible; u; abrowse 0.6; syllable) applewebkit/420+ (khtml, like gecko)"),]

#需要登陆的接口
url = 'http://www.renren.com/plogin.do'

#需要登陆的账户密码
data = {
  "email":"renren账号",
  "password":"密码"
}
#数据处理
data = bytes(parse.urlencode(data),'utf-8')
#第一次是post请求,通过登陆账户密码,得到cookie
req = request.request(url,data=data)
#发送第一次post请求,生成登陆后的cookie
response = opener.open(req)

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

#此时的opener已经包含了该链接下的cookie,此时使用该opener就可以直接访问该站点下其他的网页而不需要再登陆了
opener.open(http://www.renren.com/plogin.doxxxxxxxxxxxxx)

以上就是python爬虫基础之urllib的使用的详细内容,更多关于python 爬虫urllib的资料请关注其它相关文章!