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'))

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM