• Pythonurllib


    urllib

    request

    最基本的http请求模块

    build_opener 函数

    使用一些默认的handler构建一个opener(OpenerDirector类型)

    urlopen 函数

    最基本的构造HTTP请求的方法,实际这个函数内部就是使用build_opener完成创建opener,然后由opener完成请求

    • 参数
      • data: 二进制,如果传入了此参数,请求方式是POST
      • timeout: 超时时间
      • context: ssl.SSLContext类型
      • cafile: CA证书
      • capath: CA证书路径
    • 返回值
      • http.client.HTTPResponse类型,包含以下方法和属性
        • 方法: read, readinfo, getheader, getheaders, fileno
        • 属性: msg, version, status, reason, debuglevel, closed
        • 返回状态: status
        • 返回的数据: read(),如果是文本,可以:read().decode('utf-8)

    OpenerDirector 类

    实际上请求都是由这个类的实例完成

    open 方法

    发起请求

    Request 类

    可以构建更复杂的HTTP请求,比如添加headers

    init 方法
    • 参数
      • headers: 字典形式的headers
    add_header 方法

    添加请求头,如果已经存在会覆盖原来的值,否则新增

    BaseHandler 类

    各种handler的父类

    HTTPDefaultErrorHandler 类

    用于处理HTTP响应错误,所有错误都会抛出HTTPError类型的异常

    HTTPRedirectHandler 类

    用于处理重定向

    HTTPCookieProcessor 类

    用于处理Cookie

    ProxyHandler 类

    用于设置代理,代理默认为空

    HTTPPasswordMgr 类

    用于管理密码,它维护着用户名密码的对照表

    HTTPBasicAuthHandler 类

    用于管理认证,如果一个链接在打开时需要认证,那么可以用这个类来解决认证问题

    parse

    工具模块,用来对URL进行解析,合并等操作

    urlparse 函数

    实现URL的识别和分段,结果包含6部分:scheme://netloc/path;params?query#fragment

    • 参数

      • urlstring: 即待解析的url
      • scheme: 如果url中不包含scheme,则此参数作为默认值
      • allow_fragments: True(默认)/False,如果设置为False,则解析后的fragment为空字符串,对应的数据会被解析为path、params或者query的一部分,一般前面三者谁在最后就跟谁
    • 返回值

      • urllib.parse.ParseResult
      • 可以直接.属性获取相关部分的数据,也可以使用[下标]的方式

    urlunparse 函数

    这个函数用于构造url,即urlparse的逆操作

    • 参数
      • components:包含6个元素的可迭代对象,多了或者少了都会报错

    urlsplit 函数

    与方法urlparse类似,只是会把params部分合并到path中,结果只有5部分

    • 返回值
      • urllib.parse.SplitResult

    urlunsplit 函数

    urlsplit的逆操作

    urljoin 函数

    常用于拼接 base_url和path
    把base链接里面的部分填充到新url中对应缺失的部分

    • 参数
      • base: 基础链接
      • url: 新url
      • allow_fragments

    urlencode 函数

    可以将字典类型转成GET请求参数

    parse_qs 函数

    urlencode的逆操作,结果是字典类型

    parse_qsl 函数

    同parse_qs,结果是列表类型

    quote 函数

    对内容进行url编码

    unquote 函数

    quote的逆操作

    error

    异常处理模块

    URLError 类

    其他异常类的基类

    • 属性
      • reason

    HTTPError 类

    专门处理HTTP请求错误

    • 属性
      • code
      • reason
      • headers

    robotparser

    处理网站robot.txt文件

    RobotFileParser 类

    用来解析robots.txt文件,并可以判断是否能爬取指定的url

    parse 方法
    • 参数
      • lines: robots.txt文件中的一行行
    can_fetch 方法

    判断某个useragent是否能爬取某个url

    • 参数
      • useragent:
      • url:
    import datetime
    import http.cookiejar
    import time
    from urllib import request, parse, error, robotparser
    
    
    def test_urlopen():
        url_get = 'https://www.httpbin.org/get'
        url_post = 'https://www.httpbin.org/post'
        data = bytes(parse.urlencode({'name': 'post'}), encoding='utf-8')
        print(datetime.datetime.now())
        try:
            response = request.urlopen(url_get)
            # response = request.urlopen(url_post, data=data)
            print(response.status)
            print(response.read().decode('utf-8'))
        except Exception as e:
            print(f'异常: {e}')
        print(datetime.datetime.now())
    
    def test_Request():
        print('Request'.center(50, '='))
        url_post = 'https://www.httpbin.org/post'
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36',
        }
        req = request.Request(url_post, headers=headers, data=data)
        req.add_header('User-Agent', 'mycrawler')
        req.add_header('My', 'Yep')
        response = request.urlopen(req)
        print(response.status)
        print(response.read().decode('utf-8'))
    
    def test_auth_handler():
        print('HTTPBasicAuthHandler'.center(50, '='))
    
        username = 'admin'
        password = 'admin'
        url = 'https://ssr3.scrape.center'
    
        p = request.HTTPPasswordMgrWithDefaultRealm()
        p.add_password(None, url, username, password)
        auth_handler = request.HTTPBasicAuthHandler(p)
        opener = request.build_opener(auth_handler)
        try:
            response = opener.open(url)
            print(response.status, response.read().decode('utf-8'))
        except error.URLError as e:
            print(e.reason)
    
    
    def test_proxy_handler():
        print('ProxyHandler'.center(50, '='))
    
        proxy_handler = request.ProxyHandler({
            'http': 'http://127.0.0.1:8080',
            'https': 'https://127.0.0.1:8080',
        })
        opener = request.build_opener(proxy_handler)
        try:
            response = opener.open('https://www.baidu.com')
            print(response.status, response.read().decode('utf-8'))
        except error.URLError as e:
            print(e.reason)
    
    
    def test_cookie_processor():
        print('HTTPCookieProcessor'.center(50, '='))
    
        cookie = http.cookiejar.CookieJar()
        handler = request.HTTPCookieProcessor(cookie)
        opener = request.build_opener(handler)
        response = opener.open('https://www.baidu.com')
        for item in cookie:
            print(item.name + '=' + item.value)
    
    
    def test_cookie_file():
        print('cookie_file'.center(50, '='))
    
        cookie_file = 'cookie.txt'
        # cookie = http.cookiejar.MozillaCookieJar(cookie_file)
        cookie = http.cookiejar.LWPCookieJar(cookie_file)
        handler = request.HTTPCookieProcessor(cookie)
        opener = request.build_opener(handler)
        response = opener.open('https://www.baidu.com')
        cookie.save(ignore_expires=True, ignore_discard=True)
    
    def test_read_cookie_file():
        print('read cookie_file'.center(50, '='))
    
        # cookie = http.cookiejar.LWPCookieJar()
        # cookie.load(cookie_file, ignore_discard=True, ignore_expires=True)
        # for item in cookie:
        #     print(item.name + '=' + item.value)  # 这里有输出,说明读取成功了
        # handler = request.HTTPCookieProcessor(cookie)
        # opener = request.build_opener(handler)
        # # 貌似不起作用,返回的cookie没有数据
        # response = opener.open('https://www.httpbin.org/cookies')
        # 下面这种方式可以返回cookie数据
        req = request.Request('https://www.httpbin.org/cookies', headers={'Cookie':'BIDUPSID=2189E52DAAF0E09623AD53F9D29B9F81'})
        response = opener.open(req)
        print(response.read().decode('utf-8'))
    
    
    def test_urlparse():
        print('urlparse'.center(50, '='))
        # url不带scheme,netloc部分被解析到了path
        # url = 'www.baidu.com/index.html;user?id=5#comment'
        url = 'http://www.baidu.com/index.html;user?id=5#comment'
        result = parse.urlparse(url, scheme='https')
        # result = parse.urlparse(url, allow_fragments=False)
        print(type(result))
        print(result)
        print(type(result.fragment))
    
        '''
        <class 'urllib.parse.ParseResult'>
        ParseResult(scheme='http', netloc='www.baidu.com', path='/index.html', params='user', query='id=5', fragment='comment')
        <class 'str'>
        '''
    
    
    def test_urlunparse():
        print('urlunparse'.center(50, '='))
    
        url = parse.urlunparse(['https', 'www.baidu.com', '/index.html', 'user', 'id=5', 'comment'])
        print(url)
    
    
    def test_urljoin():
        print('urljoin'.center(50, '='))
    
        print(parse.urljoin('https://www.baidu.com', 'index.html'))
        print(parse.urljoin('https://www.baidu.com', 'www.cnblogs.com/index.html'))
        print(parse.urljoin('https://www.baidu.com', 'http://www.cnblogs.com/index.html'))
    
        '''
        https://www.baidu.com/index.html
        https://www.baidu.com/www.cnblogs.com/index.html
        http://www.cnblogs.com/index.html
        '''
    
    
    def test_urlencode():
        print('urlencode'.center(50, '='))
    
        data = {
            'name': ['名称', '名称2'],
            'password': '密码'
        }
        # 当一个key有多个值时,字典的方式得到的结果不对,会把整个list作为整体进行encode
        # data = {'name': ['名称', '名称2'], 'password': ['密码']}
        # 需要使用列表的方式
        # data = [('name', '名称'), ('name', '名称2'), ('password', '密码')]
        base_url = 'https://www.baidu.com?'
        print(base_url + parse.urlencode(data))
    
        '''
        https://www.baidu.com?name=%E5%90%8D%E7%A7%B0&password=%E5%AF%86%E7%A0%81
        '''
    
    
    def test_parse_qs():
        print('parse_qs'.center(50, '='))
        # url = 'https://www.baidu.com?name=%E5%90%8D%E7%A7%B0&password=%E5%AF%86%E7%A0%81'
        # url = 'https://www.baidu.com?name=名称&name=名称2&password=密码'
        # 这种方式解析出来的name值是字符串,而不是数组
        url = 'https://www.baidu.com?name=%5B%27%E5%90%8D%E7%A7%B0%27%2C+%27%E5%90%8D%E7%A7%B02%27%5D&password=%5B%27%E5%AF%86%E7%A0%81%27%5D'
        '''
        qs: {'name': ["['名称', '名称2']"], 'password': ["['密码']"]}
        qsl: [('name', "['名称', '名称2']"), ('password', "['密码']")]
        '''
        query = parse.urlparse(url).query
        print(query)
        # data = parse.parse_qs(query)
        data = parse.parse_qsl(query)
        print(data)
    
        ''' parse_qs
        name=%E5%90%8D%E7%A7%B0&password=%E5%AF%86%E7%A0%81
        {'name': ['名称'], 'password': ['密码']}
        '''
    
        ''' parse_qsl
        name=%E5%90%8D%E7%A7%B0&password=%E5%AF%86%E7%A0%81
        [('name', '名称'), ('password', '密码')]
        '''
    
    
    def test_quote():
        print('quote'.center(50, '='))
        print(parse.quote('名称'))
        print(parse.quote('https://www.baidu.com?name=名称&name=名称2&password=密码'))
        print(parse.quote('https://www.baidu.com?name=名称&name=名称2&password=密码', safe=''))
    
        '''
        %E5%90%8D%E7%A7%B0
        https%3A//www.baidu.com%3Fname%3D%E5%90%8D%E7%A7%B0%26name%3D%E5%90%8D%E7%A7%B02%26password%3D%E5%AF%86%E7%A0%81
        https%3A%2F%2Fwww.baidu.com%3Fname%3D%E5%90%8D%E7%A7%B0%26name%3D%E5%90%8D%E7%A7%B02%26password%3D%E5%AF%86%E7%A0%81
    
        '''
    
    def test_unquote():
        print('unquote'.center(50, '='))
        url = 'https%3A%2F%2Fwww.baidu.com%3Fname%3D%E5%90%8D%E7%A7%B0%26name%3D%E5%90%8D%E7%A7%B02%26password%3D%E5%AF%86%E7%A0%81'
        print(parse.unquote(url))
    
        '''
        https://www.baidu.com?name=名称&name=名称2&password=密码
        '''
    
    
    def test_robots_text():
        print('RobotFileParser'.center(50, '='))
        rp = robotparser.RobotFileParser()
        response = request.urlopen('https://www.baidu.com/robots.txt')
        rp.parse(response.read().decode('utf-8').split('\n'))
        print(rp.can_fetch('BaiduSpider', 'https://www.baidu.com'))
        print(rp.can_fetch('BaiduSpider', 'https://www.baidu.com/homepage/'))
        print(rp.can_fetch('Googlebot', 'https://www.baidu.com/homepage/'))
    
    def main():
        # test_urlparse()
        # test_urlunparse()
        # test_urljoin()
        # test_urlencode()
        # test_parse_qs()
        # test_quote()
        # test_unquote()
        test_robots_text()
    
    
    if __name__ == '__main__':
        main()
    
    
    
  • 相关阅读:
    Manually Traverse a DOM Tree Using jQuery | James Wiseman
    JW Player
    San Francisco Bay Area Professional Blog: Traverse/walk DOM tree recursively
    开源集群计算环境 Spark
    INNO Setup 使用笔记
    C++ 容器及选用总结 Keosu 博客园
    Qt 4.7: DOM Traversal Example
    JavaScript Lab Articles Nonrecursive Preorder Traversal Part 4
    Tree traversal Wikipedia, the free encyclopedia
    Javascript – Traversing the HTML DOM recursively « blog.swapnilsarwe.com
  • 原文地址:https://www.cnblogs.com/yarightok/p/15941775.html
Copyright © 2020-2023  润新知