爬虫 :urllib库的用法,关于 request,parse模块总结

urllib库

它是python内置的请求库,包括 request ,error ,parse,robotparse。

这里主要介绍request 和parse模块。

request

它是HTTP请求模块,主要用来模拟发送请求。就像我们输入网址之后回车这样,这个模块提供一些参数,就可以模拟这个过程了。

1.urlopen()

urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)

用这个方法很简单,给这个方法传入一个url就可以请求网页,直接看代码

def urltest1():

    response = urllib.request.urlopen('https://www.python.org')  # 抓取python官网
    print(response.read().decode('utf-8'))    # 输出网页源码
    print(response.status)    # 查看返回结果的状态码
    print(response.getheaders())    # 查看相应的头信息
    print(response.getheader('Server')) # 查看响应头中的Server信息
    print(type(response.read()))    # 查看类型

if __name__ == '__main__':
    urltest1()
    pass

运行结果:

爬虫 :urllib库的用法,关于 request,parse模块总结_第1张图片

data参数

还可以给方法中的 data 传参, data为我们要传入的数据。这样一来,它的请求方式就不是GET,而是POST。也就是说模拟了表单提交的方式,以POST传输数据。

def urltest2():
    data = urllib.parse.urlencode({'word': 'hello'})  # urlencode将字典转字符串
    data = data.encode('utf-8')  # 转字节流
    response = urllib.request.urlopen('http://httpbin.org/post', data=data)
    print(response.read().decode('utf-8'))  # decode将字节流转为字符串

if __name__ == '__main__':
    # usecookies()
    urltest2()
    pass

运行结果:

{
  "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.7"
  }, 
  "json": null, 
  "origin": "119.101.46.252, 119.101.46.252", 
  "url": "https://httpbin.org/post"
}


Process finished with exit code 0
 

 可以发现,我们传递的参数出现在了form字段中。

timeout参数

timeout用于设定超时时间,若请求超时,则会报错抛出异常。我们抓取网页时可以设置这个超时时间,若长时间没响应就跳过这个页面。具体操作可以用 try except语句实现,这里不再展示代码。

其他参数

context : 用于指定SSL设置

cafile : 指定CA证书

capath : CA证书路径

cadefoult不用理会,已弃用

Request类

构成一个完整的请求,靠以上参数还不够。如果要加入Headers等信息,这就可以利用Request类

class urlib.request.Request( url, data= None , headers={}, origin_req_host = None, unverifiable=False, method=None)

首先解释一下每个参数的意思:

url:这个是必传参数,表示网页地址

data:字节流(bytes)类型,表示数据。如果要传的数据是字典,那么可以用 urllib.parse 模块中的urlencode编码。

headers:请求头。

origin_req_host :请求方的host名称或者IP地址

unverifiable:表示请求是否是无法验证的,,默认用户没有足够权限来选择接受这个请求的结果。

method:用来指示请求使用的方法

我们依然可以用urlopen这个方法发送请求,只不过这时候的参数变为了Request类的一个对象。

def urltest():
    url = 'http://httpbin.org/post'
    dic = {
        'name': 'Germey'
    }
    data = parse.urlencode(dic).encode('utf-8')  # data字节流
    headers = {    # 请求头
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36',
        'Host': 'httpbin.org'
    }
    req = request.Request(url=url,data=data,headers=headers,method='POST') # 构造一个Request对象
    response = request.urlopen(req)
    print(response.read().decode())

if __name__ == '__main__':
    # usecookies()
    urltest()
    pass

运行结果:

{
  "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/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36"
  }, 
  "json": null, 
  "origin": "119.101.46.252, 119.101.46.252", 
  "url": "https://httpbin.org/post"
}


Process finished with exit code 0
 

 Handler

虽然上面的操作能构造请求了,但是一些更高级的操作,比如cookies处理怎么办呢?这就有了更高级的工具Handler。handler是什么?handler可以理解为处理各种事务的工具,比如处理登陆验证,cookie,代理等。利用这个强大的工具我们基本能做到HTTP请求的所有事情。

首先介绍 BaseHandler类,它是所有Handler的父类。各种子类例如:

HTTPDefaultErrorHandler :处理HTTP响应错误。

HTTPRedirectHandler: 用于处理重定向

HTTPCookieProcessor:用于处理cookies

ProxyHandler:设置代理。

HTTPPasswordMgr:管理密码。

HTTPBasicAuthHandler:管理认证,如果链接需要认证,那么它可以解决认证问题。

那么我们再介绍和Handler密切相关的OpenerDirector类,称之为Opener。urlopen实际上就是一个opener。只不过我们现在需要更高级的功能,urlopen已经不能满足我们的需要,所以我们现在要深入一层进行配置,这样我们就要用到Opener。Opener可以使用open方法,返回类型和urlopen如出一辙。简而言之就是用handler构造opener。

我们以获取cookies和利用获取到的cookies创建请求为例,再来看看关于这种用法的实例:

def getcookies():
    # cookies处理
    filename = 'cookies.txt'  #路径
    # cookies = http.cookiejar.CookieJar()
    cookies = http.cookiejar.MozillaCookieJar(filename)  # cookie
    handler = urllib.request.HTTPCookieProcessor(cookies)   # 创建一个Handler
    opener = urllib.request.build_opener(handler)  # 用handler构建opener
    response = opener.open('http://www.baidu.com') # 打开链接
    cookies.save(ignore_discard=True, ignore_expires=True)  # 保存cookies文件

    filename1 = 'cookies1.txt'
    cookies1 = http.cookiejar.LWPCookieJar(filename1)  # LWP格式的cookie
    handler1 = urllib.request.HTTPCookieProcessor(cookies1)  # 创建一个Handler
    opener1 = urllib.request.build_opener(handler1)  # 用handler构建opener
    response1 = opener1.open('http://www.baidu.com')
    cookies1.save(ignore_discard=True, ignore_expires=True)  # 保存cookies文件
    for item in cookies:    # 打印cookies
        print(item.name + "=" + item.value)


def usecookies():
    # 从文件读取cookies
    cookies = http.cookiejar.LWPCookieJar()
    cookies.load('cookies1.txt', ignore_expires=True, ignore_discard=True)  # 读取本地的cookies文件
    handler = urllib.request.HTTPCookieProcessor(cookies)
    opener = urllib.request.build_opener(handler)
    response = opener.open('http://www.baidu.com')
    print(response.read().decode('utf-8'))  # 输出源码



 

getcookies运行结果是保存了两种格式的cookies文件和打印cookies文件:

爬虫 :urllib库的用法,关于 request,parse模块总结_第2张图片

爬虫 :urllib库的用法,关于 request,parse模块总结_第3张图片 爬虫 :urllib库的用法,关于 request,parse模块总结_第4张图片

usecookies读取了本地保存的cookies文件,运行得到了网站的源码。

parse

下面是parse模块的一些url处理方法,请看代码

def parsetest():
    # parse模块方法
    # 测试urlparse
    result = parse.urlparse('www.baidu.com/index.html;user?id=5#comment',scheme='https')
    # result 是一个元组,可以通过索引顺序获取,也可以用属性名获取
    print(result,result.scheme,result[0])
    # 测试urlunparse 可迭代对象长度为6
    data = ['http','www.baidu.com','index.html','user','id=5','comment']
    print(parse.urlunparse(data))
    # 测试urlsplit
    print(parse.urlsplit('http://www.baidu.com/index.html;user?id=5#comment'))
    # 测试urlunsplit 可迭代对象长度为5
    data =['http','www.baidu.com','index.html','id=5','comment']
    print(parse.urlunsplit(data))
    # urljoin 测试。第一个参数不完整就补充,第二个参数完整就用第二个参数
    print(parse.urljoin('www.baidu.com#comment','?category=2'))
    print(parse.urljoin('http://www.baidu.com','https://www.baidu.com/about.html'))
    # urlencode 测试
    params = {'name':'germy','age':22}
    base_url = 'http://www.baidu.com?'
    url = base_url+parse.urlencode(params)
    print(url)
    # parse_qs 反urlencode
    query ='name=germy&age=22'
    print(parse.parse_qs(query))
    #parse_qsl和parse_qs相似,返回类型为元组组成的列表
    print(parse.parse_qsl(query))
    # 将中文参数转化为url编码
    keyword = '中文'
    url = 'http://www.baidu.com/s?wd='+parse.quote(keyword)
    print(url)
    # unquote url解码为中文
    print(parse.unquote(url))


if __name__ == '__main__':
    # getcookies()
    parsetest()
    pass

运行结果:

ParseResult(scheme='https', netloc='', path='www.baidu.com/index.html', params='user', query='id=5', fragment='comment') https https
http://www.baidu.com/index.html;user?id=5#comment
SplitResult(scheme='http', netloc='www.baidu.com', path='/index.html;user', query='id=5', fragment='comment')
http://www.baidu.com/index.html?id=5#comment
www.baidu.com?category=2
https://www.baidu.com/about.html
http://www.baidu.com?name=germy&age=22
{'name': ['germy'], 'age': ['22']}
[('name', 'germy'), ('age', '22')]
http://www.baidu.com/s?wd=%E4%B8%AD%E6%96%87
http://www.baidu.com/s?wd=中文

Process finished with exit code 0
-----------------------------------------------------------------------------

博主发现这个库用起来太复杂,一般都用requests。。。

简单介绍到这里。Over~

 

你可能感兴趣的:(Python爬虫)