• Python逆向爬虫之urllib


    Python逆向爬虫之urllib

    urllib库是python内置的一个http请求库,requests库就是基于该库开发出来的,虽然requests 库使用更方便,但作为最最基本的请求库,了解一下原理和用法还是很有必要的。

    urllib 包 包含以下几个模块:

    • urllib.request - 打开和读取 URL。
    • urllib.error - 包含 urllib.request 抛出的异常。
    • urllib.parse - 解析 URL。
    • urllib.robotparser - 解析 robots.txt 文件。

    img

    一、urllib.request

    urllib.request 定义了一些打开 URL 的函数和类,包含授权验证、重定向、浏览器 cookies等。

    1.1 urlopen函数

    urllib.request 可以模拟浏览器的一个请求发起过程。

    我们可以使用 urllib.request 的 urlopen 方法来打开一个 URL,语法格式如下:

    urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)
    
    • url:url 地址。
    • data:发送到服务器的其他数据对象,默认为 None。
    • timeout:设置访问超时时间。
    • cafile 和 capath:cafile 为 CA 证书, capath 为 CA 证书的路径,使用 HTTPS 需要用到。
    • cadefault:已经被弃用。
    • context:ssl.SSLContext类型,用来指定 SSL 设置。

    实例:

    # -*- coding: utf-8 -*-
    from urllib.request import urlopen
    data = urlopen(url="https://www.baidu.com/")
    print(data.read())
    

    以上代码使用 urlopen 打开一个 URL,然后使用 read() 函数获取网页的 HTML 实体代码。

    read() 是读取整个网页内容,我们可以指定读取的长度:

    # -*- coding: utf-8 -*-
    from urllib.request import urlopen
    data = urlopen(url="https://www.baidu.com/")
    print(data.read(100))
    

    我们在对网页进行抓取时,经常需要判断网页是否可以正常访问,这里我们就可以使用 getcode() 函数获取网页状态码,返回 200 说明网页正常,返回 404 说明网页不存在:

    # -*- coding: utf-8 -*-
    from urllib.request import urlopen
    
    data = urlopen(url="https://blog.abck8s.com/")
    print(data.getcode())
    

    没有data参数时,发送的是一个get请求,加上data参数后,请求就变成了post方式。

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

    1.2 response 响应类型

    import urllib
    from urllib import request
    
    response = urllib.request.urlopen('http://www.baidu.com')
    print(response.status)
    print(response.getheaders())
    print(response.getheader('Server'))
    

    1.3 Request对象

    如果我们需要发送复杂的请求,在urllib库中就需要使用一个Request对象。

    import urllib.request
     
    #直接声明一个Request对象,并把url当作参数直接传递进来
    request = urllib.request.Request('http://www.baidu.com')
    response = urllib.request.urlopen(request)
    print(response.read().decode('utf-8'))
    

    声明了一个Request对象,把url当作参数传递给这个对象,然后把这个对昂作为urlopen函数的参数

    更复杂的请求,加headers

    利用Request对象实现一个post请求

    import urllib.request
    url = 'http://httpbin.org/post'
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'
    }
    data = {'word':'hello'}
    data = bytes(str(data),encoding='utf-8')
    req = urllib.request.Request(url = url,data = data,headers = headers,method = 'POST')
    response = urllib.request.urlopen(req)
    print(response.read().decode('utf-8'))
    
    import urllib.request
    import urllib.parse
    
    url = 'https://s.weibo.com/weibo?q=%23%E5%A5%A5%E8%BF%90%E5%81%A5%E5%84%BF%E6%97%B6%E9%9A%94%E4%B8%80%E5%B9%B4%E5%86%8D%E6%88%98%E4%B8%96%E7%95%8C%E8%B5%9B%E5%9C%BA%23'
    
    #携带cookie进行访问
    headers = {
        'GET https': '//s.weibo.com/weibo?q=%23%E5%A5%A5%E8%BF%90%E5%81%A5%E5%84%BF%E6%97%B6%E9%9A%94%E4%B8%80%E5%B9%B4%E5%86%8D%E6%88%98%E4%B8%96%E7%95%8C%E8%B5%9B%E5%9C%BA%23 HTTP/1.1',
        'Host': ' weibo.cn',
        'Connection': ' keep-alive',
        'Upgrade-Insecure-Requests': ' 1',
        'User-Agent': ' Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36',
        'Accept': ' text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
        'Accept-Language': ' zh-CN,zh;q=0.9',
        'Cookie': ' _T_WM=c1913301844388de10cba9d0bb7bbf1e; SUB=_2A253Wy_dDeRhGeNM7FER-CbJzj-IHXVUp7GVrDV6PUJbkdANLXPdkW1NSesPJZ6v1GA5MyW2HEUb9ytQW3NYy19U; SUHB=0bt8SpepeGz439; SCF=Aua-HpSw5-z78-02NmUv8CTwXZCMN4XJ91qYSHkDXH4W9W0fCBpEI6Hy5E6vObeDqTXtfqobcD2D32r0O_5jSRk.; SSOLoginState=1516199821',
    }
    request = urllib.request.Request(url=url, headers=headers)
    response = urllib.request.urlopen(request)
    # 输出所有
    # print(response.read().decode('gbk'))
    # 将内容写入文件中
    with open('weibo.html', 'wb') as fp:
        fp.write(response.read())
    

    二、urllib.error

    可以捕获三种异常:URLError,HTTPError(是URLError类的一个子类),ContentTooShortError

    URLError只有一个reason属性

    HTTPError有三个属性:code,reason,headers

    import urllib
    from urllib import request
    from urllib import error
    #先捕捉http异常,再捕捉url异常
    try:
        response = urllib.request.urlopen('http://123.com')
    except error.HTTPError as e:
        print(e.reason, e.code, e.headers)
    except error.URLError as e:
        print(e.reason)
    else:
        print('RequestSucess!')
    

    三、urlparse函数

    该函数是对传入的url进行分割,分割成几部分,并对每部分进行赋值。

    import urllib
    from urllib import parse
    
    result = urllib.parse.urlparse('http://www.baidu.com/index.html;user?id=5#comment')
    print(type(result))
    print(result)
    

    四、urlunparse函数

    与urlparse函数作用相反,是对url进行拼接的。

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

    五、urlencode函数

    可以把一个字典转化为get请求参数。

    from urllib.parse import urlencode
    params = {
        'name': 'alvin',
        'age': 18
    }
    base_url = 'https://www.baidu.com?'
    usr = base_url + urlencode(params)
    print(usr)
    
  • 相关阅读:
    RK3288 Android5.1系统编译
    RK3288 模块单独编译
    ubuntu 设置固定DNS
    PHP取整函数之ceil,floor,round,intval的区别
    PHP实现 APP端微信支付功能
    Laravel中服务提供者和门面模式
    laravel项目利用twemproxy部署redis集群的完整步骤
    PHP转盘抽奖算法
    laravel中短信发送验证码的实现方法
    PHP操作Redis常用
  • 原文地址:https://www.cnblogs.com/chenyangqit/p/16593796.html
Copyright © 2020-2023  润新知