Mac 本 需导入 ssl
- import ssl
- ssl._create_default_https_context = ssl._create_unverified_context
urllib.request 模块 方法
从 urllib 中导入请求模块 编写 url
- from urllib import request # 导入 request 模块
- # 或者 import urllib.request
- url = "http://www.baidu.com/" # 编写 url
1. urlopen( ) 方法
用于打开一个远程的 url 连接, 并且向这个连接发出请求, 获取响应结果. 返回的结果是一个 http 响应对象, 这个响应对象中记录了本次 http 访问的响应头和响应体
urllib.request.urlopen 参数介绍:
urllib.request.urlopen( url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)
url 参数使用
- response = request.urlopen(url=url)
- print(response) # 获取响应, 结果为:<http.client.HTTPResponse object at 0x10be801d0>
- # 获取响应头
- print(response.headers) # 获取响应头
- print(response.url) # 获取响应 url
- print(response.status) # 获取响应状态码
- # 获取响应体
- print(response.read()) # 获取响应体 二进制字符串
- print(response.read().decode("utf-8")) # 对响应体进行解码
- # 按行读取
- print(response.readline()) # 读取一行
- print(response.readline()) # 读取下一行
- print( response.readlines()) # 读取多行. 得到一个列表 每个元素是一行
data 参数使用
上述例子是通过 get 请求 获得百度, 下面使用 urllib 的 post 请求.
添加 data 参数的时候就是以 post 请求方式请求, 若没有 data 参数就是 get 请求方式
- import urllib.request
- import urllib.parse # urllib.parse 模块, 后面有介绍
- #或者 from urllib import request, parse
- data = bytes(urllib.parse.urlencode({'word': 'hello'}), encoding='utf8')
- # 用 urllib.parse 模块, 通过 bytes(urllib.parse.urlencode()) 可以将 post 数据进行转换并放到 urllib.request.urlopen 的 data 参数中. 这样就完成了一次 post 请求.
- response = urllib.request.urlopen('http://httpbin.org/post', data=data)
- print(response.read())
timeout 参数使用
在某些网络情况不好或者服务器端异常的情况会出现请求慢的情况, 或者请求异常, 所以这个时候我们需要给
请求设置一个超时时间, 而不是让程序一直在等待结果. 所以使用 timeout 参数设置超时时间
- import urllib.request
- response = urllib.request.urlopen('http://httpbin.org/get', timeout=1)
- print(response.read()) # 正常结束, 控制台显示: socket.time : timed out
- response = urllib.request.urlopen('http://httpbin.org/get', timeout=0.1)
- print(response.read()) # 超时, 控制台显示: urllib.error.URLErrot : <urlopen error timed out>
2. urlretrieve(url ="xxx", filename = "xxx") 方法
打开 url 这个连接 并且发起请求, 获得响应并把响应结果保存到 filename 文件中
- res3 = request.urlretrieve(url=url,filename="./baidu.html")
- print(res3) # 获取 url 保存到 baidu.HTML 文件中 并打印
3. Request(url=url, data=data, method='POST') 方法
web 开发中, 同一个 url 往往可以对应若干套不同的数据 (或者界面, 如手机, 电脑), 后台可以根据发起请求的前端的用户代理的不同, 而决定应该给前端做出什么样的响应, 如果检测到没有用户代理可以拒绝访问.
有很多网站为了防止程序爬虫爬网站造成网站瘫痪, 会需要携带一些 headers 头部信息才能访问, 最长见的有 user-agent 参数所以需要伪装请求头, 去访问目标站.
urllib.ruquest.Request 参数介绍:
urllib.ruquest.Request(url=url,headers=headers,data=data,method='POST')
headers 参数使用
给请求添加头部信息, 定制自己请求网站时的头部信息, 使得请求伪装成浏览器等终端
- req = request.Request(url=url,headers={'UserAgent':'Mozilla/5.0 (Windows NT 10.0; Win64;x64)AppleWebKit/537.36 (KHTML, likeGecko)Chrome/71.0.3578.80Safari/537.36'})
- res = request.urlopen(req) # 用加入了请求头的请求对象发起请求
- print(res.status) # 打印状态码
添加请求头的 post 请求方式
- from urllib import request, parse
- url = 'http://httpbin.org/post'
- headers = {
- 'User-Agent': 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)',
- 'Host': 'httpbin.org'}
- dict = { 'name': 'taotao'}
- data = bytes(parse.urlencode(dict), encoding='utf8')
- req = request.Request(url=url, data=data, headers=headers, method='POST')
- response = request.urlopen(req)
- print(response.read().decode('utf-8')
添加请求头的第二种 post 方式, 好处是自己可以定义一个请求头字典, 然后循环进行添加
- from urllib import request, parse
- url = 'http://httpbin.org/post'
- dict = {'name': 'Germey'}
- data = bytes(parse.urlencode(dict), encoding='utf8')
- req = request.Request(url=url, data=data, method='POST')
- req.add_header('User-Agent', 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)')
- response = request.urlopen(req)
- print(response.read().decode('utf-8'))
4. rulllib.request.ProxyHandler( ) 方法
高级用法 - 代理: 各种 handler 代理
rulllib.request.ProxyHandler( ) 方法设置代理
urllib.request.build_opener(handler) 创建一个 opener 携带 handler
opener.open(req) 用 opener 发起请求
设置代理, 网站它会检测某一段时间某个 IP 的访问次数, 如果访问次数过多它会禁止访问, 所以这个时候需要通过设置代理来爬取数据
- import urllib.request,urllib.parse
- url = "https://www.baidu.com/s?wd=ip"
- headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36'}
- req = urllib.request.Request(url=url,headers=headers) # 创建一个请求对象
- handler = urllib.request.ProxyHandler( # 创建一个 handler
- {"http":'122.241.88.79:15872'
- "https":'122.241.88.79:15872'})
- opener = urllib.request.build_opener(handler) # 创建一个 opener 携带 handler
- res = opener.open(req) # 用 opener 发起请求
- with open("ip.html",'wb') as fp:
- fp.write(res.read())
会话处理机制
cookie 中保存中我们常见的登录信息, 有时候爬取网站需要携带 cookie 信息访问, 这里用到了 http.cookijar, 用于获取 cookie 以及存储 cookie
「采用 handler+opener 机制处理会话问题」导入 cookie 初始化工具, 处理 cookie 的时候这个对象就可以存储 cookie 信息
- from urllib import request,parse
- from http import cookiejar
- cookie = cookiejar.CookieJar() # 初始化一个 cookie 对象
- handler = request.HTTPCookieProcessor(cookie) # 创建一个 handler 对象, 携带上 cookie
- opener = request.build_opener(handler) # 创建一个 opener 对象携带上 handler
- response = opener.open('http://www.baidu.com') # 用 opener 来发起请求
- print(response.read().decode('utf-8')) # 此时发起的请求结束以后, 相关的 cookie 信息就会被 opener 的 handler 通过 cookiejar 对象保存
cookie 写入到文件中保存
方式一: http.cookiejar.MozillaCookieJar( ) 方式
- import http.cookiejar, urllib.request
- filename = "cookie.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)
方式二: http.cookiejar.LWPCookieJar( ) 方式
- import http.cookiejar, urllib.request
- filename = 'cookie.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)
cookie 从文件中读取, 用哪种方式写入的, 就用哪种方式读取
方法: cookie.load( ) 方式
- import http.cookiejar, urllib.request
- cookie = http.cookiejar.LWPCookieJar()
- cookie.load('cookie.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'))
urllib.parse 模块 方法
url 解析模块
1. urlparse( ) 方法 拆分 url
URL 解析函数侧重于将 URL 字符串拆分为其组件, 或者将 URL 组件组合为 URL 字符串
拆分的时候协议类型部分就会是 scheme=" " 指定的部分. 如果 url 里面已经带了协议, scheme 指定的协议不会生效
- urllib.parse.urlparse(urlstring, scheme=" ", allow_fragments=True)
- urlparse("www.baidu.com/index.html;user?id=5#comment",scheme="https")
- from urllib.parse import urlparse
- # 对传入的 url 地址进行拆分; 可以用 scheme=" " 指定协议类型:
- result = urlparse("http://www.baidu.com/index.html;user?id=5#comment")
- print(result)
结果:
2. urlunparse( ) 方法 拼接 url
功能和 urlparse 的功能相反, 它是用于拼接
- from urllib.parse import urlunparse
- data = ['http','www.baidu.com','index.html','user','a=123','commit']
- print(urlunparse(data))
3. urljoin( ) 方法 拼接 url
拼接的时候后面的优先级高于前面的 url
- from urllib.parse import urljoin
- print(urljoin('http://www.baidu.com', 'FAQ.html'))
- # 结果 :http://www.baidu.com/FAQ.html
- print(urljoin('http://www.baidu.com', 'https://pythonsite.com/FAQ.html'))
- # 结果 :https://pythonsite.com/FAQ.html
- print(urljoin('http://www.baidu.com/about.html', 'https://pythonsite.com/FAQ.html'))
- # 结果 :https://pythonsite.com/FAQ.html
- print(urljoin('http://www.baidu.com', '?category=2#comment'))
- # 结果 :http://www.baidu.com?category=2#comment
- print(urljoin('www.baidu.com#comment', '?category=2'))
- # 结果 :www.baidu.com?category=2
4. urlencode( ) 方法
这个方法可以将字典转换为 url 参数
对 url 进行编码, 因为 urllib 这个框架中的 url 中不能出现汉字, 只能出现 ascii 码字符
- from urllib import parse
- url = "https://www.baidu.com/s?"
- # 把参数写成字典的形式
- dic= {"ie":"utf-8","wd":"奔驰"}
- # 用 parse 的 urlencode 方法编码
- parames = parse.urlencode(dic)
- # 将编码以后的参数拼接到 url 中
- url += parames
- print(request.urlopen(url=url))
urllib.error 模块 方法
有时候通过程序访问页面的时候, 有的页面可能会出现类似 404,500 等错误
这时就需要我们捕捉异常, 在 urllb 异常中有两个异常错误: URLError 和 HTTPError.HTTPError 是 URLError 的子类
1. error.URLError 异常
URLError 里只有一个属性: reason, 即抓异常的时候只能打印错误信息
- from urllib import request,error
- try:
- response = request.urlopen("http://pythonsite.com/1111.html")
- except error.URLError as e:
- print(e.reason)
2. error.HTTPError 异常
HTTPError 里有三个属性: code,reason,headers, 即抓异常的时候可以获得 code,reson,headers 三个信息
- from urllib import request,error
- try:
- response = request.urlopen("http://pythonsite.com/1111.html")
- except error.HTTPError as e:
- print(e.code)
- print(e.reason)
- print(e.headers)
- except error.URLError as e:
- print(e.reason)
- else:
- print("reqeust successfully")
来源: http://www.bubuko.com/infodetail-3051525.html