urlib库
urllib库是python中最基本的网络请求库,可以模拟浏览器的行为,向指定的服务器发送请求,并可以保存服务器返回的数据。
urlopen()
urllib.request模块提供了最基本的构造http请求的方法。利用它可以模拟浏览器的一个请求发起过程,同时它还带有处理授权验证(authentication)、重定向(redirection)、浏览器Cookies以及其他内容。
这里以Python官网为例,我们来把这个网页抓下来
- from urllib import request
- response = request.urlopen('https://www.python.org')
- print(response.read())
运行结果如下
这里我们只用了两行代码,便完成了Python官网的抓取,输出了网页的源代码。得到源代码之后呢?我们想要的链接、图片地址、文本信息不就可以提取出来了吗?
接下来,看下它返回的到底是什么。利用type()方法输出响应的类型:
- from urllib import request
- response = request.urlopen('https://www.python.org')
- print(type(response))
输出的结果如下:
- <class 'http.client.HTTPResponse'>
可以发现,它是一个HTTPResponse类型的对象,主要包含read(size)、readline()、readlines()、 readinto()、 getheader(name)、 getheaders()、 fileno()等方法, 以及msg、version、status、reason、debuglevel、colsed等属性。
得到这个对象之后,我们把它赋值为response变量,然后就可以调用这些方法和属性,得到返回结果的一系列信息了。
例如,调用read()方法可以得到返回的网页内容,调用status属性可以得到返回结果的状态码,如200代表请求成功,404代表网页未找到等。
利用最基本的urlopen()方法,可以完成最基本的简单网页的GET请求抓取。
如果想给链接传递一些参数,该怎么实现呢?首先看一下urlopen()函数的API:
urllib.request.urlopen(url, data=None, [timeout,]*, cafile=None, capath=None, cadefault=False, context=None)
可以发现,除了第一个参数可以传递url之外,我们还可以传递其他的内容,比如data(附加数据)、timeout(超时时间)等。
下面我们详细说明这几个参数的用法。
data参数
data参数是可选的。如果要添加该参数,需要使用bytes()方法将参数转化为字节流编码格式的内容,即bytes类型。另外,如果传递了这个参数,则它请求的方式就不再是GET方式,而是POST方式。
下面用实例来看一下:
- import urllib.parse
import urllib.request- data = bytes(urllib.parse.urlencode({'word': 'hello'}), encoding='utf8')
response = urllib.request.urlopen('http://httpbin.org/post', data=data)
print(response.read().decode('utf8'))
这里我们传递了一个参数word, 值是hello。它需要被转码成bytes类型。其中转字节流采用了bytes()方法,该方法的第一个参数需要str(字符串)类型,需要用urllib.parse模块里的urlencode()方法来将参数字典转化为字符串;第二个参数指定编码格式,这里指定为utf8。
这里请求的站点是httpbin.org,它可以提供HTTP请求测试。本次我们请求的URL为http://httpbin.org/post,这个链接可以用来测试POST请求,它可以输出请求的一些信息,其中包含我们传递的data参数。
运行结果如下:
- {
- "args": {},
- "data": "",
- "files": {},
- "form": {
- "word": "hello"
- },
- "headers": {
- "Accept-Encoding": "identity",
- "Content-Length": "",
- "Content-Type": "application/x-www-form-urlencoded",
- "Host": "httpbin.org",
- "User-Agent": "Python-urllib/3.7"
- },
- "json": null,
- "origin": "220.170.50.160, 220.170.50.160",
- "url": "https://httpbin.org/post"
- }
我们传递的参数出现在了form字段中,这表明是模拟了表单提交的方式,以POST方式传输数据。
timeout参数
timeout参数用于设置超时时间,单位为秒。意思就是如果请求超出了设置的这个时间,还没得到响应,就会抛出异常。如果不指定该参数,就会使用全局默认时间。它支持HTTP、HTTPS、FTP请求。
- import urllib.request
- response = urllib.request.urlopen('http://httpbin.org/get', timeout=0.1)
- print(response.read())
运行结果如下:
这里我们设置的超时时间是0.1,程序0.1秒过后,服务器依然没有响应,于是抛出了URLError异常,该异常属于urllib.error模块,错误原因是超时。
其他参数
除了data参数和timeout参数外,还有context参数,它必须是ssl.SSLContext类型,用来指定SSL设置。
此外,cafile和capath这两个参数分别指定CA证书和它的路径,这个在请求HTTPS链接会有用。
urlretrieve()
这个函数可以方便的将网页文件(源文件、图片、视频等)保存到本地,以下代码可以非常方便的将百度首页下载到本地
- from urllib import request
- resp = request.urlretrieve('http://www.baidu.com', 'baidu.html')
urlencode()
Ps:单个字符串编码应该使用quote()函数
我们用浏览器发送请求的时候,如果url中包含了中文或者其它特殊字符,那么浏览器会自动的给我们编码。所以当使用代码发送请求,我们需要手动的进行对这些字符进行编码,urlencode()这时候就排上用场了。urlencode()函数可以将存入的字典参数编码为URL查询字符串,即转换成以key1=value1&key2=value2的形式(特殊符号:汉字、&、=等特殊符号编码为%xx)。
- from urllib.parse import quote
- """特殊符号:汉字、&、=等特殊符号编码为%xx """
- KEYWORD = '苹果'
- url = 'https://s.taobao.com/search?q=' + quote(KEYWORD)
- print(url)
- #运行结果:https://s.taobao.com/search?q=%E8%8B%B9%E6%9E%9C
- KEYWORD = '='
- url = 'https://s.taobao.com/search?q=' + quote(KEYWORD)
- print(url)
- #运行结果:https://s.taobao.com/search?q=%3D
- """url标准符号:数字字母 """
- KEYWORD = 'ipad'
- url = 'https://s.taobao.com/search?q=' + quote(KEYWORD)
- print(url)
- #运行结果:https://s.taobao.com/search?q=ipad
- KEYWORD = ''
- url = 'https://s.taobao.com/search?q=' + quote(KEYWORD)
- print(url)
- #运行结果:https://s.taobao.com/search?q=3346778
- from urllib.parse import urlencode
- base_url = 'https://m.weibo.cn/api/container/getIndex?'
- """url标准符号:数字字母"""
- params1 = {
- "value":"english",
- 'page':1
- }
- url1 = base_url + urlencode(params1)
- print(urlencode(params1))
- print(url1)
- #运行结果
- #value=english&page=1
- #https://m.weibo.cn/api/container/getIndex?value=english&page=1
- """特殊符号:汉字,/,&,=,URL编码转化为%xx的形式"""
- params2 = {
- 'name':"王二",
- 'extra':"/",
- 'special':'&',
- 'equal':'='
- }
- url2 = base_url + urlencode(params2)
- print(urlencode(params2))
- print(url2)
- #运行结果
- #name=%E7%8E%8B%E4%BA%8C&extra=%2F&special=%26&equal=%3D
- #https://m.weibo.cn/api/container/getIndex?name=%E7%8E%8B%E4%BA%8C&extra=%2F&special=%26&equal=%3D
- print(type(urlencode(params2)))
- print(type(url2))
- #运行结果
- #<class 'str'>
- #<class 'str'>
parse_qs()
可以将编码后的url参数进行解码
- from urllib import parse
- params = {'name': '张三', 'age': 18, 'greet': 'hello world'}
- qs = parse.urlencode(params)
- result = parse.parse_qs(qs)
- print(result)
- #运行结果:
name=%E5%BC%A0%E4%B8%89&age=18&greet=hello+world
{'name': ['张三'], 'age': ['18'], 'greet': ['hello world']}
urlparse()和urlsplit()
有时候拿到一个url,要想对这个url各个组成部分进行分割,那么这时候可以使用urlpare()或者urlsplit()。示例代码如下:
- from urllib import parse
- url = 'http://www.baidu.com/s?wd=python&username=abc#1'
- result = parse.urlparse(url)
- print(result)
运行结果:
- ParseResult(scheme='http', netloc='www.baidu.com', path='/s', params='', query='wd=python&username=abc', fragment='')
我们也可以获取其中的某个属性值
- from urllib import parse
- url = 'http://www.baidu.com/s?wd=python&username=abc#1'
- result = parse.urlparse(url)
- print(result)
- print('scheme:', result.scheme)
- print('netloc:', result.netloc)
- print('path', result.path)
- print('params', result.params)
- print('query', result.query)
- print('fragment', result.fragment)
运行结果:
- ParseResult(scheme='http', netloc='www.baidu.com', path='/s', params='', query='wd=python&username=abc', fragment='')
- scheme: http
- netloc: www.baidu.com
- path /s
- params
- query wd=python&username=abc
- fragment 1
我们也可以用urlsplit()来进行分割,其结果和urlparse()运行的结果大致相同,唯一区别是urlsplit()的结果没有params这个属性
- from urllib import parse
- url = 'http://www.baidu.com/s?wd=python&username=abc#1'
- result = parse.urlsplit(url)
- print(result)
- print('scheme:', result.scheme)
- print('netloc:', result.netloc)
- print('path', result.path)
- # print('params', result.params)
- print('query', result.query)
- print('fragment', result.fragment)
运行结果:
- SplitResult(scheme='http', netloc='www.baidu.com', path='/s', query='wd=python&username=abc', fragment='')
- scheme: http
- netloc: www.baidu.com
- path /s
- query wd=python&username=abc
- fragment
request.Request
我们利用urlopen()方法可以显示最基本请求的发起,但这几个简单的参数 并不足以构建一个完整的请求。如果请求需要加入Headers等信息,就可以利用更 强大的Request类来构建。
首先,我们用实例来感受一下Request的用法:
- import urllib.request
- request = urllib.request.Request('http://python.org')
- response = urllib.request.urlopen(request)
- print(response.read().decode('utf8'))
可以发现,我们依然利用urlopen()方法来发送这个请求,只不过这个该方法不再是URL,而是一个Requeset类型的对象。通过构造这个数据结构,一方面我们可以将请求独立成一个对象,另一方面可更加丰富和灵活地配置参数。
它的构造方法如下:
class urllib.request.Request(url, data=None, headers={}, origin_req_host=None, univerifiable=False, method=None)
- 第一个参数url用于请求URL,这是必传参数,其他都是可选参数。
- 第二个参数data如果要传,必须传bytes(字节流)类型的,如果它是字典,可以先用urllib.parse模块里的urlencode()编码。
- 第三个参数是一个字典,它就是请求头,我们可以在构造请求时通过headers参数直接构造,也可以通过调用请求实例的add_header()方法添加。添加请求头常用的用法就是通过修改User-Agent来伪装浏览器,默认的User-Agent是Python-urllib,我们可以通过修改它来伪装浏览器。
- 第四个参数origin_req_host指的是请求方的host名称或者IP地址。
- 第五个参数unverifiable表示这个请求是否是无法验证的,默认是False,意思就是说 用户没有足够的 权限来选择接受这个请求的结果。例如我们请求一个HTML文档的图片,但是我们没有权限自动抓取图像的权限,这时unverifiable的值就是True。
- 第六个参数method是一个字符串,用来指示请求使用的方法。比如GET、POST和PUT等。
- from urllib import request
- from urllib import parse
- url = 'http://httpbin.org/post'
- headers = {
- 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36',
- 'Host': 'httpbin.org'
- }
- dict = {'name': 'Germey'}
- data = bytes(parse.urlencode(dict), encoding='utf8')
- req = request.Request(url=url, headers=headers, data=data, method='POST')
- response = request.urlopen(req)
- print(response.read().decode('utf8'))
这个我们通过4个参数构造了一个请求,运行结果如下:
- {
- "args": {},
- "data": "",
- "files": {},
- "form": {
- "name": "Germey"
- },
- "headers": {
- "Accept-Encoding": "identity",
- "Content-Length": "",
- "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/76.0.3809.100 Safari/537.36"
- },
- "json": null,
- "origin": "220.170.50.184, 220.170.50.184",
- "url": "https://httpbin.org/post"
- }
观察结果可以发现,我们成功设置了data、headers和method。
另外,headers也可以用add_header()方法来添加:
- req = request.Request(url=url, data=data, method='POST')
- req.add_header('User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36')
如此一来,我们就可以更加方便地构造请求,实现请求的发送。
ProxyHandler处理器(代理设置)
很多的网站会检测某一段时间某个IP的访问次数(通过流量统计,系统日志等),如果超过这个阈值,它会禁止这个IP的访问。所以我们可以设置一些代理服务器,每隔一段时间换一个代理,就算IP被禁止,依然可以换个IP继续爬取。urllib中通过ProxyHandler来设置代理服务器,下面代码说明如何自定义opener来使用代理。
- from urllib import request
- # 没有使用代理的
- url = 'http://httpbin.org/ip'
- # resp = request.urlopen(url)
- # print(resp.read())
- # 使用代理
- # 1,使用ProxyHandler,传入代理构建一个handler
- # 2. 使用上面创建的handler构建一个opener
- # 3. 使用opener发送一个请求
- handler = request.ProxyHandler({"http":"125.123.71.211:9999"})
opener = request.build_opener(handler)
resp = opener.open(url)
print(resp.read())
Ps:
- 代理的基本原理:代理实际上指的就是代理服务器,它的功能是代理网络用户去取得网络信息。形象地说,它是网络信息的中转站。
- http://httpbin.org 这个网站可以查看请求的一些参数
- ProxyHandler() 参数是一个字典,字典的key依赖于代理服务器能够接受的类型,一般是"http"或者是"https",值是“ip:port”
运行结果:
- b'{\n "origin": "125.123.71.211, 125.123.71.211"\n}\n'
常用的代理:
什么是cookie?
由于http请求是无状态的(HTTP无状态是指HTTP协议对事务处理是没有记忆能力的也就是说服务器不知道客户端是什么状态),也就是说即使第一次和服务器链接并成功登陆后,第二次访问服务器依然不知道当前请求是那个用户。cookie的出现就是为了解决这个问题,第一次登陆后服务器返回一些数据(cookie)给用户浏览器,浏览器将数据保存在本地,当用户发送再次请求时,浏览器会自动的把之前保存在本地的cookie数据发送给服务器,服务器根据用户发送的cookie就能辨别用户了。cookie储存的数据量有限,不同的浏览器有不同储存大小,但一般不超过4kb,因此使用cookie只能储存一些小量的数据。
cookie格式
Set-Cookie: NAME= VALUE; expires = DATE; path = PATH; domain = DOMAIN_NAME;SECURE
- NAME :cookie的名字
- value:cookie值
- expires:过期时间
- path:cookie作用的路径
- domain:cookie作用的域名
- secure:是否只在https下起作用
使用cookielib库和HTTPCookieProcessor模拟登陆
cookie指某些网站为了辨别用户身份们进行会话跟踪而储存在用户本地终端上的数据。Cookie可以保持登陆信息到下次与服务器的会话。
这里以人人网为例。人人网中,要访问个人主页,必须先登陆才能访问。那么我们想要用代码的方式访问,就必须要有正确的Cookie信息。解决的方法有两种,第一种是使用浏览器访问,然后将cookie信息复制下来,放到headers中,进而发送请求。示例代码如下:
urlib库的更多相关文章
- urlib库的使用
urlib库实际上不是很常用,因为其api调用复杂,已被requests模块取代. 1.request发送请求 from urllib import request #默认指定的是get请求 #url ...
- Python爬虫与数据分析之爬虫技能:urlib库、xpath选择器、正则表达式
专栏目录: Python爬虫与数据分析之python教学视频.python源码分享,python Python爬虫与数据分析之基础教程:Python的语法.字典.元组.列表 Python爬虫与数据分析 ...
- 3.爬虫 urlib库讲解 总结
urllib库的总结: 用ProcessOn(安利这个软件,够用了)根据前面的几节内容做了个思维导图. urllib库一共有四个模块: request:它是最基本的模块,可以用来模拟发送请求 erro ...
- 2.爬虫 urlib库讲解 异常处理、URL解析、分析Robots协议
1.异常处理 URLError类来自urllib库的error模块,它继承自OSError类,是error异常模块的基类,由request模块产生的异常都可以通过这个类来处理. from urllib ...
- 1.爬虫 urlib库讲解 Handler高级用法
在前面我们总结了urllib库的 urlopen()和Request()方法的使用,在这一小节我们要使用相关的Handler来实现代理.cookies等功能. 写在前面: urlopen()方法不支持 ...
- 0.爬虫 urlib库讲解 urlopen()与Request()
# 注意一下 是import urllib.request 还是 form urllib import request 0. urlopen() 语法:urllib.request.urlopen(u ...
- 基本urllib库
urlib库 urllib库是Python中一个最基本的网络请求库.可以模拟浏览器的行为,向指定的服务器发送一个请求,并可以保存服务器返回的数据. urlopen函数: 在Python3的urllib ...
- requests库的基本使用
1.发送get请求 import requests # response=requests.get('http://www.baidu.com') # 查看响应内容,返回的是已经解码的内容 # res ...
- Python爬虫与数据分析之模块:内置模块、开源模块、自定义模块
专栏目录: Python爬虫与数据分析之python教学视频.python源码分享,python Python爬虫与数据分析之基础教程:Python的语法.字典.元组.列表 Python爬虫与数据分析 ...
随机推荐
- jsp页面获取后台传过来的list集合的长度
在jsp页面导入函数标签库: <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"% ...
- 64位CreateProcess逆向:(二)0环下参数的整合即创建进程的整体流程
转载:https://bbs.pediy.com/thread-207683.htm 点击下面进入总目录: 64位Windows创建64位进程逆向分析(总目录) 在上一篇文章中,我们介绍了Create ...
- (转载) AutoML 与轻量模型大列表
作者:guan-yuan 项目地址:awesome-AutoML-and-Lightweight-Models 博客地址:http://www.lib4dev.in/info/guan-yuan/aw ...
- 导入一个eclipse的java项目到IDEA报Cannot find JDK '1.7' for module 'TEST'
解决办法: 右键你的项目--------------->OPen module settings 将dependencies里面的module sdk改成你安装的java版本就可以了(比如我电脑 ...
- snapde的批量数据运算公式
一.snapde基本介绍 Snapde,一个专门为编辑超大型数据量CSV文件而设计的单机版电子表格软件:它能打开最大3G大小的CSV文件进行编辑:它运行的速度非常快,反应非常灵敏. 二.snapde批 ...
- win10锁住鼠标和键盘操作。
以前做的一个winform自动更新程序没考虑到程序在更新过程中禁止操作被更新程序.现在加上了更新过程中锁住鼠标和大部分键盘. 碰到问题:用系统api -- BlockInput(true)锁住屏幕无效 ...
- LeetCode 328. 奇偶链表(Odd Even Linked List)
328. 奇偶链表 328. Odd Even Linked List 题目描述 给定一个单链表,把所有的奇数节点和偶数节点分别排在一起.请注意,这里的奇数节点和偶数节点指的是节点编号的奇偶性,而不是 ...
- 彩蛋(Python)-------都是细节
• python所有的符号全部是英文的符号• 数字和bool不支持迭代,列表支持• 列表有序,可变,支持索引• 元组有序,不可变,支持索引• 字典是无序的,可变的数据类型,不支持索引.• 集合,无值的 ...
- 函数的学习2——返回值&传递列表——参考Python编程从入门到实践
返回值 函数并非总是直接显示输出,相反,它可以处理一些数据,并返回一个或一组值.函数的返回值被称为返回值. 1. 简单的返回值 def get_formatted_name(first_name, l ...
- example
import pandas as pd import numpy as np import os,sys df = pd.read_excel("C:\\Users\\ryanzhang\\ ...