• python 给定URL 如何获取其内容,并将其保存至HTML文档。


    一,获取URL的内容需要用到标准库urllib包,其中的request模块。

    import urllib.request
    url='http://www.baidu.com'
    response=urllib.request.urlopen(url)
    string=response.read()
    html=string.decode('utf-8')
    print(html)
    

    urllib.request.urlopen(urldata=None, [timeout, ]*cafile=Nonecapath=Nonecadefault=Falsecontext=None)

    urlopen()方法返回一个<class 'http.client.HTTPResponse'>,即标准库http包里的对象,该包是一个底层包,由request模块调用。

    read()方法返回一个<class 'bytes'>,字节对象是计算机认的,人看不懂。需要转成人看得懂的字符串。

    字节对象转成str对象用str.decode()方法


    二,将获取的str对象内容保存到HTML文件,需用到程序内置的方法open()

    f=open('lc.html','w')
    f.write(html)
    f.close()
    

      open()方法返回一个<class '_io.TextIOWrapper'>

      write()方法是向文件对象写入str内容

      最后要关闭文件对象


    三,注:若上面的url换成http://www.baidu.com,则出现错误:

      UnicodeEncodeError: 'gbk' codec can't encode character 'xbb' in position 29531: illegal multibyte sequence

    原因分析:上面生成的lc.html用记事本打开,显示文件编码为ANSI,即gb2312编码。

    (不同的国家和地区制定了不同的标准,由此产生了 GB2312, BIG5, JIS 等各自的编码标准。这些使用 2 个字节来代表一个字符的各种汉字延伸编码方式,称为 ANSI 编码。在简体中文系统下,ANSI 编码代表 GB2312 编码,在日文操作系统下,ANSI 编码代表 JIS 编码。)

    如何以utf-8编码来存储lc.html文件呢?

    f=open('lc.html','w',encoding='utf-8')  

    四,注: 若上面的URL换成https://www.foxizy.com/v-5zoc-235f23.html,则出现错误:

      UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte

      原因分析:服务器传过来的内容是压缩格式(gzip),浏览器能够自动解压缩,而程序不能。

      下面来看下http应答包的header部分:

    >>> response.getheaders()
    [('Server', 'nginx'), ('Date', 'Sun, 23 Jun 2019 00:25:46 GMT'), ('Content-Type', 'text/html; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Connection', 'close'), ('Cache-Control', 'public, max-age=252000'), ('Expires', 'Mon, 24 Jun 2019 07:14:39 GMT'), ('Last-Modified', 'Fri, 21 Jun 2019 09:14:39 GMT'), ('Content-Encoding', 'gzip'), ('N-Cache', 'HIT')]

    从红色部分可以看出,服务器返回的内容经过了gzip压缩,所以需要解压缩。

    如何解决该问题:

    import zlib
    string=zlib.decompress(string,zlib.MAX_WBITS | 16) 

    五,注:若urlopen()方法只传入一个url地址参数,则该HTTP请求的方法为GET请求。

    如何进行POST请求呢? 

    from urllib import request,parse
    url='http://httpbin.org/post'
    d={'name':'张三'} da=parse.urlencode(d) data=bytes(da,encoding='utf-8') response=request.urlopen(url,data=data)
    print(response.read().decode('utf-8'))

      用了第二个参数data,就相当于post请求,但是data参数要求是字节(bytes)类型。


    六,注:当我们想传递request headers的时候,urlopen就无法支持了,这里需要一个新的方法。

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

    from urllib import request,parse
    url='http://httpbin.org/post'
    headers={
        'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3100.0 Safari/537.36',
        'Host':'httpbin.org'
    }
    dict={'name':'zhangsan'}
    data=bytes(parse.urlencode(dict),encoding='utf-8')
    req=request.Request(url=url,data=data,headers=headers,method='post')
    response=request.urlopen(req)
    print(response.read().decode('utf-8'))
    

      

  • 相关阅读:
    反射/元类/项目的生命周期
    面向对象高级
    面向对象之封装/鸭子类型
    面向对象之继承
    面向对象1
    包/logging模块/hashlib模块/openpyxl模块/深浅拷贝
    python 几行代码实现自动回复功能
    python crypto rsa 加密运用
    pytohn 单下划线与双下划线的区别
    python 线程小练习
  • 原文地址:https://www.cnblogs.com/blogzyq/p/11067648.html
Copyright © 2020-2023  润新知