Python爬虫02-Urllib库基本使用

Python爬虫02-Urllib库基本使用

2.1 Urllib库介绍

是Python内置的HTTP请求库,包含四个模块:

  • urllib.request:请求模板
  • urllib.error:异常处理模块
  • urllib.parse:url解析模块
  • urllib.robotparser:robots.txt解析模块

2.2 Urllib库的用法

2.2.1 urllib.request.urlopen

函数原型:urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)
函数参数介绍:

  • url 参数:目标资源在网路中的位置。
  • data参数:data用来指明发往服务器请求中的额外的信息(如:在线翻译,在线答题等提交的内容)
  • cafile、capath、cadefault 参数:用于实现可信任的CA证书的HTTP请求。(基本上很少用)
  • context参数:实现SSL加密传输。(基本上很少用)

把网页请求下来

  1. GET类型的请求
import urllib.request

response = urllib.request.urlopen('http://www.baidu.com')
print(response.read().decode('utf-8'))

运行结果:完整的源代码()
在这里插入图片描述
在这里插入图片描述
2. POST类型的请求

import urllib.parse
import urllib.request

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

运行结果:输出Json字符串
在这里插入图片描述
3. 超时的设置,GET类型的请求,若没肉在规定时间内没有得到相应则会抛出异常。响应时间设置为1s

import urllib.request

response = urllib.request.urlopen('http://httpbin.org/get', timeout=1)
print(response.read())

运行结果:
在这里插入图片描述
4。 超时的设置,GET类型的请求,若没肉在规定时间内没有得到相应则会抛出异常。响应时间设置为0.1s

import socket
import urllib.error
import urllib.request
try:
	response = urllib.request.urlopen('http://httpbin.org/get',timeout=0.1)
except urllib.error.URLError as e:
	if isinstance(e.reason,socket.timeout):
		print('TIME OUT')

运行结果:
在这里插入图片描述

2.2.2 响应

  1. 响应类型
import urllib.request

response = urllib.request.urlopen('https://www.python.org')
print(type(response))

运行结果:
在这里插入图片描述
2. 状态码、响应头

import urllib.request

response = urllib.request.urlopen('https://www.python.org')
print(response.status)
print(response.getheaders())
print(response.getheader('Server'))

运行结果:
在这里插入图片描述

2.2.3 urllib.request.Request

urlopen()方法可以实现最基本的发送,但这几个参数并不足以构建一个完整的请求,如果请求中需要加入Headers等信息,就可以利用更强大的Request。

函数原型:urllib.request.Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)
函数参数介绍:

  • url:访问的地址
  • data:此参数为可选字段,其中传递的参数需要转为bytes,如果是字典只需要通过 urllib.parse.urlencode 转换即可
  • headers:http相应headers传递的信息,构造方法:headers 参数传递,通过调用 Request 对象的 add_header() 方法来添加请求头
  • origin_req_host :指的是请求方的 host 名称或者 IP 地址
  • unverifiable :用来表明这个请求是否是无法验证的,默认是 False 。意思就是说用户没有足够权限来选择接收这个请求的结果。如果没有权限,这时 unverifiable 的值就是 True
  • method :用来指示请求使用的方法,比如 GET , POST , PUT 等
import urllib.request

request = urllib.request.Request('https://python.org')
response = urllib.request.urlopen(request)
print(response.read().decode('utf_8'))

运行结果:完整的源代码

在这里插入图片描述

from urllib import request,parse
url = 'http://httpbin.org/post'   # 请求URL
headers = {   # headers指定User-Agent,Host
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36',
    'Host':'httpbin.org'
}
dict = {
    'name':'Germey'
}
data = bytes(parse.urlencode(dict), encoding='utf8')  # 参数转化为字节流
req = request.Request(url=url, data=data, headers=headers, method='POST')  # 指定请求方式为POST
response = request.urlopen(req)
print(response.read().decode('utf-8'))

运行结果:
在这里插入图片描述

2.2.4 Handler

  1. 代理
    我们爬虫的时候肯定会有频繁访问某一网站的情况,这个时候有些服务器会识别到我们是非正常访问,就会把我们的IP禁掉,这个时候就需要用代理伪装自己的IP地址
from urllib.error import URLError
from urllib.request import ProxyHandler, build_opener
# 使用ProxyHandler构建一个字典,键名为协议,键值为代理链接,这里的代理可能无效了,链接可在网上百度
proxy_handler = ProxyHandler({
    'http':'http://127.0.0.1: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)

2.2.5 Cookie

Cookie是一个很小的文本文件,是浏览器储存在用户的机器上的。Cookie是纯文本,没有可执行代码。储存一些服务器需要的信息,每次请求站点,会发送相应的cookie,这些cookie可以用来辨别用户身份信息等作用。(可以叫做浏览器缓存)
Cookie在爬虫中是为了维持登录状态

import http.cookiejar, urllib.request   

#  获取Cookies
cookie = http.cookiejar.CookieJar()   # 声明一个CookieJar对象
handler = urllib.request.HTTPCookieProcessor(cookie)  # 利用HTTPCookieProcessor来构建一个Handler
opener = urllib.request.build_opener(handler) # 利用build_opener()方法构建出Opener
response = opener.open('http://www.baidu.com')  # 执行open()函数
for item in cookie: 
    print(item.name + "=" + item.value)

# 用MozillaCookieJar 保存cookies
filename = 'cookies1.txt'
cookie = http.cookiejar.MozillaCookieJar(filename)
handler = urllib.request.HTTPCookieProcessor(cookie)
opener = urllib.request.build_opener(handler)
response = opener.open('http://www.baidu.com')
cookie.save(ignore_discard = True, ignore_expires = True)

# 用LWPCookieJar 保存cookies
filename = 'cookies2.txt'
cookie = http.cookiejar.LWPCookieJar(filename)
handler = urllib.request.HTTPCookieProcessor(cookie)
opener = urllib.request.build_opener(handler)
response = opener.open('http://www.baidu.com')
cookie.save(ignore_discard = True, ignore_expires = True)

# 从文件中读取cookies
cookie = http.cookiejar.LWPCookieJar()
cookie.load('cookies2.txt', ignore_discard=True, ignore_expires=True)
handler = urllib.request.HTTPCookieProcessor(cookie)
opener = urllib.request.build_opener(handler)
response = opener.open('http://www.baidu.com')
print(response.read().decode('utf-8'))

2.2.6 解析链接

urllib的error模块定义了由request模块产生的异常,如果出现了问题,request模块会抛出error模块中定义的异常

  1. urlparse():拆分URL
  • url: 必填项,即待解析的URL
  • scheme: 它是默认的协议(比如http和https)
  • allow_fragments: 即是否忽略fragment
from urllib.parse import urlparse

result =urlparse('https://www.baidu.com/index.html;user?id=5#comment')
print(type(result), result)

result = urlparse('www.baidu.com/index.html;user?id=5#comment', scheme='https')
print(result)

result = urlparse('http://www.baidu.com/index.html;user?id=5#comment', scheme='https')
print(result)

result = urlparse('www.baidu.com/index.html;user?id=5#comment', allow_fragments=False)
print(result)

result = urlparse('www.baidu.com/index.html;user?id=5#comment', allow_fragments=True)
print(result)

result = urlparse('https://www.baidu.com/index.html#comment', allow_fragments=True)
print(result)

运行结果:
在这里插入图片描述
2. urlunparse():构造URL

from urllib.parse import urlunparse
data = ['http','www.baidu.com','index.html','user','a=6','comment']  # 长度必须为6
print(urlunparse(data))

运行结果:
在这里插入图片描述
3. urljoin():
我们可以提供一个base_url(基础链接)作为第一个参数,将新的链接作为第二个参数,该方法会分析base_url的scheme、netoc和path这3个内容并对新链接缺失的部分进行补充

from urllib.parse import urljoin

print(urljoin('http://www.baidu.com', 'FAQ.html'))
print(urljoin('http://www.baidu.com', 'https://cuiqingcai.com/FAQ.html'))  # 如果新的链接中有scheme、netoc和path,就用新的
print(urljoin('http://www.baidu.com/about.html', 'https://cuiqingcai.com/FAQ.html')) # base_url中的params、query和fragment不起作用
print(urljoin('http://www.baidu.com/about.html', 'https://cuiqingcai.com/FAQ.html?question=2'))
print(urljoin('http://www.baidu.com?wd=abc', 'https://cuiqingcai.com/index.php'))
print(urljoin('http://www.baidu.com', '?category=2#comment'))
print(urljoin('www.baidu.com', '?category=2#comment'))
print(urljoin('www.baidu.com#comment', '?category=2'))

运行结果:
在这里插入图片描述
3.urlencode():将字典转换为请求参数

from urllib.parse import urlencode

params = {
    'name': 'germey',
    'age': 22
}
base_url = 'http://www.baidu.com?'
url = base_url + urlencode(params)
print(url)

运行结果:
在这里插入图片描述

2.2.7 异常处理

  1. URLError
from urllib import  request,error

try:
    response = request.urlopen('https://blog.csdn.net/Daycym/article/details/11')   # 随便传入一个不存在的页面
except error.URLError as e:
    print(e.reason)   # 打印异常原因,不会报错

  1. HTTPError
    它是URLError的子类,专门用来处理HTTP请求错误,比如认证请求失败
  • code: 返回HTTP的状态码,比如404表示网页不存在,500表示服务器内部错误
  • reason: 同父类一样,用于返回错误的原因
  • headers: 返回请求头
from urllib import request, error

try:
    response = request.urlopen('https://blog.csdn.net/Daycym/article/details/11')
except error.HTTPError as e:
    print(e.reason, e.code, e.headers)   # 输出reason、code、headers属性


# 这是一个比较好的异常处理方法
# 可以先捕获子类异常再捕获父类异常
from urllib import request, error

try:
    response = request.urlopen('https://blog.csdn.net/Daycym/article/details/11')
except error.HTTPError as e:
    print(e.reason, e.code, e.headers)
except error.URLError as e:
    print(e.reason)
else:
    print('Request Successfully')


import socket
import urllib.request
import urllib.error

try:
    response = urllib.request.urlopen('https://www.baidu.com', timeout=0.1)
except urllib.error.URLError as e:
    print(type(e.reason))  # 有时候返回的不一定是字符串,也可能是对象
    if isinstance(e.reason, socket.timeout):
        print('TIME OUT')

猜你喜欢

转载自blog.csdn.net/qq_42145862/article/details/89800672
今日推荐