zoukankan      html  css  js  c++  java
  • python自带的urllib使用

    1.urllib中request构建完整请求

    """request构建完整请求"""
    from urllib import request
    
    
    # Request封装url
    req = request.Request("https://python.org")
    # 发起请求并保存请求结果
    res = request.urlopen(req)
    # 打印响应信息
    print(res.read().decode("utf-8"))
    
    
    """
    class Request:
    
        def __init__(self, url, data=None, headers={},
                     origin_req_host=None, unverifiable=False,
                     method=None):
        参数解析:
        url:请求URL
        data:跟urlopen里面的data传递一样的bytes类型数据
        headers:请求头可直接构造,也可以使用类方法add_header()传递参数
        origin_req_host:请求时的host名称或者IP
        unverifiable:权限操作,有或者没有。默认False,表示用户没有权限选择接受这个请求的结果
        method:请求时的方法,比如GET,POST,DELETE等
    """
    
    
    
    
    from urllib import request, parse
    
    
    # 设置请求的url
    url = "http://httpbin.org/post"
    # 设置请求头信息
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36",
        "Host": "httpbin.org"
    }
    dict = {"name": "Germey"}
    # 把字典转换成字节流信息
    data = bytes(parse.urlencode(dict), encoding="utf8")
    # 参数按值传递
    req = request.Request(url=url, data=data, headers=headers, method="POST")
    # 发起请求并保存请求结果
    res = request.urlopen(req)
    # 打印响应信息
    print(res.read().decode("utf-8"))
    View Code

    2.request中urlopen的get请求分析

    """urlopen的get分析"""
    from urllib import request
    from http.client import HTTPResponse  # 引用
    
    
    res = request.urlopen("https://www.python.org")
    print(type(res))        # 打印返回结果的类型,用from引用这个类型查看具备的方法和属性
    print(res.status)       # 返回相应的状态码
    print(res.getheaders())     # 返回所有请求头信息
    print(res.getheader("Server"))      # 返回服务器信息,nginx。socket服务器中比较牛逼的一种
    
    # def urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
    #             *, cafile=None, capath=None, cadefault=False, context=None):
    """
    源码解释:
    打开URL url,可以是字符串或Request对象。
    
        * data *必须是指定要发送到的其他数据的对象
        服务器,如果不需要这样的数据,则为None。请参阅请求
        细节。
    
        urllib.request模块使用HTTP / 1.1并包含“Connection:close”
        HTTP请求中的标头。
    
        可选的* timeout *参数指定超时(以秒为单位)
        阻塞操作,如连接尝试(如果未指定,则
        将使用全局默认超时设置)。这仅适用于HTTP,
        HTTPS和FTP连接。
    
        如果指定了* context *,则它必须是描述的ssl.SSLContext实例
        各种SSL选项。有关更多详细信息,请参阅HTTPSConnection。
    
        可选的* cafile *和* capath *参数指定一组可信CA.
        HTTPS请求的证书。 cafile应该指向一个文件
        包含一捆CA证书,而capath应指向a
        哈希证书文件的目录。更多信息可以在中找到
        ssl.SSLContext.load_verify_locations()。
    
        * cadefault *参数被忽略。
    
        此函数始终返回可用作上下文的对象
        经理和有方法,如
    
        * geturl() - 返回检索到的资源的URL,常用于
          确定是否遵循重定向
    
        * info() - 返回页面的元信息,例如标题
          email.message_from_string()实例的形式(请参阅快速参考
          HTTP标头)
    
        * getcode() - 返回响应的HTTP状态代码。引发URLError
          关于错误。
    
        对于HTTP和HTTPS URL,此函数返回http.client.HTTPResponse
        对象略有修改。除了以上三种新方法外,还有
        msg属性包含与reason属性相同的信息---
        服务器返回的原因短语 - 而不是响应
        在HTTPResponse的文档中指定的标头。
    
        对于遗留显式处理的FTP,文件和数据URL以及请求
        URLopener和FancyURLopener类,这个函数返回一个
        urllib.response.addinfourl对象。
    """
    View Code

    3.request中urlopen的post请求分析

    """urlopen的post请求分析"""
    from urllib import parse
    from urllib import request
    import json
    
    
    # 转换utf8编码的data数据
    data = bytes(parse.urlencode({"word": "hello"}), encoding="utf8")
    # parse.urlencode({"word": "hello"})    返回字符串形式'word=hello'
    print(data)       # b'word=hello'    返回bytes类型数据与下面json区别
    print(type(data))    # <class 'bytes'>
    res = request.urlopen("http://httpbin.org/post", data=data)
    print(res)          # <http.client.HTTPResponse object at 0x00000184DB1C3E10>   返回响应对象
    print(type(res))    # <class 'http.client.HTTPResponse'>   对象类型
    print(res.read())   # 读取返回的内容中b'"form":{"word":"hello"},'此字段表明模拟了表单提交的方式
    arg = json.dumps({"word": "hello"})
    print(arg)          # '{"word": "hello"}' json返回字符串形式字典数据
    print(type(arg))    # <class 'str'>
    View Code

    4.request中urlopen的异常处理

    """urllib的异常处理"""
    from urllib import request, error
    
    
    try:
        res = request.urlopen("https://home.cnblogs.com/u/Guishuzhe/1")
    except error.HTTPError as e:
        # 先捕获子类详细异常原因
        print(e.reason, e.code, e.headers)
    except error.URLError as e:
        # 再用父类捕获子类中没有的异常
        print(e.reason)
    else:
        print("Request Successfully")
    
    
    
    import socket
    from urllib import request
    from urllib import error
    
    
    try:
        # 设置超时时间timeout=0.2
        res = request.urlopen("http://httpbin.org/get", timeout=0.2)
    # 捕捉超时异常,返回友好信息
    except error.URLError as e:
        print(type(e.reason))
        # class URLError(OSError):源码  self.reason属性, e.reason调用这个属性
        # 内置函数isinstance判断错误对象是不是某一类型
        # 在这里是连接超时错误socket.timeout
        if isinstance(e.reason, socket.timeout):
            print("超时了")
    View Code

    5.urllib进阶设置Handler

    """urllib进阶设置Handler工具"""
    from urllib.request import HTTPPasswordMgrWithDefaultRealm, HTTPBasicAuthHandler, build_opener
    from urllib.error import URLError
    
    
    username = "username"
    password = "password"
    url = "http://127.0.0.1:8000/"
    # 实例化一个待处理对象
    p = HTTPPasswordMgrWithDefaultRealm()
    # 给实例化对象添加请求参数realm=None等..
    p.add_password(None, url, username, password)
    # class AbstractBasicAuthHandler:找到父类并实例化出具体请求对象(Handler)
    auth_handler = HTTPBasicAuthHandler(p)
    # build_opener()方法接受*Handlers任意个Handler对象进行去重等处理,返回Opener对象
    opener = build_opener(auth_handler)
    
    try:
        # 开始请求
        res = opener.open(url)
        # 获取请求结果
        html = res.read().decode("utf8")
        print(html)
    except URLError as e:
        # 打印错误信息
        print(e.reason)
    
    
    """
    HITPDefaultErrorHandler :用于处理HTTP响应错误,错误都会抛出HTTPError类型的异常
    HTTPRedirectHandler :用于处理重定向
    HTTPCookieProcessor 用于处理Cookies
    ProxyHandler :用于设置代理默认代理为空
    HπPPasswordMgr :用于管理密码,它维护了用户名和密码的表
    HTTPBasicAuthHandler 用于管理认证,如果一个链接打开时需要认证,那么可以用它来解决认证问题
    """
    View Code

    6.cookies的处理

    """cookies的处理"""
    from http import cookiejar
    from urllib import request
    
    
    # 存放cookie信息
    filename = "cookies.txt"
    cookie = cookiejar.LWPCookieJar(filename)    # 建议使用此保存格式
    # cookie = cookiejar.MozillaCookieJar(filename)
    handler = request.HTTPCookieProcessor(cookie)
    opener = request.build_opener(handler)
    res = opener.open("http://www.baidu.com")
    cookie.save(ignore_discard=True, ignore_expires=True)
    
    
    
    # 读取cookie信息
    cookie = cookiejar.LWPCookieJar()       # 实例化LWP对象
    # 指定要读取的文件数据到cookie实例,忽略丢弃和忽略过期
    cookie.load("cookies.txt", ignore_discard=True, ignore_expires=True)
    # 将读取的cookie信息封装为handler类型
    handler = request.HTTPCookieProcessor(cookie)
    # 创建一个opener对象
    opener = request.build_opener(handler)
    # 调用opener对象的open方法打开url
    res = opener.open("http://www.baidu.com")
    print(res.read().decode("utf-8"))
    View Code

    7.代理设置

    """urllib的代理设置"""
    from urllib.error import URLError
    from urllib.request import ProxyHandler, build_opener
    
    
    # 设置代理请求的类型、ip和端口,_parse_proxy函数完成代理参数解析
    proxy_handler = ProxyHandler({
        "http": "http://124.231.16.75:9000",
        "https": "https://113.105.201.193:3128"
    })
    # 封装设置的代理数据,制造opener对象
    opener = build_opener(proxy_handler)
    try:
        # 调用opener的open方法代理访问百度
        res = opener.open("https://www.baidu.com")
        print(res.read().decode("utf-8"))
    except URLError as e:
        print(e.reason)
    View Code

    8.url的解析

    """urllib中的parse模块"""
    from urllib.parse import urlparse     # 等同from urllib.parse import urlsplit
    from urllib.parse import urlunparse   # 等同from urllib.parse import urlunsplit
    # urljoin拼接主url和所需url参数形成完整的url
    from urllib.parse import urljoin      # base_url + new_url = complete_url
    from urllib.parse import urlencode    # 构造GET请求参数,序列化完整url
    # 反序列化url参数
    from urllib.parse import parse_qs     # from urllib.parse import parse_qsl
    from urllib.parse import quote        # 解决中文编码问题,默认utf-8编码
    from urllib.parse import unquote      # 进行URL解码
    
    
    # 解析url的标准格式
    res = urlparse("http://www.baidu.com/index.html;user?id=5#comment")
    print(type(res), res)
    
    """
    # 返回ParseResult结果的对象
    <class 'urllib.parse.ParseResult'> 
    ParseResult(scheme='http',              # 协议
                netloc='www.baidu.com',     # 域名
                path='/index.html',         # 路径
                params='user',              # 参数
                query='id=5',               # 查询条件,一般get查询时使用
                fragment='comment'          # 锚点,定位页面内部的下拉位置
                )
    scheme://netloc/path;params?query#fragment    标准格式的url
    """
    
    # urlunparse拼接url,需要6个参数完成拼接,限制比较大
    data = ["https", "www.baidu.com", "index.html", "user", "id=5", "comment"]
    print(urlunparse(data))
    
    
    # urljoin拼接,常用此拼接方法,可自动补全完整的url连接
    print(urljoin("https://www.baidu.com", "s?ie=utf-8&tn=baidu&wd=girl"))
    
    
    # urlencode构造GET请求参数,常用方法。用字段存储url所需参数,使用时再进行转换
    params = {
        "name": "Jim",
        "age": "26"
    }
    base_url = "https://www.baidu.com?"
    url = base_url + urlencode(params)
    print(url)
    
    
    # parse_qs反序列化url参数{'name': ['Jim'], 'age': ['26']}, parse_qsl转换为元组组成的列表
    query = "name=Jim&age=26"
    print(parse_qs(query))
    
    
    # quote方法可以将内容转换为URL编码的格式,默认utf-8编码
    keyword = "机械键盘"
    url = "https://www.baidu.com/s?wd=" + quote(keyword)
    print(url)
    
    
    # unquote方法可以将已编码的URL解码
    url = "https://www.baidu.com/s?wd=%E6%9C%BA%E6%A2%B0%E9%94%AE%E7%9B%98"
    print(unquote(url))
    View Code

    9.蜘蛛协议

    """
    百度!!!
    分析Robots协议,Robots协议也称作爬虫协议、机器人协议,它的全名叫作网络爬虫排除标准(Robots Exclusion
    Protocol),用来告诉爬虫和搜索引擎哪些页面可以抓取,哪些不可以抓取它通常是一个叫作 robots.txt
    的文本文件,一般放在网站的根目录下
    User-agent: *     *通配符,表示对所有爬虫都有效,此处可以设置爬虫名称
    Disallow: /       /不允许抓取所有页面,不允许抓取的目录
    Allow: /public/    可以抓取的目录,和Disallow一起使用
    
    urllib的robotparser模块
    set_url():用来设置robots.txt文件的链接如果在创建RobotFileParser对象时传入了链
    接,那么就不需要再使用这个方法设置了
    read ():读取robots.txt文件并进行分析.注意,这个方法执行一个读取和分析操作,如果不
    调用这个方法接下来的判断都会为False,所以一定记得调用这个方法这个方法不会返
    回任何内容,但是执行了读取操作
    parse():用来解析robots.txt文件,传人的参数是robots.txt某些行的内容,它会按照robots.txt
    的语法规则来分析这些内容
    can_fetch():该方法传人两个参数第一个是User-agent,第二个是要抓取的URL返回的
    内容是该搜索引擎是否可以抓取这个URL,返回结果是True或False
    mtime():返回的是上次抓取和分析robots.txt的时间,这对于长时间分析和抓取的搜索爬虫
    很有必要的,你可能需要定期检查来抓取最新的robots.txt
    modified():它同样对长时间分析和抓取的搜索爬虫很有帮助,将当前时间设置为上次抓取
    和分析robots.txt的时间
    """
    from urllib.robotparser import RobotFileParser
    from urllib.request import urlopen
    from urllib import request
    
    
    # 创建RobotFileParser对象
    rp = RobotFileParser()
    # 设置连接
    rp.set_url("https://www.jianshu.com/robots.txt")
    # 读取分析
    rp.read()
    # 打印判断的结果,直接无模拟访问抓取都返回False
    print(rp.can_fetch("*", "https://www.jianshu.com/p/b67554025d7d"))      # False
    print(rp.can_fetch("*", "https://www.jianshu.com/search?q=python&page=1&type=collections"))     # False
    
    
    # 需要添加headers信息,不添加直接403.模拟浏览器访问抓取
    url = "https://www.jianshu.com/robots.txt"
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36"
    }
    req = request.Request(url=url, headers=headers)
    res = urlopen(req).read().decode("utf-8").split("
    ")
    rp = RobotFileParser()
    rp.parse(res)
    print(rp.can_fetch("*", "https://www.jianshu.com/p/b67554025d7d"))      # True
    print(rp.can_fetch("*", "https://www.jianshu.com/search?q=python&page=1&type=collections"))     # False
    View Code
  • 相关阅读:
    数据库_初学
    数据库—修改表的列
    做一个导航栏(bootstrap)
    几个比较常用的特效
    当、你想给一个目标挂上一个事件时
    图片轮播的几个小程序
    JS练习题 ( 下拉菜单;好友选中输入)
    Bootstrap 按钮和折叠插件
    Bootstrap 轮播插件
    Bootstrap 弹出框和警告框插件
  • 原文地址:https://www.cnblogs.com/Guishuzhe/p/10164837.html
Copyright © 2011-2022 走看看