精华内容
下载资源
问答
  • 爬虫基础——HTTP基本原理爬虫基础——网页基础爬虫的基本原理爬虫基础——会话和Cookie爬虫基础——代理的基本原理urllib库的作用在爬虫的基本原理中,我们已经讲过,爬虫的第一个步骤是获取网页,urllib库就是用来...

    阅读提示

    理解本文内容需要具备python基础知识爬虫基础知识(HTML、JS)

    爬虫基础可参考以往文章:

    爬虫基础——HTTP基本原理

    爬虫基础——网页基础

    爬虫的基本原理

    爬虫基础——会话和Cookie

    爬虫基础——代理的基本原理

    urllib库的作用

    在爬虫的基本原理中,我们已经讲过,爬虫的第一个步骤是获取网页,urllib库就是用来实现这个功能:向服务器发送请求,得到服务器响应,获取网页的内容。

    Python的强大就在于提供了功能齐全的类库,来帮助我们完成这个请求,通过调用urllib库,我们不需要了解请求的数据结构,HTTP、TCP、IP层的网络传输通信,以及服务器应答原理等等。

    我们只需要关心以下三点,然后通过几行调用urllib库的代码,就能够获得我们想要的网页内容。

    • 请求的URL是什么
    • 传递的参数是什么
    • 如何设置可选的请求头

    urllib库的构成

    在python2中,曾经有urllib和urllib2两个库来实现请求的发送,但目前通用的python3版本中,两个库的功能已经合并成一个库,统一为urllib,它是python内置函数,不需要额外安装即可使用。

    urllib的四个模块

    466f094410cc7dc04832a0770890948c.png

    【1】requsetHTTP请求模块,可以用来模拟发送请求,只需要传入URL及额外参数,就可以模拟浏览器访问网页的过程。

    【2】error异常处理模块,检测请求是否报错,捕捉异常错误,进行重试或其他操作,保证程序不会终止。

    【3】parse工具模块,提供许多URL处理方法,如拆分、解析、合并等。

    【4】robotparser:识别网站的robots.txt文件,判断哪些网站可以爬,哪些网站不可以爬,使用频率较少。

    发送请求

    1.urlopen( )

    urlopen是request模块中的方法,用于抓取网页。

    官方文档:(https://docs.python.org/3/library/urllib.request.html

    下面以代码举例,我们抓取百度的网页。

    代码示例

    import 

    df112e73ec97865071959a9724f36c71.png

    返回的结果比较多,随便截取其中一部分,可以看出是百度的网页HTML源代码。

    a071661dcd7791b1cd65ac37973996e1.png

    我们只用几行代码,就完成了百度的抓取,并打印了网页的源代码,接下来,我们看一看我们获得的响应内容response到底是什么?利用type()方法来输出响应的类型

    import 

    9283ff62c54fa7b386e0ea291748abd0.png

    输出结果如下:

    35b21f429166bee64417ba2cd1b90fdf.png

    它是一个HTTPResponse类型的对象

    包含方法:read()、readinto()、getheader()、getheaders()、fileno()等

    包含属性:msg、version、status、reason、debuglevel、closed等属性。

    通过调用以上的方法和属性,就能返回我们所需的信息。

    比如一开始我们打印获取网页内容时,就用到了read()方法。

    调用status属性则可以得到返回结果的状态码,200代表强求成功,404代表网页未找到等。

    再看一个代码示例加深理解:

    import 

    0779f57fef2303ca25425c30b3fad8de.png

    返回结果:

    31f2dd3816ce5956bf059484ca4b9f3b.png

    在打印的三行代码中

    第一行输出了响应的状态码(200代表正常)

    第二行输出了响应的头信息

    第三行通过调用getheader()方法并传递参数Server,获取了第二行响应头信息中的Server对应的值BWS/1.1。

    参数

    利用基本的urlopen()方法可以完成最基本的简单网页GET方法抓取。

    如果想达成更复杂一些的任务,需要给链接传递一些参数,该如何实现?

    urlopen()的函数原型如下:

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

    除了第一个参数传递URL之外,我们还可以传递其参数,比如data(附加数据)、timeout(超时时间)等。

    data参数

    data用来指明发往服务器请求中的额外的参数信息,data默认是None,此时以GET方式发送请求;当用户给出data参数的时候,改为POST方式发送请求

    data参数是可选的,如果要添加该参数,需要使用bytes()方法将参数转化为二进制数据。

    还是通过代码示例理解:

    import 

    4d3171ecda259936856fefc79c47895e.png

    首页这里请求的站点是http://httpbin.org,它是一个HTTP请求测试网站,记住它后面举例会经常用到它。

    这次我们要使用post方式请求,而不是get,因为post是需要携带表单信息的(类似登陆的用户名和密码)所以我们要在urlopen函数中传递data参数。

    前面讲了data参数必须是bytes型。

    bytes()这个方法第一个参数需要str(字符串类型),这里就需要用到urllib库的parse模块里的urlencode()方法来将参数字典转化为字符串。第二个参数是指定编码格式,这里指定为utf-8。

    运行结果如下:

    4bbb34fe9a7972040e67f11888f351c5.png

    可以看到,我们传递的参数data中的字典键值对"word":"hello"出现在了form字段中,这表明了表单提交的方式,以POST方式传输数据。

    timeout参数

    timeout参数用于设置超时时间,单位为秒,意思是如果请求时间超过了设置的时间,还没有得到响应,就会抛出异常,在实际爬虫中,我们要对许多URL发起请求,中途肯定会出现爬取异常的URL,短时间无法获得响应,我们需要识别出这种异常,就需要用到timeout参数。

    如果不指定timeout参数,会使用全局默认时间。它支持HTTP、HTTPS、FTP请求。

    通过代码示例理解:

    import 

    1158d4910f34d31871a499e59a6e8c37.png

    这里我们把timeout参数设成0.01秒,网页反应时间是没这么快的,所以一定会报错,我们来看一下报错的信息:

    139d3597a691cc2654fad589dafb8ac8.png

    直接看结尾红框部分,显示异常属于urllib.error模块,错误原因是超时。

    在实际爬虫中,我们可以用过设置这个超时时间来控制一个网页在长时间未响应时,就跳过它的抓取。这可以利用try except 语句来实现。

    代码示例:

    import 

    30a8d25ce593edd3a40f31bf18b4870c.png

    在代码中加入try except 语句后,如果响应超时,便会跳过抓取,我们捕获了URLError异常后,接着判断异常是socket.timeout类型(意思就是超时异常),于是打印出了time out !

    输出结果如下:

    1973be5bf7ba88f1bc1a4348d35e5d14.png

    其他参数(少用)

    context参数:它必须是ssl.SSLContext类型,用来指定SSL设置,实现SSL加密传输

    cafile、capath:分别指定CA证书和它的路径,用于实现可信任的CA证书的HTTP请求。

    cadefault:已经弃用,默认False。

    2.Requset

    上文已经讲解了如何利用urlopen()方法实现最基本的请求发起。但这几个简单的参数并不足以构建一个完整的请求(过于简单的请求会被浏览器识别为爬虫而拒绝响应)。如果请求中需要加入Headers等信息,就需要用到Requset类来构建。

    同样通过实例展示Request用法:

    import 

    13bbae9665d05b8d27c17686276d9f34.png

    我们依然是用urlopen()方法来发送请求,只是这次的参数不再是url,而是一个Request类型对象。通过构造这个数据结构,我们可以将请求独立为一个对象,并且更灵活的配置参数。

    Request的函数原型如下:

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

    下面来看它的具体参数:

    url:用于请求URL,这是必传参数,其他都是可选参数。

    data:必须是bytes类型,如果它是字典,可以先用urllib.parse模块里的urlencode方法编码。(用于POST请求)

    headers:是一个字典,它就是请求头,我们可以在构造请求时,通过headers参数直接构造,也可以通过调用请求示例的add_header()方法添加。

    origin_req_host :指的是请求方的host名称或IP地址。

    unverifiable:表示这个请求是否无法验证,默认为False,意思是说用户没有足够权限来选择接收这个请求的结果。比如我们请求一个HTML文档中的图片,但是我们没有自助抓取图象的权限,这是unverifiable的值就是True。

    method:是一个字符串,用来指示请求使用方法,如GET、POST、PUT等。

    下面我们给Request传入多个参数构建请求为例进行理解:

    import 

    34f544f55f150e32cf8d1b6d60d1045a.png

    在这个示例中,我们通过4个参数构造了一个请求,我们加入了url、data、headers、method,其中最重要的是把头信息(包含User-Agent和Host)写入了Request,让请求变得更完整。

    运行结果如下:

    b1e9ed338e95dc9473496b978d59eae6.png

    可以看到,我们成功通过新建的参数,设置了data、headers 和 method。

    另外之前提到的headers也可以用add_header()方法添加,示例代码如下:

    req 

    3.高级用法

    在上面的过程中,我们虽然可以构造请求,但是对于一些更高级的操作,比如Cookie处理、代理设置等,我们还需要借助Handler工具。

    本部分内容相对硬核,初学者可以跳过,笔者后续有使用到再更新。

    本文总结参考《Python3网络爬虫开发实战》

    展开全文
  • 一.urllib库urllib是Python自带一个用于爬虫库,其主要作用就是可以通过代码模拟浏览器发送请求。其常被用到子模块在Python3中为urllib.request和urllib.parse,在Python2中是urllib和urllib2。二.由易到难...

    一.urllib库

    urllib是Python自带的一个用于爬虫的库,其主要作用就是可以通过代码模拟浏览器发送请求。其常被用到的子模块在Python3中的为urllib.request和urllib.parse,在Python2中是urllib和urllib2。

    二.由易到难的爬虫程序:

    1.爬取百度首页面所有数据值

    #!/usr/bin/env python#-*- coding:utf-8 -*-#导包

    importurllib.requestimporturllib.parseif __name__ == "__main__":#指定爬取的网页url

    url = 'http://www.baidu.com/'

    #通过urlopen函数向指定的url发起请求,返回响应对象

    reponse = urllib.request.urlopen(url=url)#通过调用响应对象中的read函数,返回响应回客户端的数据值(爬取到的数据)

    data = reponse.read()#返回的数据为byte类型,并非字符串

    print(data)#打印显示爬取到的数据值。

    补充说明:

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

    在上述案例中我们只使用了该函数中的第一个参数url。在日常开发中,我们能用的只有url和data这两个参数。

    url参数:指定向哪个url发起请求

    data参数:可以将post请求中携带的参数封装成字典的形式传递给该参数(暂时不需要理解,后期会讲)

    urlopen函数返回的响应对象,相关函数调用介绍:

    response.headers():获取响应头信息

    response.getcode():获取响应状态码

    response.geturl():获取请求的url

    response.read():获取响应中的数据值(字节类型)

    2.将爬取到百度新闻首页的数据值写入文件进行存储

    #!/usr/bin/env python#-*- coding:utf-8 -*-

    importurllib.requestimporturllib.parseif __name__ == "__main__":

    url= 'http://news.baidu.com/'reponse= urllib.request.urlopen(url=url)#decode()作用是将响应中字节(byte)类型的数据值转成字符串类型

    data =reponse.read().decode()#使用IO操作将data表示的数据值以'w'权限的方式写入到news.html文件中

    with open('./news.html','w') as fp:

    fp.write(data)print('写入文件完毕')

    3.爬取网络上某张图片数据,且存储到本地

    #!/usr/bin/env python#-*- coding:utf-8 -*-

    importurllib.requestimporturllib.parse#如下两行代码表示忽略https证书,因为下面请求的url为https协议的请求,如果请求不是https则该两行代码可不用。

    importssl

    ssl._create_default_https_context=ssl._create_unverified_contextif __name__ == "__main__":#url是https协议的

    url = 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1536918978042&di=172c5a4583ca1d17a1a49dba2914cfb9&imgtype=0&src=http%3A%2F%2Fimgsrc.baidu.com%2Fimgad%2Fpic%2Fitem%2F0dd7912397dda144f04b5d9cb9b7d0a20cf48659.jpg'reponse= urllib.request.urlopen(url=url)

    data= reponse.read()#因为爬取的是图片数据值(二进制数据),则无需使用decode进行类型转换。

    with open('./money.jpg','wb') as fp:

    fp.write(data)print('写入文件完毕')

    4.url的特性:url必须为ASCII编码的数据值。所以我们在爬虫代码中编写url时,如果url中存在非ASCII编码的数据值,则必须对其进行ASCII编码后,该url方可被使用。

    案例:爬取使用百度根据指定词条搜索到的页面数据(例如爬取词条为‘周杰伦’的页面数据)

    #!/usr/bin/env python#-*- coding:utf-8 -*-

    importurllib.requestimporturllib.parseif __name__ == "__main__":#原始url中存在非ASCII编码的值,则该url无法被使用。

    #url = 'http://www.baidu.com/s?ie=utf-8&kw=周杰伦'

    #处理url中存在的非ASCII数据值

    url = 'http://www.baidu.com/s?'

    #将带有非ASCII的数据封装到字典中,url中非ASCII的数据往往都是'?'后面键值形式的请求参数

    param ={'ie':'utf-8','wd':'周杰伦'}#使用parse子模块中的urlencode函数将封装好的字典中存在的非ASCII的数值进行ASCII编码

    param =urllib.parse.urlencode(param)#将编码后的数据和url进行整合拼接成一个完整可用的url

    url = url +paramprint(url)

    response= urllib.request.urlopen(url=url)

    data=response.read()

    with open('./周杰伦.html','wb') as fp:

    fp.write(data)print('写入文件完毕')

    5.通过自定义请求对象,用于伪装爬虫程序请求的身份。

    之前在讲解http常用请求头信息时,我们讲解过User-Agent参数,简称为UA,该参数的作用是用于表明本次请求载体的身份标识。如果我们通过浏览器发起的请求,则该请求的载体为当前浏览器,则UA参数的值表明的是当前浏览器的身份标识表示的一串数据。如果我们使用爬虫程序发起的一个请求,则该请求的载体为爬虫程序,那么该请求的UA为爬虫程序的身份标识表示的一串数据。有些网站会通过辨别请求的UA来判别该请求的载体是否为爬虫程序,如果为爬虫程序,则不会给该请求返回响应,那么我们的爬虫程序则也无法通过请求爬取到该网站中的数据值,这也是反爬虫的一种初级技术手段。那么为了防止该问题的出现,则我们可以给爬虫程序的UA进行伪装,伪装成某款浏览器的身份标识。

    上述案例中,我们是通过request模块中的urlopen发起的请求,该请求对象为urllib中内置的默认请求对象,我们无法对其进行UA进行更改操作。urllib还为我们提供了一种自定义请求对象的方式,我们可以通过自定义请求对象的方式,给该请求对象中的UA进行伪装(更改)操作。

    #!/usr/bin/env python#-*- coding:utf-8 -*-

    importurllib.requestimporturllib.parseimportssl

    ssl._create_default_https_context=ssl._create_unverified_contextif __name__ == "__main__":#原始url中存在非ASCII编码的值,则该url无法被使用。

    #url = 'http://www.baidu.com/s?ie=utf-8&kw=周杰伦'

    #处理url中存在的非ASCII数据值

    url = 'http://www.baidu.com/s?'

    #将带有非ASCII的数据封装到字典中,url中非ASCII的数据往往都是'?'后面键值形式的请求参数

    param ={'ie':'utf-8','wd':'周杰伦'}#使用parse子模块中的urlencode函数将封装好的字典中存在的非ASCII的数值进行ASCII编码

    param =urllib.parse.urlencode(param)#将编码后的数据和url进行整合拼接成一个完整可用的url

    url = url +param#将浏览器的UA数据获取,封装到一个字典中。该UA值可以通过抓包工具或者浏览器自带的开发者工具中获取某请求,从中获取UA的值

    headers={'User-Agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'}#自定义一个请求对象

    #参数:url为请求的url。headers为UA的值。data为post请求的请求参数(后面讲)

    request = urllib.request.Request(url=url,headers=headers)#发送我们自定义的请求(该请求的UA已经进行了伪装)

    response =urllib.request.urlopen(request)

    data=response.read()

    with open('./周杰伦.html','wb') as fp:

    fp.write(data)print('写入数据完毕')

    展开全文
  • 爬虫之urllib库

    2019-01-10 16:31:00
    一.urllib库简介 简介 Urllib是Python内置HTTP请求库。其主要作用就是可以通过代码模拟浏览器发送请求。它包含四个模块: urllib.request :请求模块 urllib.error :异常处理模块 urllib.parse url : ...

    一.urllib库简介

    简介

    Urllib是Python内置的HTTP请求库。其主要作用就是可以通过代码模拟浏览器发送请求。它包含四个模块:

    urllib.request :请求模块
    urllib.error :异常处理模块
    urllib.parse url : 解析模块
    urllib.robotparser :robots.txt解析模块,用的比较少

    相比Python2与3变化:

    其常被用到的子模块在Python3中的为urllib.request和urllib.parse,在Python2中是urllib和urllib2。

    Python2: import urllib2 response=urllib2.urlopen(‘http://www.baidu.com’)
    Python3: import urllib.request response=urllib.request.urlopen(‘http://www.baidu.com’)

    二.使用简介:

    parse 

    用于url解析转换

    dic = {'wd': '赵丽颖'}
    ps = parse.urlencode(dic)
    print(ps)  # wd=%E8%B5%B5%E4%B8%BD%E9%A2%96
    print(parse.parse_qs(ps))  # {'wd': ['赵丽颖']}

     

    urlopen

    这个函数很简单,就是请求一个url的内容。其实这就是爬虫的第一步:网页请求,获取内容。

        urllib.request.urlopen(url, 
                               data=None,
                               [timeout] *,
                               cafile=None,
                               capath=None,
                               cadefault=False,
                               context=None)
        # urlopen前三个分别是(网站,网站的数据,超时设置,主要前两个其他不常用)

     

    可以看到,这个函数可以有非常多的参数,前三个用的最多,我们来逐一看看。

    1.url参数

    import urllib.request
    response =urllib.request.urlopen('http://www.baidu.com') #把请求的结果传给response
    print(response.read().decode('utf-8')) #转换成字符串
    print(response.read(10).decode('utf-8')) #只读取10个
    print(response.readline().decode('utf-8')) #只读取一行

    在交互模式下执行以上命令就可以打印出百度首页的源代码了。
    这是一种GET类型的请求,只传入了一个参数(url)。
    下面演示一种POST类型的请求:

    2.data参数
    示例代码:

    import urllib.parse
    import urllib.request
    
    data=bytes(urllib.parse.urlencode({'word':'hello'}),encoding='utf8')
    #需要传入一个data参数,需要的是bytes类型,这里用了urlencode方法传入一个字典,并指定编码
    response=urllib.request.urlopen('http://httpbin.org/post',data=data)
    #给urlopen函数传入两个参数,一个是url,一个是data
    print(response.read())

    (http://httpbin.org/ 是一个HTTP测试页面)
    可以看到打印出了一些Json字符串:

    我们可以从打印结果看到,我们成功的把’word’:'hello’这个字典通过urlopen函数以POST形式把它传递过去了。这样我们就完成了一个POST的请求。
    总结:加了data参数就是以POST形式发送请求,否则就是GET方式了。

    3.timeout
    再来看看第三个参数:超时时间。如果超过了这个时间没有得到响应的话,就会抛出异常。
    示例代码:

    import urllib.request
    response=urllib.request.urlopen('http://httpbin.org/get',timeout=1)#设置超时时间
    print(response.read())

    再看另一种情况,我们把超时时间设置为0.1:

    import socket
    import urllib.request
    import urllib.error
    
    try:
    response=urllib.request.urlopen('http://httpbin.org/get',timeout=0.1)
    #必须在0.1秒内得到响应,否则就会抛出异常
    except urllib.error.URLError as e:
    if isinstance(e.reason,socket.timeout):#类型判断,如果是超时错误,那么打印
    print('TIME OUT')

    响应(response)

    获取响应类型:type()
    示例:

    import urllib.request
    response =urllib.request.urlopen('https://www.python.org')
    print(type(response))#打印响应的类型

    通过调用这个方法我们可以看到响应的类型。

    状态码、响应头
    一个响应里面包含了两个比较有用的信息:状态码和响应头。

    以上面提到的http://httpbin.org/ 为例,我们可以在审查中,找到状态码和响应头(上图红框所示)。
    这两个信息是判断响应是否成功的非常重要的标志。
    在这里我们可以用status参数获取响应的状态码,用getheaders()方法获取响应头。
    示例:

    import urllib.request
    
    response =urllib.request.urlopen('https://www.python.org')
    print(response.status)#状态码
    print(response.getheaders())#响应头
    print(response.getheader('Server'))#可以取得响应头中特定的信息

    另外,关于read()方法,它获取的是响应体中的内容(bytes形式)

    import urllib.request
    response =urllib.request.urlopen('https://www.python.org')
    print(response.read().decode('utf-8'))#将字节流解码为utf-8

    请求(request)

    如果我们要在请求中加入别的信息怎么办呢?用上面的urlopen函数是无法满足的。
    例如我们要在请求中加上Headers参数,但是urlopen函数中是没有提供这个参数的。
    如果我们想要发送一些更为复杂的请求的话,比如加上Headers,怎么办呢?
    那么我可以创建一个request对象——使用Request(它也是属于urllib.request模块的)。
    来看示例:

    import urllib.request
    request=urllib.request.Request('https://python.org')#把url构造成一个request对象
    response=urllib.request.urlopen(request)#再把request对象传给urlopen
    print(response.read().decode('utf-8'))

    这样也可以成功实现请求。
    有了这样的方法,我们就能更方便地指定请求的方式,还可以加一些额外的数据。
    那么现在尝试构造一个POST请求,并且把headers加进来。

    from urllib import request,parse
    #构造一个POST请求
    url='http://httpbin.org/post'
    headers={
        'Users-Agent':'..............',
        'Host':'httpbin.org'
    }
    dic={
        'name':'iron'
    }
    data=bytes(parse.urlencode(dic),encoding='utf8')#fontdata数据
    req=request.Request(url=url,data=data,headers=headers,method='POST')#构建一个Request()的一个结构
    response = request.urlopen(req)
    print(response.read().decode('utf-8'))

    我们把以上代码写成一个py文件并运行:

     

    可以看到,我们构造的Request包含了之前所提到的信息,请求的时候我们是把Request当成一个整体传递给了urlopen,就可以实现这样的请求了。
    好处是整个Request的结构是非常清晰的。
    此外还有另外一种实现方式,就是用add_header()方法,也可以实现相同的效果:

    from urllib import request, parse

    # 构造一个POST请求
    url = 'http://httpbin.org/post'

    dic = {
    'name': 'iron'
    }
    data = bytes(parse.urlencode(dict), encoding='utf8') # fontdata数据
    req = request.Request(url=url, data=data, method='POST') # 构建一个Request()的一个结构
    req.add_header('User-Angent', '................')
    req.add_header('Host', 'httpbin.org')
    response = request.urlopen(req)
    print(response.read().decode('utf-8'))

    add_header() 方法作为添加header的另一种方式,可以用来比较复杂的情况,比如要添加许多键值对,那么可以用一个for循环来不断调用这个方法,这也是比较方便的。

    urlretrieve

    直接打开url并写到本地

    request.urlretrieve('http://www.baidu.com', 'baidu.html')

     例如直接下载图片或者视频

    url = input('你想下载的视频或图片链接:')
    
    request.urlretrieve(url, 'binfile')

     

    Headler

    Headler相当于一个辅助工具,来帮助我们处理一些额外的工作,比如FTP、Cache等等操作,我们都需要借助Headler来实现。比如在代理设置的时候,就需要用到一个ProxyHandler。更多的用法,请参阅官方文档。

    1.代理
    用来对ip地址进行伪装成不同地域的,防止ip在爬虫运行时被封掉。
    示例:

    from urllib import request
    proxy_handler = request.ProxyHandler( #构建ProxyHandler,传入代理的网址
    {'http':'http://127.0.0.1:9743',
    'https':'https://127.0.0.1:9743'
    }) #实践表明这个端口已经被封了,这里无法演示了
     
    opener = request.build_opener(proxy_handler)#再构建一个带有Handler的opener
     
    response = opener.open('http://www.baidu.com')
    print(response.read())

    2.Cookie
    Cookie是在客户端保存的用来记录用户身份的文本文件。
    在爬虫时,主要是用来维护登录状态,这样就可以爬取一些需要登录认证的网页了。


    实例演示:

    from urllib import request
     
    from http import cookiejar
    cookie =cookiejar.CookieJar()#将cookie声明为一个CookieJar对象
     
    handler = request.HTTPCookieProcessor(cookie)
     
    opener = request.build_opener(handler)
     
    response  =opener.open('http://www.baidu.com')#通过opener传入,并打开网页
     
    for item in cookie:#通过遍历把已经赋值的cookie打印出来
        print(item.name+'='+item.value)#通过item拿到每一个cookie并打印

    3.Cookie的保存
    我们还可以把cookie保存成文本文件,若cookie没有失效,我们可以从文本文件中再次读取cookie,在请求时把cookie附加进去,这样就可以继续保持登录状态了。
    示例代码:

    from urllib import request
    from http import cookiejar
    
    filename="cookie.txt"
    cookie=cookiejar.MozillaCookieJar(filename)
    #把cookie声明为cookiejar的一个子类对象————MozillaCookieJar,它带有一个save方法,可以把cookie保存为文本文件
    handler=request.HTTPCookieProcessor(cookie)
    opener=request.build_opener(handler)
    response=opener.open('http://www.baidu.com')
    cookie.save(ignore_discard=True,ignore_expires=True)#调用save方法

    执行代码后,我们就可以在运行目录下找到已经保存好的cookie文本文件了:

     

    还有另外一种格式:
    在上面那段代码的基础上,换一个子类对象就可以了:

    cookie=cookiejar.LWPCookieJar(filename)

    可以看到,这次生了一个不同格式的cookie文本文件:

    4.Cookie的读取

    我们可以选择相对应的格式来完成读取。以上面的LWP格式为例:

    from urllib import request
    from http import cookiejar
    
    
    cookie=cookiejar.LWPCookieJar() #z注意选择相应的格式,这里是LWP
    cookie.load('cookie.txt',ignore_discard=True,ignore_expires=True)#load方法是读取的关键
    handler=request.HTTPCookieProcessor(cookie)
    opener=request.build_opener(handler)
    response=opener.open('http://www.baidu.com')
    print(response.read().decode('utf-8'))

    以上的代码就可以完成读取了。这样,我们就可以在对网页进行请求时,自动把之前的cookie附着进去,以保持一个登录的状态了。

    异常处理

    这是属于urllib的另一大模块。

    rom urllib import request,error
    
    #我们试着访问一个不存在的网址
    try:
        response = request.urlopen('http://www.cuiqingcai.com/index.html')
    except error.URLError as e:
        print(e.reason)#通过审查可以查到我们捕捉的异常是否与之相符

    可以看到,返回了错误信息。这样的异常处理可以保证爬虫在工作时不会轻易中断。
    那么,urllib可以捕捉哪些异常呢?详见官方文档。
    其实一般碰到有两个:HTTP和URL。我们一般只需要捕捉这两个异常就可以了。

    from urllib import request,error
    
    #我们试着访问一个不存在的网址
    try:
        response = request.urlopen('http://www.cuiqingcai.com/index.html')
    except error.HTTPError as e:#最好先捕捉HTTP异常,因为这个异常是URL异常的子类
        print(e.reason,e.code,e.headers,sep='\n')
    except error.URLError as e:
        print(e.reason)
    else:
        print('Request Successfully!')

    打印出错误的相关信息。
    此外,e.reason也是一个类,它可以得到异常的类型。
    我们试着看看:

    from urllib import request,error
    import socket
    
    
    try:
        response = request.urlopen('http://www.baidu.com',timeout = 0.01)#超时异常
    except error.URLError as e:
        print(type(e.reason))
        if isinstance(e.reason,socket.timeout):#判断error类型
            print('TIME OUT')

    异常类型被打印出来了,确实是超时异常。

    URL解析

    这是一个工具性质的模块,即拿即用就行。

    1.urlparse
    这个方法将将url进行分割,分割成好几个部分,再依次将其复制。

    urllib.parse.urlparse(urlstring,scheme='',allow_fragments = True)
    #分割成(url,协议类型,和#后面的东西)

    来看具体的例子:

    from urllib.parse import urlparse
     
    result = urlparse('https://www.baidu.com/s?wd=urllib&ie=UTF-8')
    print(type(result),result)  #<class 'urllib.parse.ParseResult'>
     
    #无协议类型指定,自行添加的情况
    result1 = urlparse('www.baidu.com/s?wd=urllib&ie=UTF-8',scheme = 'https')
    print(result1)
     
    #有指定协议类型,默认添加的情况?
    result2 = urlparse('http://www.baidu.com/s?wd=urllib&ie=UTF-8',scheme = 'https')
    print(result2)
    
    #allow_fragments参数使用
    result3 = urlparse('http://www.baidu.com/s?#comment',allow_fragments = False)
     
    result4 = urlparse('http://www.baidu.com/s?wd=urllib&ie=UTF-8#comment',allow_fragments = False)
    print(result3,result4)
    #allow_fragments=False表示#后面的东西不能填,原本在fragment位置的参数就会往上一个位置拼接,可以对比result1和result2的区别

    从这个例子我们也可以知道,一个url可以分成6个字段。

    2.urlunparse(urlparse的反函数)
    这个函数用来拼接url。
    看看这个例子:

    from urllib.parse import urlunparse
    #注意即使是空符号也要写进去,不然会出错
    
    data = ['http',  'www.baidu.com', 'index.html','user','a=6' 'comment']
    print(urlunparse(data))

    3.urljoin

    这个函数用来拼合url。
    通过例子感受以下:
    以后面的参数为基准,会覆盖掉前面的字段。如果后面的url,存在空字段而前面的url有这个字段,就会用前面的作为补充。

    from urllib.parse import urljoin
    print(urljoin('http://www.baidu.com','FQA.html'))
    #http://www.baidu.com/FQA.html
     
    print(urljoin('http://www.baidu.com','http://www.caiqingcai.com/FQA.html'))
    #http://www.caiqingcai.com/FQA.html
     
    print(urljoin('https://www.baidu.com/about.html','http://www.caiqingcai.com/FQA.html'))
    #http://www.caiqingcai.com/FQA.html
     
    print(urljoin('http://www.baidu.com/about.html','https://www.caiqingcai.com/FQA.html'))
    #https://www.caiqingcai.com/FQA.html

    4.urlencode
    这个函数用来将字典对象转化为get请求参数。

    from urllib.parse import urlencode
     
    params = {
    'name':'zhuzhu',
    'age':'23'
    }
     
    base_url = 'http://www.baidu.com?'
     
    url = base_url+urlencode(params)#将params对象编码转换
     
    print(url)

    robotparser

    用来解析robot.txt。用的比较少,这里不再赘述。

    三.由易到难的爬虫程序:

    1.爬取百度首页面所有数据值

     1 #!/usr/bin/env python 
     2 # -*- coding:utf-8 -*-
     3 #导包
     4 import urllib.request
     5 import urllib.parse
     6 if __name__ == "__main__":
     7     #指定爬取的网页url
     8     url = 'http://www.baidu.com/'
     9     #通过urlopen函数向指定的url发起请求,返回响应对象
    10     reponse = urllib.request.urlopen(url=url)
    11     #通过调用响应对象中的read函数,返回响应回客户端的数据值(爬取到的数据)
    12     data = reponse.read()#返回的数据为byte类型,并非字符串
    13     print(data)#打印显示爬取到的数据值。
    #补充说明
    urlopen函数原型:urllib.request.urlopen(url, data=None, timeout=<object object at 0x10af327d0>, *, cafile=None, capath=None, cadefault=False, context=None)
    
    在上述案例中我们只使用了该函数中的第一个参数url。在日常开发中,我们能用的只有url和data这两个参数。
    
    url参数:指定向哪个url发起请求
    data参数:可以将post请求中携带的参数封装成字典的形式传递给该参数(暂时不需要理解,后期会讲)
    
    urlopen函数返回的响应对象,相关函数调用介绍:
    response.headers():获取响应头信息
    response.getcode():获取响应状态码
    response.geturl():获取请求的url
    response.read():获取响应中的数据值(字节类型)

    2.将爬取到百度新闻首页的数据值写入文件进行存储

    #!/usr/bin/env python 
    # -*- coding:utf-8 -*-
    import urllib.request
    import urllib.parse
    if __name__ == "__main__":
        url = 'http://news.baidu.com/'
        reponse = urllib.request.urlopen(url=url)
        #decode()作用是将响应中字节(byte)类型的数据值转成字符串类型
        data = reponse.read().decode()
        #使用IO操作将data表示的数据值以'w'权限的方式写入到news.html文件中
        with open('./news.html','w') as fp:
            fp.write(data)
        print('写入文件完毕')

    3.爬取网络上某张图片数据,且存储到本地

    #!/usr/bin/env python 
    # -*- coding:utf-8 -*-
    import urllib.request
    import urllib.parse
    #如下两行代码表示忽略https证书,因为下面请求的url为https协议的请求,如果请求不是https则该两行代码可不用。
    import ssl
    ssl._create_default_https_context = ssl._create_unverified_context
    
    if __name__ == "__main__":
        #url是https协议的
        url = 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1536918978042&di=172c5a4583ca1d17a1a49dba2914cfb9&imgtype=0&src=http%3A%2F%2Fimgsrc.baidu.com%2Fimgad%2Fpic%2Fitem%2F0dd7912397dda144f04b5d9cb9b7d0a20cf48659.jpg'
        reponse = urllib.request.urlopen(url=url)
        data = reponse.read()#因为爬取的是图片数据值(二进制数据),则无需使用decode进行类型转换。
        with open('./money.jpg','wb') as fp:
            fp.write(data)
        print('写入文件完毕')

      4.url的特性:

      url必须为ASCII编码的数据值。所以我们在爬虫代码中编写url时,如果url中存在非ASCII编码的数据值,则必须对其进行ASCII编码后,该url方可被使用。

      案例:爬取使用百度根据指定词条搜索到的页面数据(例如爬取词条为‘周杰伦’的页面数据)

    import urllib.request
    import urllib.parse
    
    if __name__ == "__main__":
        #原始url中存在非ASCII编码的值,则该url无法被使用。使用会报错需要转码
        #url = 'http://www.baidu.com/s?ie=utf-8&wd=赵丽颖'
        #处理url中存在的非ASCII数据值
        url = 'http://www.baidu.com/s?'
        #将带有非ASCII的数据封装到字典中,url中非ASCII的数据往往都是'?'后面键值形式的请求参数
        param = {
            'ie':'utf-8',
            'wd':'赵丽颖'
        }
        #使用parse子模块中的urlencode函数将封装好的字典中存在的非ASCII的数值进行ASCII编码
        param = urllib.parse.urlencode(param)
        #将编码后的数据和url进行整合拼接成一个完整可用的url
        url = url + param
        print(url)
        response = urllib.request.urlopen(url=url)
        data = response.read()
        with open('./赵丽颖.html','wb') as fp:
            fp.write(data)
        print('写入文件完毕')

     

    5.通过自定义请求对象,用于伪装爬虫程序请求的身份。

        之前在讲解http常用请求头信息时,我们讲解过User-Agent参数,简称为UA,该参数的作用是用于表明本次请求载体的身份标识。如果我们通过浏览器发起的请求,则该请求的载体为当前浏览器,则UA参数的值表明的是当前浏览器的身份标识表示的一串数据。如果我们使用爬虫程序发起的一个请求,则该请求的载体为爬虫程序,那么该请求的UA为爬虫程序的身份标识表示的一串数据。有些网站会通过辨别请求的UA来判别该请求的载体是否为爬虫程序,如果为爬虫程序,则不会给该请求返回响应,那么我们的爬虫程序则也无法通过请求爬取到该网站中的数据值,这也是反爬虫的一种初级技术手段。那么为了防止该问题的出现,则我们可以给爬虫程序的UA进行伪装,伪装成某款浏览器的身份标识。

        上述案例中,我们是通过request模块中的urlopen发起的请求,该请求对象为urllib中内置的默认请求对象,我们无法对其进行UA进行更改操作。urllib还为我们提供了一种自定义请求对象的方式,我们可以通过自定义请求对象的方式,给该请求对象中的UA进行伪装(更改)操作。

    import urllib.request
    import urllib.parse
    
    import ssl
    ssl._create_default_https_context = ssl._create_unverified_context  # 证书相关
    
    if __name__ == "__main__":
        #原始url中存在非ASCII编码的值,则该url无法被使用。
        #url = 'http://www.baidu.com/s?ie=utf-8&wd=赵丽颖'
        #处理url中存在的非ASCII数据值
        url = 'http://www.baidu.com/s?'
        #将带有非ASCII的数据封装到字典中,url中非ASCII的数据往往都是'?'后面键值形式的请求参数
        param = {
            'ie':'utf-8',
            'wd':'赵丽颖'
        }
        #使用parse子模块中的urlencode函数将封装好的字典中存在的非ASCII的数值进行ASCII编码
        param = urllib.parse.urlencode(param)
        #将编码后的数据和url进行整合拼接成一个完整可用的url
        url = url + param
        #将浏览器的UA数据获取,封装到一个字典中。该UA值可以通过抓包工具或者浏览器自带的开发者工具中获取某请求,从中获取UA的值
        headers={
            'User-Agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'
        }
        #自定义一个请求对象
        #参数:url为请求的url。headers为UA的值。data为post请求的请求参数(后面讲)
        request = urllib.request.Request(url=url,headers=headers)
    
        #发送我们自定义的请求(该请求的UA已经进行了伪装)
        response = urllib.request.urlopen(request)
    
        data=response.read()
    
        with open('./赵丽颖.html','wb') as fp:
            fp.write(data)
        print('写入数据完毕')

     

    转载于:https://www.cnblogs.com/clbao/p/10250799.html

    展开全文
  • urllib 是 Python 标准中用于网络请求的。该有四个模块,分别是:urllib.requesturllib.errorurllib.parseurllib....urllib.request 的作用不仅仅是发起请求, 还能获取请求返回结果。发起请求,单靠 urlopen...

    urllib 是 Python 标准库中用于网络请求的库。

    该库有四个模块,分别是:

    urllib.request

    urllib.error

    urllib.parse

    urllib.robotparser

    1 发起请求

    模拟浏览器发起一个 HTTP 请求,我们需要用到 urllib.request 模块。urllib.request 的作用不仅仅是发起请求, 还能获取请求返回结果。发起请求,单靠 urlopen() 方法就可以叱咤风云。我们先看下 urlopen() 的 API:

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

    data 是 bytes 类型的内容,可通过 bytes()函数转为化字节流。它也是可选参数。使用 data 参数,请求方式变成以 POST 方式提交表单。使用标准格式是application/x-www-form-urlencoded

    timeout 参数是用于设置请求超时时间。单位是秒。

    cafile和capath代表 CA 证书和 CA 证书的路径。如果使用HTTPS则需要用到。

    context参数必须是ssl.SSLContext类型,用来指定SSL设置

    该方法也可以单独传入urllib.request.Request对象

    该函数返回结果是一个http.client.HTTPResponse对象。

    使用 urllib.request.urlopen() 去请求百度贴吧,并获取到它页面的源代码。

    importurllib.request

    url= "http://tieba.baidu.com"response=urllib.request.urlopen(url)

    html= response.read() #获取到页面的源代码

    print(html.decode('utf-8')) #转化为 utf-8 编码

    1.2 设置请求超时

    有些请求可能因为网络原因无法得到响应。因此,我们可以手动设置超时时间。当请求超时,我们可以采取进一步措施,例如选择直接丢弃该请求或者再请求一次。

    importurllib.request

    url= "http://tieba.baidu.com"response= urllib.request.urlopen(url, timeout=1)print(response.read().decode('utf-8'))

    1.3 使用 data 参数提交数据

    在请求某些网页时需要携带一些数据,我们就需要使用到 data 参数。

    importurllib.parseimporturllib.request

    url= "http://www.baidu.com/"params={'name':'TTT','author':'Miracle'}

    data= bytes(urllib.parse.urlencode(params), encoding='utf8')

    response= urllib.request.urlopen(url, data=data)print(response.read().decode('utf-8'))

    params 需要被转码成字节流。而 params 是一个字典。我们需要使用 urllib.parse.urlencode() 将字典转化为字符串。再使用 bytes() 转为字节流。最后使用 urlopen() 发起请求,请求是模拟用 POST 方式提交表单数据。

    注意:当url地址含有中文或者“/”的时候,这是就需要用做urlencode一下编码转换。urlencode的参数是词典,它可以将key-value这样的键值对转换成我们想要的格式

    1.4 使用 Request

    由上我们知道利用 urlopen() 方法可以发起简单的请求。但这几个简单的参数并不足以构建一个完整的请求,如果请求中需要加入headers(请求头)、指定请求方式等信息,我们就可以利用更强大的Request类来构建一个请求。

    按照国际惯例,先看下 Request 的构造方法:

    urllib.request.Request(url, data=None, headers={}, origin_req_host=None,

    unverifiable=False, method=None)

    data 参数跟 urlopen() 中的 data 参数用法相同。

    headers 参数是指定发起的 HTTP 请求的头部信息。headers 是一个字典。它除了在 Request 中添加,还可以通过调用 Reques t实例的 add_header() 方法来添加请求头。

    origin_req_host 参数指的是请求方的 host 名称或者 IP 地址。

    unverifiable表示请求是否是无法验证的,默认False。意思就是说用户没有足够权限来选择接收这个请求的结果。例如我们请求一个HTML文档中的图片,但是我们没有自动抓取图像的权限,我们就要将 unverifiable 的值设置成 True。

    method 参数指的是发起的 HTTP 请求的方式,有 GET、POST、DELETE、PUT等

    1.4.1 简单使用 Request

    使用 Request 伪装成浏览器发起 HTTP 请求。如果不设置 headers 中的 User-Agent,默认的User-Agent是Python-urllib/3.5。可能一些网站会将该请求拦截,所以需要伪装成浏览器发起请求。我使用的 User-Agent 是 Chrome 浏览器。

    #修改User-Agent为chrome的UA进行伪装

    importurllib.request

    url= "http://tieba.baidu.com/"headers={'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36'}

    request= urllib.request.Request(url=url, headers=headers)

    response=urllib.request.urlopen(request)print(response.read().decode('utf-8'))

    1.4.2 Request 高级用法

    如果我们需要在请求中添加代理、处理请求的 Cookies,我们需要用到Handler和OpenerDirector。

    1) Handler

    Handler 的中文是处理者、处理器。 Handler 能处理请求(HTTP、HTTPS、FTP等)中的各种事情。它的具体实现是这个类 urllib.request.BaseHandler。它是所有的 Handler 的基类,其提供了最基本的Handler的方法,例如default_open()、protocol_request()等。

    继承 BaseHandler 有很多个,我就列举几个比较常见的类:

    ProxyHandler:为请求设置代理

    HTTPCookieProcessor:处理 HTTP 请求中的 Cookies

    HTTPDefaultErrorHandler:处理 HTTP 响应错误。

    HTTPRedirectHandler:处理 HTTP 重定向。

    HTTPPasswordMgr:用于管理密码,它维护了用户名密码的表。

    HTTPBasicAuthHandler:用于登录认证,一般和 HTTPPasswordMgr 结合使用。

    2) OpenerDirector

    对于 OpenerDirector,我们可以称之为 Opener。我们之前用过 urlopen() 方法,实际上它就是 urllib 为我们提供的一个Opener。那 Opener 和 Handler 又有什么关系?opener 对象是由 build_opener(handler)方法来创建出来 。我们需要创建自定义的 opener,就需要使用 install_opener(opener)方法。值得注意的是,install_opener 实例化会得到一个全局的 OpenerDirector 对象。

    1.5 使用代理

    我们已经了解了 opener 和 handler,接下来我们就通过示例来深入学习。第一个例子是为 HTTP 请求设置代理

    有些网站做了浏览频率限制。如果我们请求该网站频率过高。该网站会被封 IP,禁止我们的访问。所以我们需要使用代理来突破这“枷锁”。

    importurllib.request

    url= "http://tieba.baidu.com/"headers={'User-Agent': 'Mozilla/5.0 AppleWebKit/537.36 Chrome/56.0.2924.87 Safari/537.36'}

    proxy_handler=urllib.request.ProxyHandler({'http': 'web-proxy.oa.com:8080','https': 'web-proxy.oa.com:8080'})

    opener=urllib.request.build_opener(proxy_handler)

    urllib.request.install_opener(opener)

    request= urllib.request.Request(url=url, headers=headers)

    response=urllib.request.urlopen(request)print(response.read().decode('utf-8'))

    1.6 认证登录

    有些网站需要携带账号和密码进行登录之后才能继续浏览网页。碰到这样的网站,我们需要用到认证登录。我们首先需要使用 HTTPPasswordMgrWithDefaultRealm() 实例化一个账号密码管理对象;然后使用 add_password() 函数添加账号和密码;接着使用 HTTPBasicAuthHandler() 得到 hander;再使用 build_opener() 获取 opener 对象;最后使用 opener 的 open() 函数发起请求。

    第二个例子是携带账号和密码请求登录博客园,代码如下:

    importurllib.request

    url= "http://cnblogs.com/xtznb/"user= '奇迹'password= 'password'pwdmgr=urllib.request.HTTPPasswordMgrWithDefaultRealm()

    pwdmgr.add_password(None,url,user,password)

    auth_handler=urllib.request.HTTPBasicAuthHandler(pwdmgr)

    opener=urllib.request.build_opener(auth_handler)

    response=opener.open(url)print(response.read().decode('utf-8'))

    1.7 Cookies设置

    如果请求的页面每次需要身份验证,我们可以使用 Cookies 来自动登录,免去重复登录验证的操作。获取 Cookies 需要使用 http.cookiejar.CookieJar() 实例化一个 Cookies 对象。再用 urllib.request.HTTPCookieProcessor 构建出 handler 对象。最后使用 opener 的 open() 函数即可。

    第三个例子是获取请求百度贴吧的 Cookies 并保存到文件中,代码如下:

    importhttp.cookiejarimporturllib.request

    url= "http://tieba.baidu.com/"fileName= 'cookie.txt'cookie=http.cookiejar.CookieJar()

    handler=urllib.request.HTTPCookieProcessor(cookie)

    opener=urllib.request.build_opener(handler)

    response=opener.open(url)

    f= open(fileName,'a')for item incookie:

    f.write(item.name+"="+item.value+'\n')

    f.close()

    1.8 HTTPResponse

    从上面的例子可知, 使用 urllib.request.urlopen() 或者 opener.open(url) 返回结果是一个 http.client.HTTPResponse 对象。它具有 msg、version、status、reason、debuglevel、closed等属性以及read()、readinto()、getheader(name)、getheaders()、fileno()等函数。

    2 错误解析

    发起请求难免会出现各种异常,我们需要对异常进行处理,这样会使得程序比较人性化。

    异常处理主要用到两个类,urllib.error.URLError和urllib.error.HTTPError。

    URLError

    URLError 是 urllib.error 异常类的基类, 可以捕获由urllib.request 产生的异常。

    它具有一个属性reason,即返回错误的原因。

    捕获 URL 异常的示例代码:

    importurllib.requestimporturllib.error

    url= "http://www.google.com"

    try:

    response=request.urlopen(url)excepterror.URLError as e:print(e.reason)

    HTTPError HTTPError 是 UEKRrror 的子类,专门处理 HTTP 和 HTTPS 请求的错误。它具有三个属性。

    1)code:HTTP 请求返回的状态码。

    2)reason:与父类用法一样,表示返回错误的原因。

    3)headers`:HTTP 请求返回的响应头信息。

    获取 HTTP 异常的示例代码, 输出了错误状态码、错误原因、服务器响应头

    importurllib.requestimporturllib.error

    url= "http://www.google.com"

    try:

    response=request.urlopen(url)excepterror.HTTPError as e:print('code:' + e.code + '\n')print('reason:' + e.reason + '\n')print('headers:' + e.headers + '\n')

    2.urllib.response

    (在使用urlopen()方法或者opener的open()方法发起请求后,获得的结果是一个response对象。这个对象有一些方法和属性,可以让我们对请求返回的结果进行一些处理。)

    geturl() :返回获取的真实的URL,这个很有用,因为 urlopen(或者 opener 对象使用的)或许会有重定向。获取的 URL 或许跟请求 URL 不同。

    info() :这个返回对象的字典对象,该字典描述了获取的页面情况。通常是服务器发送的特定头 headers。

    read():获取响应返回的数据,只能使用一次。

    getcode():获取服务器返回的状态码。

    getheaders():获取返回响应的响应报头。

    3.urllib.parse

    (urllib.parse是urllib中用来解析各种数据格式的模块)

    1. urllib.parse.quote

    在url中,是只能使用ASCII中包含的字符的,也就是说,ASCII不包含的特殊字符,以及中文等字符都是不可以在url中使用的。而我们有时候又有将中文字符加入到url中的需求,例如百度的搜索地址:https://www.baidu.com/s?wd=南北。?之后的wd参数,则是我们搜索的关键词。那么我们实现的方法就是将特殊字符进行url编码,转换成可以url可以传输的格式,urllib中可以使用quote()方法来实现这个功能。

    from urllib importparse

    keyword= '南北'parse.quote(keyword)=======>>'%E5%8D%97%E5%8C%97'

    #如果需要将编码后的数据转换回来,可以使用unquote()方法。

    parse.unquote('%E5%8D%97%E5%8C%97')=======>>'南北'

    2. urllib.parse.urlencode

    在访问url时,我们常常需要传递很多的url参数,而如果用字符串的方法去拼接url的话,会比较麻烦,所以urllib中提供了urlencode这个方法来拼接url参数。

    from urllib importparse

    params= {'wd': '南北', 'code': '1', 'height': '188'}

    parse.urlencode(params)=======>>'wd=%E5%8D%97%E5%8C%97&code=1&height=188'

    4.urllib.error

    在urllib中主要设置了两个异常,一个是URLError,一个是HTTPError,HTTPError是URLError的子类。

    HTTPError还包含了三个属性:

    code:请求的状态码

    reason:错误的原因

    headers:响应的报头

    from urllib.error importHTTPErrortry:

    request.urlopen('https://www.jianshu.com')exceptHTTPError as e:print(e.code)403

    一个使用代理的例子:

    proxy_handler = urllib.request.ProxyHandler({'http':'http://www.example.com:3128/'})

    proxy_auth_handler=urllib.request.ProxyBasicAuth()

    proxy_auth_handler.add_password('realm', 'host', 'username', 'password')

    opener=urllib.request.build_opener(proxy_handler, proxy_auth_handler)

    opener.open('http://www.example.com/login.html')

    添加HTTP请求头部:

    importurllib.request

    req= urllib.request.Request('http://www.example.com/')

    req.add_header('Referer', 'http://www.python.org/')

    r= urllib.request.urlopen(req)

    更改User-agent:

    importurllib.request

    opener=urllib.request.build_opener()

    opener.addheaders= [('User-agent', 'Mozilla/5.0')]

    opener.open('http://www.example.com/')

    三、Python3.X中使用整合后的urllib

    Python2.x 有这些库名可用: urllib,urllib2,urllib3,httplib,httplib2,requestsPython3.x 有这些库名可用: urllib,urllib3,httplib2,requests

    若只使用Python3.x,记住有个urllib的库就行了。Pyhton2.x和Python3.x都有urllib3和requests, 它们不是标准库。urllib3提供线程安全连接池和文件post等支持,与urllib及urllib2的关系不大。requests 自称HTTP for Humans,使用更简洁方便。

    Python3.x中将urllib2合并到了urllib,之后此包分成了以下几个模块:

    urllib.request 用于打开和读取URL

    urllib.error 用于处理前面request引起的异常

    urllib.parse 用于解析URL

    urllib.robotparser用于解析robots.txt文件

    Python3.x中,随着urllib2合入urllib,一些常用的方法也发生了变化:2

    在Python2.x中使用import urlparse——在Python3.x中会使用import urllib.parse

    在Python2.x中使用urllib2.urlopen或urllib.urlopen(已弃用)——在Python3.x中会使用urllib.request.urlopen

    在Python2.x中使用urllib2.Request——在Python3.x中会使用urllib.request.Request

    在Python2.x中使用urllib.quote——在Python3.x中会使用urllib.request.quote

    在Python2.x中使用urllib.urlencode——在Python3.x中会使用urllib.parse.urlencode

    在Python2.x中使用cookielib.CookieJar——在Python3.x中会使用http.CookieJar

    异常处理:在Python2.x中使用urllib2.URLError,urllib2.HTTPError——在Python3.x中会使用urllib.error.URLError,urllib.error.HTTPError

    注:在Python3.3后urllib2已经不能再用,所有urllib2全部用urllib.request来代替。

    PUT一个请求:

    importurllib.request

    DATA=b'some data'req= urllib.request.Request(url='http://localhost:8080', data=DATA, method='PUT')

    with urllib.request.urlopen(req) as f:pass

    print(f.status)print(f.reason)

    基本的HTTP认证:

    importurllib.request

    auth_handler= urllib.request.HTTPBasicAuthHandler()

    auth_handler.add_password(realm='PDQ Application',

    uri='https://mahler:8092/site-updates.py',

    user='klem',

    passwd='kadidd!ehopper')

    opener= urllib.request.build_opener(auth_handler)

    urllib.request.install_opener(opener)

    urllib.request.urlopen('http://www.example.com/login.html')

    指定proxy:

    importurllib.request

    proxies= {'http': 'http://proxy.example.com:8080/'}

    opener=urllib.request.FancyURLopener(proxies)

    with opener.open("http://www.python.org") as f:

    f.read().decode('utf-8')

    不使用proxy, 覆盖环境变量的proxy:

    importurllib.request

    opener=urllib.request.FancyURLopener({})

    with opener.open("http://www.python.org/") as f:

    f.read().decode('utf-8')

    展开全文
  • 一、urllib库urllib是Python自带一个用于爬虫库,其主要作用就是可以通过代码模拟浏览器发送请求。其常被用到子模块在Python3中为urllib.request和urllib.parse,在Python2中是urllib和urllib2。二、由易到...
  • urllib 是 Python 标准中用于网络请求的。该有四个模块,分别是:urllib.requesturllib.errorurllib.parseurllib....urllib.request 的作用不仅仅是发起请求, 还能获取请求返回结果。发起请求,单靠 urlopen...
  • Python之urllib库详解

    2019-10-04 01:36:34
    urllib 是 Python 标准中用于网络请求的。 该有四个模块,分别是: urllib.request urllib.error urllib.parse ...urllib.robotparser ...urllib.request 的作用不仅仅是发起请求, 还能获取请求返...
  • 一.urllib库urllib是Python自带一个用于爬虫库,其主要作用就是可以通过代码模拟浏览器发送请求。其常被用到子模块在Python3中为urllib.request和urllib.parse,在Python2中是urllib和urllib2。二.由易到难...
  • urllib库-内置函数

    2019-12-05 11:11:19
    urllib库:python中一个最基本网络请求库,可以模拟浏览器行为,向指定服务器发送一个请求,并可以保存服务器返回数据 urlertrieve函数 作用:这个函数可以方便将网页文件保存到本地 格式:ulrlib.request...
  • 一.urllib库  urllib是Python自带一个用于爬虫库,其主要作用就是可以通过代码模拟浏览器发送请求。其常被用到子模块在Python3中为urllib.request和urllib.parse,在Python2中是urllib和urllib2。 二.由...
  • 【Python3网络爬虫】 urllib库的使用

    千次阅读 2018-05-12 01:16:12
    1.库的作用,让我们在使用时不需要关心底层,不再需要关心怎么做,而是只需要关心做什么。2.urllib is a package that collects several modules for working with URLs:urllib.request for opening and reading ...
  • 3.x的版本urllib与urllib2已经合并为一个urllib库,学着比较清晰些,2.7的版本呢urllib与urllib2各有各的作用,下面我把自己学习官方文档和其他资料的总结写下,方便以后使用。 urllib与urllib2
  • 下面介绍爬虫一个基本urllib 从代码看起(本文所有代码依赖于第一篇代码中前三行导入的库和模块) 一: 下面代码介绍最基本方法及其作用,注释在代码块中 import urllib from urllib import request ...
  • 本文基于Python3.x,这里urllib.request模块对应Python2.x的request模块 ...parse的英文意思是『句法分析』,可见它的作用就是用来解析传进来饿的URL地址,并输出相应的信息——它是不需要联网的 r...
  • 3.x的版本urllib与urllib2已经合并为一个urllib库,学着比较清晰些,2.7的版本呢urllib与urllib2各有各的作用,下面我把自己学习官方文档和其他资料的总结写下,方便以后使用。  urllib与urlli...
  • python中urllib2使用

    2019-04-11 11:26:51
    1)用法:urllib2.Request(url[, data][, headers][, origin_req_host][, unverifiable]) 2)作用:用于构造Request对象,可以传递data数据,添加请求头(headers)等,构造好后作为urllib2.urlopen()参数。...
  • cookie:某些网站为了辨别用户身份、进行session跟踪而存储再本地终端上...Path:cookie作用的路径 Domain:cookie作用的域名 SECURE:是否只再https协议下起作用 set-cookie 通知客户端保存数据 作者:zs578695
  • 3.x的版本urllib与urllib2已经合并为一个urllib库,学着比较清晰些,2.7的版本呢urllib与urllib2各有各的作用,下面我把自己学习官方文档和其他资料的总结写下,方便以后使用。urllib与urllib2并不...
  • 前言该文章主要说明Python3 标准库urllib的使用。修改时间:20191216修改时间:20191217修改时间:20191218添加urllib.parse.urlencode,urllib.request.Request方法解释天象独行0X01;urllib作用是什么?urllib是...
  • 目录 一、urllib ...urllib库的作用:网页爬虫、自动化处理表单、自动化测试脚本(如sqlmap 1.获取网页内容 根据url获取网页信息、网页信息实质是一段html、css、js代码 python2的代码,获取百度...
  • python3.x中urllib库和urilib2库合并成了urllib库。 其中urllib2.urlopen()变成了urllib.request.urlopen() urllib2.Request()变成了urllib.request.Request() Python3 如何对url解码?实现Python2中urllib....
  • Python3标准——urllib

    2019-12-17 22:54:33
     urllib是Python3一个内置标准,主要用来进行http请求。其中主要包含四个常见模块。分别是:request,error,parse,robotparser。request模块功能提供一个基本请求功能,来模拟http请求。error异常处理模块...
  • 一、分析网站 链接:尚学堂贴吧地址 前面部分为域名:固定不变, 后面跟着字符串含有变量 ... pass#无任何作用,只是为了保持格式(python代码对格式有严格要求) 保存页面信息 def save_html(): pass
  • 3.x的版本urllib与urllib2已经合并为一个urllib库,学着比较清晰些,2.7的版本呢urllib与urllib2各有各的作用,下面我把自己学习官方文档和其他资料的总结写下,方便以后使用。  urllib与url
  • urllib是Python自带一个用于爬虫的库,其主要作用就是可以通过代码模拟浏览器发送请求。其常被用到子模块在Python3中urllib.request和urllib.parse,在Python2中是urlliburllib2。 一、使用流程: ...

空空如也

空空如也

1 2 3 4 5 ... 9
收藏数 174
精华内容 69
热门标签
关键字:

urllib库的作用