美文网首页
tenliu的爬虫-urllib2学习

tenliu的爬虫-urllib2学习

作者: tenliu的简书 | 来源:发表于2018-01-20 10:11 被阅读0次

    我们知道通过urllib可以编写简单的爬虫,但是也存在很大的问题。
    python基金会不得不推出urllib的增强版urllib2。

    urllib2方法和类概述

    urllib2.urlopen()

    urllib2.urlopen(url[, data][, timeout])

    三个参数

    • url:可以是一个url字符串。也可以是一个urllib2的Request对象(Request对象是什么后面讲)
    • data:可选参数,默认为null时,请求是get方式;设定data后,请求为post方式。
    • timeout:定义超时时间,请求超时会跑出超时异常。

    其实urllib2.urlopen()参数不止上面三个,这里只是列出常用的。

    urllib2.Request

    urllib2.Request(url[, data][, headers])

    Request类是一个抽象的URL请求。
    三个参数:

    • url:url字符串
    • data:请求参数
    • headers:http的headers,urllib2可以伪装,就在这里了。

    以上就是基本常用的方法和类了,更加具体的我们在例子中讲解和补全吧

    在例子中实践

    基本get请求

    urllib2.urlopen(url[, data[, timeout]]])
    我们已经知道urllib的urlopen()函数,看看urllib2的urlopen()函数吧,还是从一个简单例子开始:

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    import urllib
    import urllib2
    import requests
    import sys
    reload(sys)
    sys.setdefaultencoding('utf8')
    def first():
        #基本 普通的get请求
        url = "http://www.tenliu.top/index.php/httpclient/"
        try:
            resp = urllib2.urlopen(url,timeout=4)
            print resp.read()
            print resp.info()
            print resp.getcode()
            print resp.geturl()
        except urllib2.URLError,e:
            print e
    if __name__=="__main__":
        first()
    

    这个例子看来和urllib.urlopen()似乎差不多啊,多了timeout超时参数,请求超时会抛出异常,这里可以自己捕获再次处理。

    基本post请求

    urllib2.urlopen()中,带上data参数,请求就是post方式了。
    还是看例子

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    import urllib
    import urllib2
    import requests
    import sys
    reload(sys) 
    sys.setdefaultencoding('utf8')
    def second():
        url = "http://www.tenliu.top/index.php/httpclient/"
        data = {'country': '中国', 'ranking': 2}
        resp = urllib2.urlopen(url,data=urllib.urlencode(data))
        print resp.read()
    if __name__=="__main__":
        second()
    

    加上Request类

    urllib2.urlopen()中的url参数不仅仅可以是url字符串,而且可以是urllib2.Request类,这是urllib2封装的抽象请求,比urllib功能更强大的地方就体现在这个类上。我们先看一个基本用法吧:

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    import urllib
    import urllib2
    import requests
    import sys
    reload(sys) 
    sys.setdefaultencoding('utf8')
    def thrid():
        #看看这个urllib2.Request() get
        url = "http://www.tenliu.top/index.php/httpclient/"
        req = urllib2.Request(url)
        resp = urllib2.urlopen(req)
        print resp.read()
    if __name__=="__main__":
        thrid()
    

    真实的url封装在Request类中,然后通过urlopen()进行请求。

    Request带参数post请求

    使用Request类如何post参数。
    这里需要注意的是urllib和urllib2的post参数时,都是需要进行url编码处理的,即要用到urllib.urlencode()。这就是urllib没有被urllib2完全取代的原因,至于为什么要这么设计,鬼知道!但正是种种not for Humans的设计,才会使requests库的出现,这是后话。还是先看例子吧:

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    import urllib
    import urllib2
    import requests
    import sys
    reload(sys) 
    sys.setdefaultencoding('utf8')
    def fourth():
        #urllib2.Request(),post
        url = "http://www.tenliu.top/index.php/httpclient/"
        data = {'country': '中国', 'ranking': 2}
        req = urllib2.Request(url,urllib.urlencode(data))
        resp = urllib2.urlopen(req)
        print resp.read()
    if __name__=="__main__":
        fourth()
    

    伪装headers

    urllib2正是通过Requests这个类进行headers的伪装的。可以操作headers,使得爬虫功能变的十分强大了,比如通过“User-Agent”伪装成浏览器;
    通过“Cookie”免登陆,保持会话等等。

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    import urllib
    import urllib2
    import requests
    import sys
    reload(sys) 
    sys.setdefaultencoding('utf8')
    def fifth():
        #urllib2可以添加headers
        #并且可以设置cookies,可做的事情大大增加,例如使用cookies登录或保持登录状态,也相当会保持会话了
        url = "http://www.tenliu.top/index.php/httpclient/"
        data = {'country': '中国', 'ranking': 2}
        headers = {
            'Cookie':'sugstore=1; type=test',
            'User-Agent':'Mozilla/5.0  test',
        }
        req = urllib2.Request(url, urllib.urlencode(data), headers)
        resp = urllib2.urlopen(req)
        print resp.read()
    if __name__=="__main__":
        fifth()
    

    运行这个例子看看。抓取的页面中

    var res = {"headers":{"HTTP_ACCEPT_ENCODING":"identity",<font color="red">"HTTP_USER_AGENT":"Mozilla/5.0 test"</font>,"HTTP_CONNECTION":"close",<font color="red">"HTTP_COOKIE":"sugstore=1; type=test"</font>,"REQUEST_METHOD":"POST"},"params":{"country":"\u4e2d\u56fd","ranking":"2"},"ipinfo":{"ipAdder":"123.123.133.69","ipPhysical":"\u5317\u4eac\u5e02 \u8054\u901a"}};

    看来我们伪装成功了,起码服务器已经无法通过User-Agent 来识别请求是爬虫还是真实的浏览器了。

    代理ip

    从以上例子中看来,urllib2比urllib确实功能上强大很多,下面我们看看urllib2中的IP代理如何设置,urllib2.urlopen()中没有proxies参数啊。

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    import urllib
    import urllib2
    import requests
    import sys
    reload(sys) 
    sys.setdefaultencoding('utf8')
    def sixth():
        #ip代理
        url = "http://www.tenliu.top/index.php/httpclient/"
        proxies = {"http" : '101.248.64.68:80'}
        # proxy_handler = urllib2.ProxyHandler({"http" : 'http://some-proxy.com:8080'})
        proxy_handler = urllib2.ProxyHandler(proxies)
        opener = urllib2.build_opener(proxy_handler)
        urllib2.install_opener(opener)
        resp = urllib2.urlopen(url)
        print resp.read()
    if __name__=="__main__":
        sixth()
    

    运行打印看看结果,在抓取到的页面中:

    var res = {"headers":{"HTTP_USER_AGENT":"Python-urllib/2.7","HTTP_CACHE_CONTROL":"max-age=600","HTTP_CONNECTION":"keep-alive","REQUEST_METHOD":"GET"},"params":[],"ipinfo":{<font color="red">"ipAdder":"101.248.64.68"</font>,"ipPhysical":"\u897f\u85cf \u7535\u4fe1"}};

    说明代理已经添加成功啦。

    urllib2虽然可以设置ip代理,但是这种复杂的设计,甚至比自己的上一代urllib设置起来还要复杂啊。
    也难怪被第三方库requests吐槽了,not for Humans这个黑锅urllib和urllib2是背定了,那么requests这个库又怎么样呢?我们下一次再说吧。

    相关文章

      网友评论

          本文标题:tenliu的爬虫-urllib2学习

          本文链接:https://www.haomeiwen.com/subject/iygzoxtx.html